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