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