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