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 #include <stand.h> 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 #ifdef LOADER_ZFS_SUPPORT 28 #include <sys/zfs_bootenv.h> 29 #endif 30 31 #include <machine/bootinfo.h> 32 #include <machine/elf.h> 33 #include <machine/pc/bios.h> 34 35 #include <stdarg.h> 36 #include <stddef.h> 37 38 #include <a.out.h> 39 #include "bootstrap.h" 40 #include "libi386.h" 41 #include <btxv86.h> 42 43 #include "lib.h" 44 #include "rbx.h" 45 #include "cons.h" 46 #include "bootargs.h" 47 #include "disk.h" 48 #include "part.h" 49 #include "paths.h" 50 51 #include "libzfs.h" 52 53 #define ARGS 0x900 54 #define NOPT 14 55 #define NDEV 3 56 57 #define BIOS_NUMDRIVES 0x475 58 #define DRV_HARD 0x80 59 #define DRV_MASK 0x7f 60 61 #define TYPE_AD 0 62 #define TYPE_DA 1 63 #define TYPE_MAXHARD TYPE_DA 64 #define TYPE_FD 2 65 66 extern uint32_t _end; 67 68 static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ 69 static const unsigned char flags[NOPT] = { 70 RBX_DUAL, 71 RBX_SERIAL, 72 RBX_ASKNAME, 73 RBX_CDROM, 74 RBX_CONFIG, 75 RBX_KDB, 76 RBX_GDB, 77 RBX_MUTE, 78 RBX_NOINTR, 79 RBX_PAUSE, 80 RBX_QUIET, 81 RBX_DFLTROOT, 82 RBX_SINGLE, 83 RBX_VERBOSE 84 }; 85 uint32_t opts; 86 87 /* 88 * Paths to try loading before falling back to the boot2 prompt. 89 * 90 * /boot/zfsloader must be tried before /boot/loader in order to remain 91 * backward compatible with ZFS boot environments where /boot/loader exists 92 * but does not have ZFS support, which was the case before FreeBSD 12. 93 * 94 * If no loader is found, try to load a kernel directly instead. 95 */ 96 static const struct string { 97 const char *p; 98 size_t len; 99 } loadpath[] = { 100 { PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS) }, 101 { PATH_LOADER, sizeof(PATH_LOADER) }, 102 { PATH_KERNEL, sizeof(PATH_KERNEL) }, 103 }; 104 105 static const unsigned char dev_maj[NDEV] = {30, 4, 2}; 106 107 static struct i386_devdesc *bdev; 108 static char cmd[512]; 109 static char cmddup[512]; 110 static char kname[1024]; 111 static int comspeed = SIOSPD; 112 static struct bootinfo bootinfo; 113 static uint32_t bootdev; 114 static struct zfs_boot_args zfsargs; 115 #ifdef LOADER_GELI_SUPPORT 116 static struct geli_boot_args geliargs; 117 #endif 118 119 extern vm_offset_t high_heap_base; 120 extern uint32_t bios_basemem, bios_extmem, high_heap_size; 121 122 static char *heap_top; 123 static char *heap_bottom; 124 125 void exit(int); 126 static void i386_zfs_probe(void); 127 static void load(void); 128 static int parse_cmd(void); 129 130 #ifdef LOADER_GELI_SUPPORT 131 #include "geliboot.h" 132 static char gelipw[GELI_PW_MAXLEN]; 133 #endif 134 135 struct arch_switch archsw; /* MI/MD interface boundary */ 136 static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */ 137 138 struct devsw *devsw[] = { 139 &bioshd, 140 #if defined(LOADER_ZFS_SUPPORT) 141 &zfs_dev, 142 #endif 143 NULL 144 }; 145 146 struct fs_ops *file_system[] = { 147 #if defined(LOADER_ZFS_SUPPORT) 148 &zfs_fsops, 149 #endif 150 #if defined(LOADER_UFS_SUPPORT) 151 &ufs_fsops, 152 #endif 153 NULL 154 }; 155 156 caddr_t 157 ptov(uintptr_t x) 158 { 159 return (PTOV(x)); 160 } 161 162 int main(void); 163 164 int 165 main(void) 166 { 167 unsigned i; 168 int auto_boot, fd, nextboot = 0; 169 struct disk_devdesc *devdesc; 170 171 bios_getmem(); 172 173 if (high_heap_size > 0) { 174 heap_top = PTOV(high_heap_base + high_heap_size); 175 heap_bottom = PTOV(high_heap_base); 176 } else { 177 heap_bottom = (char *) 178 (roundup2(__base + (int32_t)&_end, 0x10000) - __base); 179 heap_top = (char *)PTOV(bios_basemem); 180 } 181 setheap(heap_bottom, heap_top); 182 183 /* 184 * Initialise the block cache. Set the upper limit. 185 */ 186 bcache_init(32768, 512); 187 188 archsw.arch_autoload = NULL; 189 archsw.arch_getdev = i386_getdev; 190 archsw.arch_copyin = NULL; 191 archsw.arch_copyout = NULL; 192 archsw.arch_readin = NULL; 193 archsw.arch_isainb = NULL; 194 archsw.arch_isaoutb = NULL; 195 archsw.arch_zfs_probe = i386_zfs_probe; 196 197 bootinfo.bi_version = BOOTINFO_VERSION; 198 bootinfo.bi_size = sizeof(bootinfo); 199 bootinfo.bi_basemem = bios_basemem / 1024; 200 bootinfo.bi_extmem = bios_extmem / 1024; 201 bootinfo.bi_memsizes_valid++; 202 bootinfo.bi_bios_dev = *(uint8_t *)PTOV(ARGS); 203 204 /* Set up fall back device name. */ 205 snprintf(boot_devname, sizeof (boot_devname), "disk%d:", 206 bd_bios2unit(bootinfo.bi_bios_dev)); 207 208 /* Set up currdev variable to have hooks in place. */ 209 env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, 210 env_nounset); 211 212 devinit(); 213 214 /* XXX assumes this will be a disk, but it looks likely give above */ 215 disk_parsedev((struct devdesc **)&devdesc, boot_devname, NULL); 216 217 bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc->d_slice + 1, 218 devdesc->dd.d_unit, 219 devdesc->d_partition >= 0 ? devdesc->d_partition : 0xff); 220 free(devdesc); 221 222 /* 223 * devformat() can be called only after dv_init 224 */ 225 if (bdev != NULL && bdev->dd.d_dev->dv_type == DEVT_ZFS) { 226 /* set up proper device name string for ZFS */ 227 strncpy(boot_devname, devformat(&bdev->dd), sizeof (boot_devname)); 228 if (zfs_get_bootonce(bdev, OS_BOOTONCE, cmd, 229 sizeof(cmd)) == 0) { 230 nvlist_t *benv; 231 232 nextboot = 1; 233 memcpy(cmddup, cmd, sizeof(cmd)); 234 if (parse_cmd()) { 235 if (!OPT_CHECK(RBX_QUIET)) 236 printf("failed to parse bootonce " 237 "command\n"); 238 exit(0); 239 } 240 if (!OPT_CHECK(RBX_QUIET)) 241 printf("zfs bootonce: %s\n", cmddup); 242 243 if (zfs_get_bootenv(bdev, &benv) == 0) { 244 nvlist_add_string(benv, OS_BOOTONCE_USED, 245 cmddup); 246 zfs_set_bootenv(bdev, benv); 247 } 248 /* Do not process this command twice */ 249 *cmd = 0; 250 } 251 } 252 253 /* now make sure we have bdev on all cases */ 254 free(bdev); 255 i386_getdev((void **)&bdev, boot_devname, NULL); 256 257 env_setenv("currdev", EV_VOLATILE, boot_devname, gen_setcurrdev, 258 env_nounset); 259 260 /* Process configuration file */ 261 auto_boot = 1; 262 263 fd = open(PATH_CONFIG, O_RDONLY); 264 if (fd == -1) 265 fd = open(PATH_DOTCONFIG, O_RDONLY); 266 267 if (fd != -1) { 268 ssize_t cmdlen; 269 270 if ((cmdlen = read(fd, cmd, sizeof(cmd))) > 0) 271 cmd[cmdlen] = '\0'; 272 else 273 *cmd = '\0'; 274 close(fd); 275 } 276 277 if (*cmd) { 278 /* 279 * Note that parse_cmd() is destructive to cmd[] and we also 280 * want to honor RBX_QUIET option that could be present in 281 * cmd[]. 282 */ 283 memcpy(cmddup, cmd, sizeof(cmd)); 284 if (parse_cmd()) 285 auto_boot = 0; 286 if (!OPT_CHECK(RBX_QUIET)) 287 printf("%s: %s\n", PATH_CONFIG, cmddup); 288 /* Do not process this command twice */ 289 *cmd = 0; 290 } 291 292 /* Do not risk waiting at the prompt forever. */ 293 if (nextboot && !auto_boot) 294 exit(0); 295 296 if (auto_boot && !*kname) { 297 /* 298 * Iterate through the list of loader and kernel paths, 299 * trying to load. If interrupted by a keypress, or in case of 300 * failure, drop the user to the boot2 prompt. 301 */ 302 for (i = 0; i < nitems(loadpath); i++) { 303 memcpy(kname, loadpath[i].p, loadpath[i].len); 304 if (keyhit(3)) 305 break; 306 load(); 307 } 308 } 309 310 /* Present the user with the boot2 prompt. */ 311 312 for (;;) { 313 if (!auto_boot || !OPT_CHECK(RBX_QUIET)) { 314 printf("\nFreeBSD/x86 boot\n"); 315 printf("Default: %s%s\nboot: ", boot_devname, kname); 316 } 317 if (ioctrl & IO_SERIAL) 318 sio_flush(); 319 if (!auto_boot || keyhit(5)) 320 getstr(cmd, sizeof(cmd)); 321 else if (!auto_boot || !OPT_CHECK(RBX_QUIET)) 322 putchar('\n'); 323 auto_boot = 0; 324 if (parse_cmd()) 325 putchar('\a'); 326 else 327 load(); 328 } 329 } 330 331 /* XXX - Needed for btxld to link the boot2 binary; do not remove. */ 332 void 333 exit(int x) 334 { 335 __exit(x); 336 } 337 338 static void 339 load(void) 340 { 341 union { 342 struct exec ex; 343 Elf32_Ehdr eh; 344 } hdr; 345 static Elf32_Phdr ep[2]; 346 static Elf32_Shdr es[2]; 347 caddr_t p; 348 uint32_t addr, x; 349 int fd, fmt, i, j; 350 ssize_t size; 351 352 if ((fd = open(kname, O_RDONLY)) == -1) { 353 printf("\nCan't find %s\n", kname); 354 return; 355 } 356 357 size = sizeof(hdr); 358 if (read(fd, &hdr, sizeof (hdr)) != size) { 359 close(fd); 360 return; 361 } 362 if (N_GETMAGIC(hdr.ex) == ZMAGIC) { 363 fmt = 0; 364 } else if (IS_ELF(hdr.eh)) { 365 fmt = 1; 366 } else { 367 printf("Invalid %s\n", "format"); 368 close(fd); 369 return; 370 } 371 if (fmt == 0) { 372 addr = hdr.ex.a_entry & 0xffffff; 373 p = PTOV(addr); 374 lseek(fd, PAGE_SIZE, SEEK_SET); 375 size = hdr.ex.a_text; 376 if (read(fd, p, hdr.ex.a_text) != size) { 377 close(fd); 378 return; 379 } 380 p += roundup2(hdr.ex.a_text, PAGE_SIZE); 381 size = hdr.ex.a_data; 382 if (read(fd, p, hdr.ex.a_data) != size) { 383 close(fd); 384 return; 385 } 386 p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); 387 bootinfo.bi_symtab = VTOP(p); 388 memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); 389 p += sizeof(hdr.ex.a_syms); 390 if (hdr.ex.a_syms) { 391 size = hdr.ex.a_syms; 392 if (read(fd, p, hdr.ex.a_syms) != size) { 393 close(fd); 394 return; 395 } 396 p += hdr.ex.a_syms; 397 size = sizeof (int); 398 if (read(fd, p, sizeof (int)) != size) { 399 close(fd); 400 return; 401 } 402 x = *(uint32_t *)p; 403 p += sizeof(int); 404 x -= sizeof(int); 405 size = x; 406 if (read(fd, p, x) != size) { 407 close(fd); 408 return; 409 } 410 p += x; 411 } 412 } else { 413 lseek(fd, hdr.eh.e_phoff, SEEK_SET); 414 for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { 415 size = sizeof (ep[0]); 416 if (read(fd, ep + j, sizeof (ep[0])) != size) { 417 close(fd); 418 return; 419 } 420 if (ep[j].p_type == PT_LOAD) 421 j++; 422 } 423 for (i = 0; i < 2; i++) { 424 p = PTOV(ep[i].p_paddr & 0xffffff); 425 lseek(fd, ep[i].p_offset, SEEK_SET); 426 size = ep[i].p_filesz; 427 if (read(fd, p, ep[i].p_filesz) != size) { 428 close(fd); 429 return; 430 } 431 } 432 p += roundup2(ep[1].p_memsz, PAGE_SIZE); 433 bootinfo.bi_symtab = VTOP(p); 434 if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { 435 lseek(fd, hdr.eh.e_shoff + 436 sizeof (es[0]) * (hdr.eh.e_shstrndx + 1), 437 SEEK_SET); 438 size = sizeof(es); 439 if (read(fd, &es, sizeof (es)) != size) { 440 close(fd); 441 return; 442 } 443 for (i = 0; i < 2; i++) { 444 memcpy(p, &es[i].sh_size, 445 sizeof(es[i].sh_size)); 446 p += sizeof(es[i].sh_size); 447 lseek(fd, es[i].sh_offset, SEEK_SET); 448 size = es[i].sh_size; 449 if (read(fd, p, es[i].sh_size) != size) { 450 close(fd); 451 return; 452 } 453 p += es[i].sh_size; 454 } 455 } 456 addr = hdr.eh.e_entry & 0xffffff; 457 } 458 close(fd); 459 460 bootinfo.bi_esymtab = VTOP(p); 461 bootinfo.bi_kernelname = VTOP(kname); 462 #ifdef LOADER_GELI_SUPPORT 463 explicit_bzero(gelipw, sizeof(gelipw)); 464 #endif 465 466 if (bdev->dd.d_dev->dv_type == DEVT_ZFS) { 467 zfsargs.size = sizeof(zfsargs); 468 zfsargs.pool = bdev->zfs.pool_guid; 469 zfsargs.root = bdev->zfs.root_guid; 470 #ifdef LOADER_GELI_SUPPORT 471 export_geli_boot_data(&zfsargs.gelidata); 472 #endif 473 /* 474 * Note that the zfsargs struct is passed by value, not by 475 * pointer. Code in btxldr.S copies the values from the entry 476 * stack to a fixed location within loader(8) at startup due 477 * to the presence of KARGS_FLAGS_EXTARG. 478 */ 479 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 480 bootdev, 481 KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, 482 (uint32_t)bdev->zfs.pool_guid, 483 (uint32_t)(bdev->zfs.pool_guid >> 32), 484 VTOP(&bootinfo), 485 zfsargs); 486 } else { 487 #ifdef LOADER_GELI_SUPPORT 488 geliargs.size = sizeof(geliargs); 489 export_geli_boot_data(&geliargs.gelidata); 490 #endif 491 492 /* 493 * Note that the geliargs struct is passed by value, not by 494 * pointer. Code in btxldr.S copies the values from the entry 495 * stack to a fixed location within loader(8) at startup due 496 * to the presence of the KARGS_FLAGS_EXTARG flag. 497 */ 498 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 499 bootdev, 500 #ifdef LOADER_GELI_SUPPORT 501 KARGS_FLAGS_GELI | KARGS_FLAGS_EXTARG, 0, 0, 502 VTOP(&bootinfo), geliargs 503 #else 504 0, 0, 0, VTOP(&bootinfo) 505 #endif 506 ); 507 } 508 } 509 510 static int 511 mount_root(char *arg) 512 { 513 char *root; 514 struct i386_devdesc *ddesc; 515 uint8_t part; 516 517 if (asprintf(&root, "%s:", arg) < 0) 518 return (1); 519 520 if (i386_getdev((void **)&ddesc, root, NULL)) { 521 free(root); 522 return (1); 523 } 524 525 /* we should have new device descriptor, free old and replace it. */ 526 free(bdev); 527 bdev = ddesc; 528 if (bdev->dd.d_dev->dv_type == DEVT_DISK) { 529 if (bdev->disk.d_partition == -1) 530 part = 0xff; 531 else 532 part = bdev->disk.d_partition; 533 bootdev = MAKEBOOTDEV(dev_maj[bdev->dd.d_dev->dv_type], 534 bdev->disk.d_slice + 1, bdev->dd.d_unit, part); 535 bootinfo.bi_bios_dev = bd_unit2bios(bdev); 536 } 537 strncpy(boot_devname, root, sizeof (boot_devname)); 538 setenv("currdev", root, 1); 539 free(root); 540 return (0); 541 } 542 543 static void 544 fs_list(char *arg) 545 { 546 int fd; 547 struct dirent *d; 548 char line[80]; 549 550 fd = open(arg, O_RDONLY); 551 if (fd < 0) 552 return; 553 pager_open(); 554 while ((d = readdirfd(fd)) != NULL) { 555 sprintf(line, "%s\n", d->d_name); 556 if (pager_output(line)) 557 break; 558 } 559 pager_close(); 560 close(fd); 561 } 562 563 static int 564 parse_cmd(void) 565 { 566 char *arg = cmd; 567 char *ep, *p, *q; 568 const char *cp; 569 char line[80]; 570 int c, i, j; 571 572 while ((c = *arg++)) { 573 if (c == ' ' || c == '\t' || c == '\n') 574 continue; 575 for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++) 576 ; 577 ep = p; 578 if (*p) 579 *p++ = 0; 580 if (c == '-') { 581 while ((c = *arg++)) { 582 if (c == 'P') { 583 if (*(uint8_t *)PTOV(0x496) & 0x10) { 584 cp = "yes"; 585 } else { 586 opts |= OPT_SET(RBX_DUAL); 587 opts |= OPT_SET(RBX_SERIAL); 588 cp = "no"; 589 } 590 printf("Keyboard: %s\n", cp); 591 continue; 592 } else if (c == 'S') { 593 j = 0; 594 while ((unsigned int) 595 (i = *arg++ - '0') <= 9) 596 j = j * 10 + i; 597 if (j > 0 && i == -'0') { 598 comspeed = j; 599 break; 600 } 601 /* 602 * Fall through to error below 603 * ('S' not in optstr[]). 604 */ 605 } 606 for (i = 0; c != optstr[i]; i++) 607 if (i == NOPT - 1) 608 return (-1); 609 opts ^= OPT_SET(flags[i]); 610 } 611 ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : 612 OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; 613 if (ioctrl & IO_SERIAL) { 614 if (sio_init(115200 / comspeed) != 0) 615 ioctrl &= ~IO_SERIAL; 616 } 617 } if (c == '?') { 618 printf("\n"); 619 if (*arg == '\0') 620 arg = (char *)"/"; 621 fs_list(arg); 622 zfs_list(arg); 623 return (-1); 624 } else { 625 char *ptr; 626 printf("\n"); 627 arg--; 628 629 /* 630 * Report pool status if the comment is 'status'. Lets 631 * hope no-one wants to load /status as a kernel. 632 */ 633 if (strcmp(arg, "status") == 0) { 634 pager_open(); 635 for (i = 0; devsw[i] != NULL; i++) { 636 if (devsw[i]->dv_print != NULL) { 637 if (devsw[i]->dv_print(1)) 638 break; 639 } else { 640 snprintf(line, sizeof(line), 641 "%s: (unknown)\n", 642 devsw[i]->dv_name); 643 if (pager_output(line)) 644 break; 645 } 646 } 647 pager_close(); 648 return (-1); 649 } 650 651 /* 652 * If there is "zfs:" prefix simply ignore it. 653 */ 654 ptr = arg; 655 if (strncmp(ptr, "zfs:", 4) == 0) 656 ptr += 4; 657 658 /* 659 * If there is a colon, switch pools. 660 */ 661 q = strchr(ptr, ':'); 662 if (q) { 663 *q++ = '\0'; 664 if (mount_root(arg) != 0) { 665 return (-1); 666 } 667 arg = q; 668 } 669 if ((i = ep - arg)) { 670 if ((size_t)i >= sizeof(kname)) 671 return (-1); 672 memcpy(kname, arg, i + 1); 673 } 674 } 675 arg = p; 676 } 677 return (0); 678 } 679 680 /* 681 * Probe all disks to discover ZFS pools. The idea is to walk all possible 682 * disk devices, however, we also need to identify possible boot pool. 683 * For boot pool detection we have boot disk passed us from BIOS, recorded 684 * in bootinfo.bi_bios_dev. 685 */ 686 static void 687 i386_zfs_probe(void) 688 { 689 char devname[32]; 690 int boot_unit; 691 struct i386_devdesc dev; 692 uint64_t pool_guid = 0; 693 694 dev.dd.d_dev = &bioshd; 695 /* Translate bios dev to our unit number. */ 696 boot_unit = bd_bios2unit(bootinfo.bi_bios_dev); 697 698 /* 699 * Open all the disks we can find and see if we can reconstruct 700 * ZFS pools from them. 701 */ 702 for (dev.dd.d_unit = 0; bd_unit2bios(&dev) >= 0; dev.dd.d_unit++) { 703 snprintf(devname, sizeof (devname), "%s%d:", bioshd.dv_name, 704 dev.dd.d_unit); 705 /* If this is not boot disk, use generic probe. */ 706 if (dev.dd.d_unit != boot_unit) 707 zfs_probe_dev(devname, NULL, true); 708 else 709 zfs_probe_dev(devname, &pool_guid, true); 710 711 if (pool_guid != 0 && bdev == NULL) { 712 bdev = malloc(sizeof (struct i386_devdesc)); 713 bzero(bdev, sizeof (struct i386_devdesc)); 714 bdev->zfs.dd.d_dev = &zfs_dev; 715 bdev->zfs.pool_guid = pool_guid; 716 } 717 } 718 } 719