zfsboot.c revision 299997
1/*- 2 * Copyright (c) 1998 Robert Nordier 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are freely 6 * permitted provided that the above copyright notice and this 7 * paragraph and the following disclaimer are duplicated in all 8 * such forms. 9 * 10 * This software is provided "AS IS" and without any express or 11 * implied warranties, including, without limitation, the implied 12 * warranties of merchantability and fitness for a particular 13 * purpose. 14 */ 15 16#include <sys/cdefs.h> 17__FBSDID("$FreeBSD: head/sys/boot/i386/zfsboot/zfsboot.c 299997 2016-05-17 00:24:53Z peter $"); 18 19#include <sys/param.h> 20#include <sys/errno.h> 21#include <sys/diskmbr.h> 22#ifdef GPT 23#include <sys/gpt.h> 24#endif 25#include <sys/reboot.h> 26#include <sys/queue.h> 27 28#include <machine/bootinfo.h> 29#include <machine/elf.h> 30#include <machine/pc/bios.h> 31 32#include <stdarg.h> 33#include <stddef.h> 34 35#include <a.out.h> 36 37#include <btxv86.h> 38 39#include "lib.h" 40#include "rbx.h" 41#include "drv.h" 42#include "util.h" 43#include "cons.h" 44#include "bootargs.h" 45#include "paths.h" 46 47#include "libzfs.h" 48 49#define ARGS 0x900 50#define NOPT 14 51#define NDEV 3 52 53#define BIOS_NUMDRIVES 0x475 54#define DRV_HARD 0x80 55#define DRV_MASK 0x7f 56 57#define TYPE_AD 0 58#define TYPE_DA 1 59#define TYPE_MAXHARD TYPE_DA 60#define TYPE_FD 2 61 62#define DEV_GELIBOOT_BSIZE 4096 63 64extern uint32_t _end; 65 66#ifdef GPT 67static const uuid_t freebsd_zfs_uuid = GPT_ENT_TYPE_FREEBSD_ZFS; 68#endif 69static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ 70static const unsigned char flags[NOPT] = { 71 RBX_DUAL, 72 RBX_SERIAL, 73 RBX_ASKNAME, 74 RBX_CDROM, 75 RBX_CONFIG, 76 RBX_KDB, 77 RBX_GDB, 78 RBX_MUTE, 79 RBX_NOINTR, 80 RBX_PAUSE, 81 RBX_QUIET, 82 RBX_DFLTROOT, 83 RBX_SINGLE, 84 RBX_VERBOSE 85}; 86uint32_t opts; 87 88static const unsigned char dev_maj[NDEV] = {30, 4, 2}; 89 90static char cmd[512]; 91static char cmddup[512]; 92static char kname[1024]; 93static char rootname[256]; 94static int comspeed = SIOSPD; 95static struct bootinfo bootinfo; 96static uint32_t bootdev; 97static struct zfs_boot_args zfsargs; 98static struct zfsmount zfsmount; 99 100vm_offset_t high_heap_base; 101uint32_t bios_basemem, bios_extmem, high_heap_size; 102 103static struct bios_smap smap; 104 105/* 106 * The minimum amount of memory to reserve in bios_extmem for the heap. 107 */ 108#define HEAP_MIN (3 * 1024 * 1024) 109 110static char *heap_next; 111static char *heap_end; 112 113/* Buffers that must not span a 64k boundary. */ 114#define READ_BUF_SIZE 8192 115struct dmadat { 116 char rdbuf[READ_BUF_SIZE]; /* for reading large things */ 117 char secbuf[READ_BUF_SIZE]; /* for MBR/disklabel */ 118}; 119static struct dmadat *dmadat; 120 121void exit(int); 122static void load(void); 123static int parse(void); 124static void bios_getmem(void); 125void *malloc(size_t n); 126void free(void *ptr); 127 128void * 129malloc(size_t n) 130{ 131 char *p = heap_next; 132 if (p + n > heap_end) { 133 printf("malloc failure\n"); 134 for (;;) 135 ; 136 /* NOTREACHED */ 137 return (0); 138 } 139 heap_next += n; 140 return (p); 141} 142 143void 144free(void *ptr) 145{ 146 147 return; 148} 149 150static char * 151strdup(const char *s) 152{ 153 char *p = malloc(strlen(s) + 1); 154 strcpy(p, s); 155 return (p); 156} 157 158#ifdef LOADER_GELI_SUPPORT 159#include "geliboot.c" 160static char gelipw[GELI_PW_MAXLEN]; 161#endif 162 163#include "zfsimpl.c" 164 165/* 166 * Read from a dnode (which must be from a ZPL filesystem). 167 */ 168static int 169zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t size) 170{ 171 const znode_phys_t *zp = (const znode_phys_t *) dnode->dn_bonus; 172 size_t n; 173 int rc; 174 175 n = size; 176 if (*offp + n > zp->zp_size) 177 n = zp->zp_size - *offp; 178 179 rc = dnode_read(spa, dnode, *offp, start, n); 180 if (rc) 181 return (-1); 182 *offp += n; 183 184 return (n); 185} 186 187/* 188 * Current ZFS pool 189 */ 190static spa_t *spa; 191static spa_t *primary_spa; 192static vdev_t *primary_vdev; 193 194/* 195 * A wrapper for dskread that doesn't have to worry about whether the 196 * buffer pointer crosses a 64k boundary. 197 */ 198static int 199vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) 200{ 201 char *p; 202 daddr_t lba, alignlba; 203 off_t alignoff, diff; 204 unsigned int nb, alignnb; 205 struct dsk *dsk = (struct dsk *) priv; 206 207 if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) 208 return -1; 209 210 p = buf; 211 lba = off / DEV_BSIZE; 212 lba += dsk->start; 213 /* Align reads to 4k else 4k sector GELIs will not decrypt. */ 214 alignoff = off & ~ (off_t)(DEV_GELIBOOT_BSIZE - 1); 215 /* Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes. */ 216 alignlba = alignoff / DEV_BSIZE; 217 /* 218 * The read must be aligned to DEV_GELIBOOT_BSIZE bytes relative to the 219 * start of the GELI partition, not the start of the actual disk. 220 */ 221 alignlba += dsk->start; 222 diff = (lba - alignlba) * DEV_BSIZE; 223 224 while (bytes > 0) { 225 nb = bytes / DEV_BSIZE; 226 /* 227 * Ensure that the read size plus the leading offset does not 228 * exceed the size of the read buffer. 229 */ 230 if (nb > (READ_BUF_SIZE - diff) / DEV_BSIZE) 231 nb = (READ_BUF_SIZE - diff) / DEV_BSIZE; 232 /* 233 * Round the number of blocks to read up to the nearest multiple 234 * of DEV_GELIBOOT_BSIZE. 235 */ 236 alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE) 237 / DEV_BSIZE; 238 239 if (drvread(dsk, dmadat->rdbuf, alignlba, alignnb)) 240 return -1; 241#ifdef LOADER_GELI_SUPPORT 242 /* decrypt */ 243 if (is_geli(dsk) == 0) { 244 if (geli_read(dsk, ((alignlba - dsk->start) * 245 DEV_BSIZE), dmadat->rdbuf, alignnb * DEV_BSIZE)) 246 return (-1); 247 } 248#endif 249 memcpy(p, dmadat->rdbuf + diff, nb * DEV_BSIZE); 250 p += nb * DEV_BSIZE; 251 lba += nb; 252 alignlba += alignnb; 253 bytes -= nb * DEV_BSIZE; 254 /* Don't need the leading offset after the first block. */ 255 diff = 0; 256 } 257 258 return 0; 259} 260 261static int 262xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte) 263{ 264 if ((size_t)zfs_read(spa, dnode, offp, buf, nbyte) != nbyte) { 265 printf("Invalid format\n"); 266 return -1; 267 } 268 return 0; 269} 270 271static void 272bios_getmem(void) 273{ 274 uint64_t size; 275 276 /* Parse system memory map */ 277 v86.ebx = 0; 278 do { 279 v86.ctl = V86_FLAGS; 280 v86.addr = 0x15; /* int 0x15 function 0xe820*/ 281 v86.eax = 0xe820; 282 v86.ecx = sizeof(struct bios_smap); 283 v86.edx = SMAP_SIG; 284 v86.es = VTOPSEG(&smap); 285 v86.edi = VTOPOFF(&smap); 286 v86int(); 287 if (V86_CY(v86.efl) || (v86.eax != SMAP_SIG)) 288 break; 289 /* look for a low-memory segment that's large enough */ 290 if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) && 291 (smap.length >= (512 * 1024))) 292 bios_basemem = smap.length; 293 /* look for the first segment in 'extended' memory */ 294 if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) { 295 bios_extmem = smap.length; 296 } 297 298 /* 299 * Look for the largest segment in 'extended' memory beyond 300 * 1MB but below 4GB. 301 */ 302 if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) && 303 (smap.base < 0x100000000ull)) { 304 size = smap.length; 305 306 /* 307 * If this segment crosses the 4GB boundary, truncate it. 308 */ 309 if (smap.base + size > 0x100000000ull) 310 size = 0x100000000ull - smap.base; 311 312 if (size > high_heap_size) { 313 high_heap_size = size; 314 high_heap_base = smap.base; 315 } 316 } 317 } while (v86.ebx != 0); 318 319 /* Fall back to the old compatibility function for base memory */ 320 if (bios_basemem == 0) { 321 v86.ctl = 0; 322 v86.addr = 0x12; /* int 0x12 */ 323 v86int(); 324 325 bios_basemem = (v86.eax & 0xffff) * 1024; 326 } 327 328 /* Fall back through several compatibility functions for extended memory */ 329 if (bios_extmem == 0) { 330 v86.ctl = V86_FLAGS; 331 v86.addr = 0x15; /* int 0x15 function 0xe801*/ 332 v86.eax = 0xe801; 333 v86int(); 334 if (!V86_CY(v86.efl)) { 335 bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024; 336 } 337 } 338 if (bios_extmem == 0) { 339 v86.ctl = 0; 340 v86.addr = 0x15; /* int 0x15 function 0x88*/ 341 v86.eax = 0x8800; 342 v86int(); 343 bios_extmem = (v86.eax & 0xffff) * 1024; 344 } 345 346 /* 347 * If we have extended memory and did not find a suitable heap 348 * region in the SMAP, use the last 3MB of 'extended' memory as a 349 * high heap candidate. 350 */ 351 if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) { 352 high_heap_size = HEAP_MIN; 353 high_heap_base = bios_extmem + 0x100000 - HEAP_MIN; 354 } 355} 356 357/* 358 * Try to detect a device supported by the legacy int13 BIOS 359 */ 360static int 361int13probe(int drive) 362{ 363 v86.ctl = V86_FLAGS; 364 v86.addr = 0x13; 365 v86.eax = 0x800; 366 v86.edx = drive; 367 v86int(); 368 369 if (!V86_CY(v86.efl) && /* carry clear */ 370 ((v86.edx & 0xff) != (drive & DRV_MASK))) { /* unit # OK */ 371 if ((v86.ecx & 0x3f) == 0) { /* absurd sector size */ 372 return(0); /* skip device */ 373 } 374 return (1); 375 } 376 return(0); 377} 378 379/* 380 * We call this when we find a ZFS vdev - ZFS consumes the dsk 381 * structure so we must make a new one. 382 */ 383static struct dsk * 384copy_dsk(struct dsk *dsk) 385{ 386 struct dsk *newdsk; 387 388 newdsk = malloc(sizeof(struct dsk)); 389 *newdsk = *dsk; 390 return (newdsk); 391} 392 393static void 394probe_drive(struct dsk *dsk) 395{ 396#ifdef GPT 397 struct gpt_hdr hdr; 398 struct gpt_ent *ent; 399 unsigned part, entries_per_sec; 400 daddr_t slba; 401#endif 402#if defined(GPT) || defined(LOADER_GELI_SUPPORT) 403 daddr_t elba; 404#endif 405 406 struct dos_partition *dp; 407 char *sec; 408 unsigned i; 409 410 /* 411 * If we find a vdev on the whole disk, stop here. 412 */ 413 if (vdev_probe(vdev_read, dsk, NULL) == 0) 414 return; 415 416#ifdef LOADER_GELI_SUPPORT 417 /* 418 * Taste the disk, if it is GELI encrypted, decrypt it and check to see if 419 * it is a usable vdev then. Otherwise dig 420 * out the partition table and probe each slice/partition 421 * in turn for a vdev or GELI encrypted vdev. 422 */ 423 elba = drvsize(dsk); 424 if (elba > 0) { 425 elba--; 426 } 427 if (geli_taste(vdev_read, dsk, elba) == 0) { 428 if (geli_passphrase(&gelipw, dsk->unit, ':', 0, dsk) == 0) { 429 if (vdev_probe(vdev_read, dsk, NULL) == 0) { 430 return; 431 } 432 } 433 } 434#endif /* LOADER_GELI_SUPPORT */ 435 436 sec = dmadat->secbuf; 437 dsk->start = 0; 438 439#ifdef GPT 440 /* 441 * First check for GPT. 442 */ 443 if (drvread(dsk, sec, 1, 1)) { 444 return; 445 } 446 memcpy(&hdr, sec, sizeof(hdr)); 447 if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 || 448 hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 || 449 hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) { 450 goto trymbr; 451 } 452 453 /* 454 * Probe all GPT partitions for the presence of ZFS pools. We 455 * return the spa_t for the first we find (if requested). This 456 * will have the effect of booting from the first pool on the 457 * disk. 458 * 459 * If no vdev is found, GELI decrypting the device and try again 460 */ 461 entries_per_sec = DEV_BSIZE / hdr.hdr_entsz; 462 slba = hdr.hdr_lba_table; 463 elba = slba + hdr.hdr_entries / entries_per_sec; 464 while (slba < elba) { 465 dsk->start = 0; 466 if (drvread(dsk, sec, slba, 1)) 467 return; 468 for (part = 0; part < entries_per_sec; part++) { 469 ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz); 470 if (memcmp(&ent->ent_type, &freebsd_zfs_uuid, 471 sizeof(uuid_t)) == 0) { 472 dsk->start = ent->ent_lba_start; 473 dsk->slice = part + 1; 474 dsk->part = 255; 475 if (vdev_probe(vdev_read, dsk, NULL) == 0) { 476 /* 477 * This slice had a vdev. We need a new dsk 478 * structure now since the vdev now owns this one. 479 */ 480 dsk = copy_dsk(dsk); 481 } 482#ifdef LOADER_GELI_SUPPORT 483 else if (geli_taste(vdev_read, dsk, ent->ent_lba_end - 484 ent->ent_lba_start) == 0) { 485 if (geli_passphrase(&gelipw, dsk->unit, 'p', dsk->slice, dsk) == 0) { 486 /* 487 * This slice has GELI, check it for ZFS. 488 */ 489 if (vdev_probe(vdev_read, dsk, NULL) == 0) { 490 /* 491 * This slice had a vdev. We need a new dsk 492 * structure now since the vdev now owns this one. 493 */ 494 dsk = copy_dsk(dsk); 495 } 496 break; 497 } 498 } 499#endif /* LOADER_GELI_SUPPORT */ 500 } 501 } 502 slba++; 503 } 504 return; 505trymbr: 506#endif /* GPT */ 507 508 if (drvread(dsk, sec, DOSBBSECTOR, 1)) 509 return; 510 dp = (void *)(sec + DOSPARTOFF); 511 512 for (i = 0; i < NDOSPART; i++) { 513 if (!dp[i].dp_typ) 514 continue; 515 dsk->start = dp[i].dp_start; 516 dsk->slice = i + 1; 517 if (vdev_probe(vdev_read, dsk, NULL) == 0) { 518 dsk = copy_dsk(dsk); 519 } 520#ifdef LOADER_GELI_SUPPORT 521 else if (geli_taste(vdev_read, dsk, dp[i].dp_size - 522 dp[i].dp_start) == 0) { 523 if (geli_passphrase(&gelipw, dsk->unit, 's', i, dsk) == 0) { 524 /* 525 * This slice has GELI, check it for ZFS. 526 */ 527 if (vdev_probe(vdev_read, dsk, NULL) == 0) { 528 /* 529 * This slice had a vdev. We need a new dsk 530 * structure now since the vdev now owns this one. 531 */ 532 dsk = copy_dsk(dsk); 533 } 534 break; 535 } 536 } 537#endif /* LOADER_GELI_SUPPORT */ 538 } 539} 540 541int 542main(void) 543{ 544 int autoboot, i; 545 dnode_phys_t dn; 546 off_t off; 547 struct dsk *dsk; 548 549 dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); 550 551 bios_getmem(); 552 553 if (high_heap_size > 0) { 554 heap_end = PTOV(high_heap_base + high_heap_size); 555 heap_next = PTOV(high_heap_base); 556 } else { 557 heap_next = (char *)dmadat + sizeof(*dmadat); 558 heap_end = (char *)PTOV(bios_basemem); 559 } 560 561 dsk = malloc(sizeof(struct dsk)); 562 dsk->drive = *(uint8_t *)PTOV(ARGS); 563 dsk->type = dsk->drive & DRV_HARD ? TYPE_AD : TYPE_FD; 564 dsk->unit = dsk->drive & DRV_MASK; 565 dsk->slice = *(uint8_t *)PTOV(ARGS + 1) + 1; 566 dsk->part = 0; 567 dsk->start = 0; 568 dsk->init = 0; 569 570 bootinfo.bi_version = BOOTINFO_VERSION; 571 bootinfo.bi_size = sizeof(bootinfo); 572 bootinfo.bi_basemem = bios_basemem / 1024; 573 bootinfo.bi_extmem = bios_extmem / 1024; 574 bootinfo.bi_memsizes_valid++; 575 bootinfo.bi_bios_dev = dsk->drive; 576 577 bootdev = MAKEBOOTDEV(dev_maj[dsk->type], 578 dsk->slice, dsk->unit, dsk->part), 579 580 /* Process configuration file */ 581 582 autoboot = 1; 583 584#ifdef LOADER_GELI_SUPPORT 585 geli_init(); 586#endif 587 zfs_init(); 588 589 /* 590 * Probe the boot drive first - we will try to boot from whatever 591 * pool we find on that drive. 592 */ 593 probe_drive(dsk); 594 595 /* 596 * Probe the rest of the drives that the bios knows about. This 597 * will find any other available pools and it may fill in missing 598 * vdevs for the boot pool. 599 */ 600#ifndef VIRTUALBOX 601 for (i = 0; i < *(unsigned char *)PTOV(BIOS_NUMDRIVES); i++) 602#else 603 for (i = 0; i < MAXBDDEV; i++) 604#endif 605 { 606 if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS)) 607 continue; 608 609 if (!int13probe(i | DRV_HARD)) 610 break; 611 612 dsk = malloc(sizeof(struct dsk)); 613 dsk->drive = i | DRV_HARD; 614 dsk->type = dsk->drive & TYPE_AD; 615 dsk->unit = i; 616 dsk->slice = 0; 617 dsk->part = 0; 618 dsk->start = 0; 619 dsk->init = 0; 620 probe_drive(dsk); 621 } 622 623 /* 624 * The first discovered pool, if any, is the pool. 625 */ 626 spa = spa_get_primary(); 627 if (!spa) { 628 printf("%s: No ZFS pools located, can't boot\n", BOOTPROG); 629 for (;;) 630 ; 631 } 632 633 primary_spa = spa; 634 primary_vdev = spa_get_primary_vdev(spa); 635 636 if (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0) { 637 printf("%s: failed to mount default pool %s\n", 638 BOOTPROG, spa->spa_name); 639 autoboot = 0; 640 } else if (zfs_lookup(&zfsmount, PATH_CONFIG, &dn) == 0 || 641 zfs_lookup(&zfsmount, PATH_DOTCONFIG, &dn) == 0) { 642 off = 0; 643 zfs_read(spa, &dn, &off, cmd, sizeof(cmd)); 644 } 645 646 if (*cmd) { 647 /* 648 * Note that parse() is destructive to cmd[] and we also want 649 * to honor RBX_QUIET option that could be present in cmd[]. 650 */ 651 memcpy(cmddup, cmd, sizeof(cmd)); 652 if (parse()) 653 autoboot = 0; 654 if (!OPT_CHECK(RBX_QUIET)) 655 printf("%s: %s\n", PATH_CONFIG, cmddup); 656 /* Do not process this command twice */ 657 *cmd = 0; 658 } 659 660 /* 661 * Try to exec /boot/loader. If interrupted by a keypress, 662 * or in case of failure, try to load a kernel directly instead. 663 */ 664 665 if (autoboot && !*kname) { 666 memcpy(kname, PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS)); 667 if (!keyhit(3)) { 668 load(); 669 memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL)); 670 } 671 } 672 673 /* Present the user with the boot2 prompt. */ 674 675 for (;;) { 676 if (!autoboot || !OPT_CHECK(RBX_QUIET)) { 677 printf("\nFreeBSD/x86 boot\n"); 678 if (zfs_rlookup(spa, zfsmount.rootobj, rootname) != 0) 679 printf("Default: %s/<0x%llx>:%s\n" 680 "boot: ", 681 spa->spa_name, zfsmount.rootobj, kname); 682 else if (rootname[0] != '\0') 683 printf("Default: %s/%s:%s\n" 684 "boot: ", 685 spa->spa_name, rootname, kname); 686 else 687 printf("Default: %s:%s\n" 688 "boot: ", 689 spa->spa_name, kname); 690 } 691 if (ioctrl & IO_SERIAL) 692 sio_flush(); 693 if (!autoboot || keyhit(5)) 694 getstr(cmd, sizeof(cmd)); 695 else if (!autoboot || !OPT_CHECK(RBX_QUIET)) 696 putchar('\n'); 697 autoboot = 0; 698 if (parse()) 699 putchar('\a'); 700 else 701 load(); 702 } 703} 704 705/* XXX - Needed for btxld to link the boot2 binary; do not remove. */ 706void 707exit(int x) 708{ 709} 710 711static void 712load(void) 713{ 714 union { 715 struct exec ex; 716 Elf32_Ehdr eh; 717 } hdr; 718 static Elf32_Phdr ep[2]; 719 static Elf32_Shdr es[2]; 720 caddr_t p; 721 dnode_phys_t dn; 722 off_t off; 723 uint32_t addr, x; 724 int fmt, i, j; 725 726 if (zfs_lookup(&zfsmount, kname, &dn)) { 727 printf("\nCan't find %s\n", kname); 728 return; 729 } 730 off = 0; 731 if (xfsread(&dn, &off, &hdr, sizeof(hdr))) 732 return; 733 if (N_GETMAGIC(hdr.ex) == ZMAGIC) 734 fmt = 0; 735 else if (IS_ELF(hdr.eh)) 736 fmt = 1; 737 else { 738 printf("Invalid %s\n", "format"); 739 return; 740 } 741 if (fmt == 0) { 742 addr = hdr.ex.a_entry & 0xffffff; 743 p = PTOV(addr); 744 off = PAGE_SIZE; 745 if (xfsread(&dn, &off, p, hdr.ex.a_text)) 746 return; 747 p += roundup2(hdr.ex.a_text, PAGE_SIZE); 748 if (xfsread(&dn, &off, p, hdr.ex.a_data)) 749 return; 750 p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); 751 bootinfo.bi_symtab = VTOP(p); 752 memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); 753 p += sizeof(hdr.ex.a_syms); 754 if (hdr.ex.a_syms) { 755 if (xfsread(&dn, &off, p, hdr.ex.a_syms)) 756 return; 757 p += hdr.ex.a_syms; 758 if (xfsread(&dn, &off, p, sizeof(int))) 759 return; 760 x = *(uint32_t *)p; 761 p += sizeof(int); 762 x -= sizeof(int); 763 if (xfsread(&dn, &off, p, x)) 764 return; 765 p += x; 766 } 767 } else { 768 off = hdr.eh.e_phoff; 769 for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { 770 if (xfsread(&dn, &off, ep + j, sizeof(ep[0]))) 771 return; 772 if (ep[j].p_type == PT_LOAD) 773 j++; 774 } 775 for (i = 0; i < 2; i++) { 776 p = PTOV(ep[i].p_paddr & 0xffffff); 777 off = ep[i].p_offset; 778 if (xfsread(&dn, &off, p, ep[i].p_filesz)) 779 return; 780 } 781 p += roundup2(ep[1].p_memsz, PAGE_SIZE); 782 bootinfo.bi_symtab = VTOP(p); 783 if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { 784 off = hdr.eh.e_shoff + sizeof(es[0]) * 785 (hdr.eh.e_shstrndx + 1); 786 if (xfsread(&dn, &off, &es, sizeof(es))) 787 return; 788 for (i = 0; i < 2; i++) { 789 memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size)); 790 p += sizeof(es[i].sh_size); 791 off = es[i].sh_offset; 792 if (xfsread(&dn, &off, p, es[i].sh_size)) 793 return; 794 p += es[i].sh_size; 795 } 796 } 797 addr = hdr.eh.e_entry & 0xffffff; 798 } 799 bootinfo.bi_esymtab = VTOP(p); 800 bootinfo.bi_kernelname = VTOP(kname); 801 zfsargs.size = sizeof(zfsargs); 802 zfsargs.pool = zfsmount.spa->spa_guid; 803 zfsargs.root = zfsmount.rootobj; 804 zfsargs.primary_pool = primary_spa->spa_guid; 805#ifdef LOADER_GELI_SUPPORT 806 bcopy(gelipw, zfsargs.gelipw, sizeof(zfsargs.gelipw)); 807 bzero(gelipw, sizeof(gelipw)); 808#else 809 zfsargs.gelipw[0] = '\0'; 810#endif 811 if (primary_vdev != NULL) 812 zfsargs.primary_vdev = primary_vdev->v_guid; 813 else 814 printf("failed to detect primary vdev\n"); 815 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 816 bootdev, 817 KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, 818 (uint32_t) spa->spa_guid, 819 (uint32_t) (spa->spa_guid >> 32), 820 VTOP(&bootinfo), 821 zfsargs); 822} 823 824static int 825zfs_mount_ds(char *dsname) 826{ 827 uint64_t newroot; 828 spa_t *newspa; 829 char *q; 830 831 q = strchr(dsname, '/'); 832 if (q) 833 *q++ = '\0'; 834 newspa = spa_find_by_name(dsname); 835 if (newspa == NULL) { 836 printf("\nCan't find ZFS pool %s\n", dsname); 837 return -1; 838 } 839 840 if (zfs_spa_init(newspa)) 841 return -1; 842 843 newroot = 0; 844 if (q) { 845 if (zfs_lookup_dataset(newspa, q, &newroot)) { 846 printf("\nCan't find dataset %s in ZFS pool %s\n", 847 q, newspa->spa_name); 848 return -1; 849 } 850 } 851 if (zfs_mount(newspa, newroot, &zfsmount)) { 852 printf("\nCan't mount ZFS dataset\n"); 853 return -1; 854 } 855 spa = newspa; 856 return (0); 857} 858 859static int 860parse(void) 861{ 862 char *arg = cmd; 863 char *ep, *p, *q; 864 const char *cp; 865 int c, i, j; 866 867 while ((c = *arg++)) { 868 if (c == ' ' || c == '\t' || c == '\n') 869 continue; 870 for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); 871 ep = p; 872 if (*p) 873 *p++ = 0; 874 if (c == '-') { 875 while ((c = *arg++)) { 876 if (c == 'P') { 877 if (*(uint8_t *)PTOV(0x496) & 0x10) { 878 cp = "yes"; 879 } else { 880 opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); 881 cp = "no"; 882 } 883 printf("Keyboard: %s\n", cp); 884 continue; 885 } else if (c == 'S') { 886 j = 0; 887 while ((unsigned int)(i = *arg++ - '0') <= 9) 888 j = j * 10 + i; 889 if (j > 0 && i == -'0') { 890 comspeed = j; 891 break; 892 } 893 /* Fall through to error below ('S' not in optstr[]). */ 894 } 895 for (i = 0; c != optstr[i]; i++) 896 if (i == NOPT - 1) 897 return -1; 898 opts ^= OPT_SET(flags[i]); 899 } 900 ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : 901 OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; 902 if (ioctrl & IO_SERIAL) { 903 if (sio_init(115200 / comspeed) != 0) 904 ioctrl &= ~IO_SERIAL; 905 } 906 } if (c == '?') { 907 dnode_phys_t dn; 908 909 if (zfs_lookup(&zfsmount, arg, &dn) == 0) { 910 zap_list(spa, &dn); 911 } 912 return -1; 913 } else { 914 arg--; 915 916 /* 917 * Report pool status if the comment is 'status'. Lets 918 * hope no-one wants to load /status as a kernel. 919 */ 920 if (!strcmp(arg, "status")) { 921 spa_all_status(); 922 return -1; 923 } 924 925 /* 926 * If there is "zfs:" prefix simply ignore it. 927 */ 928 if (strncmp(arg, "zfs:", 4) == 0) 929 arg += 4; 930 931 /* 932 * If there is a colon, switch pools. 933 */ 934 q = strchr(arg, ':'); 935 if (q) { 936 *q++ = '\0'; 937 if (zfs_mount_ds(arg) != 0) 938 return -1; 939 arg = q; 940 } 941 if ((i = ep - arg)) { 942 if ((size_t)i >= sizeof(kname)) 943 return -1; 944 memcpy(kname, arg, i + 1); 945 } 946 } 947 arg = p; 948 } 949 return 0; 950} 951