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 <stand.h> 17 18 #include <sys/param.h> 19 #include <sys/errno.h> 20 #include <sys/diskmbr.h> 21 #ifdef GPT 22 #include <sys/gpt.h> 23 #endif 24 #include <sys/reboot.h> 25 #include <sys/queue.h> 26 #ifdef LOADER_ZFS_SUPPORT 27 #include <sys/zfs_bootenv.h> 28 #endif 29 30 #include <machine/bootinfo.h> 31 #include <machine/elf.h> 32 #include <machine/pc/bios.h> 33 34 #include <stdarg.h> 35 #include <stddef.h> 36 37 #include <a.out.h> 38 #include "bootstrap.h" 39 #include "libi386.h" 40 #include <btxv86.h> 41 42 #include "lib.h" 43 #include "rbx.h" 44 #include "cons.h" 45 #include "bootargs.h" 46 #include "disk.h" 47 #include "part.h" 48 #include "paths.h" 49 50 #include "libzfs.h" 51 52 #define ARGS 0x900 53 #define NOPT 14 54 #define NDEV 3 55 56 #define BIOS_NUMDRIVES 0x475 57 #define DRV_HARD 0x80 58 #define DRV_MASK 0x7f 59 60 #define TYPE_AD 0 61 #define TYPE_DA 1 62 #define TYPE_MAXHARD TYPE_DA 63 #define TYPE_FD 2 64 65 extern uint32_t _end; 66 67 static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ 68 static const unsigned char flags[NOPT] = { 69 RBX_DUAL, 70 RBX_SERIAL, 71 RBX_ASKNAME, 72 RBX_CDROM, 73 RBX_CONFIG, 74 RBX_KDB, 75 RBX_GDB, 76 RBX_MUTE, 77 RBX_NOINTR, 78 RBX_PAUSE, 79 RBX_QUIET, 80 RBX_DFLTROOT, 81 RBX_SINGLE, 82 RBX_VERBOSE 83 }; 84 uint32_t opts; 85 86 /* 87 * Paths to try loading before falling back to the boot2 prompt. 88 * 89 * /boot/zfsloader must be tried before /boot/loader in order to remain 90 * backward compatible with ZFS boot environments where /boot/loader exists 91 * but does not have ZFS support, which was the case before FreeBSD 12. 92 * 93 * If no loader is found, try to load a kernel directly instead. 94 */ 95 static const struct string { 96 const char *p; 97 size_t len; 98 } loadpath[] = { 99 { PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS) }, 100 { PATH_LOADER, sizeof(PATH_LOADER) }, 101 { PATH_KERNEL, sizeof(PATH_KERNEL) }, 102 }; 103 104 static const unsigned char dev_maj[NDEV] = {30, 4, 2}; 105 106 static struct i386_devdesc *bdev; 107 static char cmd[512]; 108 static char cmddup[512]; 109 static char kname[1024]; 110 static int comspeed = SIOSPD; 111 static struct bootinfo bootinfo; 112 static uint32_t bootdev; 113 static struct zfs_boot_args zfsargs; 114 #ifdef LOADER_GELI_SUPPORT 115 static struct geli_boot_args geliargs; 116 #endif 117 118 extern vm_offset_t high_heap_base; 119 extern uint32_t bios_basemem, bios_extmem, high_heap_size; 120 121 static char *heap_top; 122 static char *heap_bottom; 123 124 void exit(int); 125 static void i386_zfs_probe(void); 126 static void load(void); 127 static int parse_cmd(void); 128 129 #ifdef LOADER_GELI_SUPPORT 130 #include "geliboot.h" 131 static char gelipw[GELI_PW_MAXLEN]; 132 #endif 133 134 struct arch_switch archsw; /* MI/MD interface boundary */ 135 static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */ 136 137 struct devsw *devsw[] = { 138 &bioshd, 139 #if defined(LOADER_ZFS_SUPPORT) 140 &zfs_dev, 141 #endif 142 NULL 143 }; 144 145 struct fs_ops *file_system[] = { 146 #if defined(LOADER_ZFS_SUPPORT) 147 &zfs_fsops, 148 #endif 149 #if defined(LOADER_UFS_SUPPORT) 150 &ufs_fsops, 151 #endif 152 NULL 153 }; 154 155 caddr_t 156 ptov(uintptr_t x) 157 { 158 return (PTOV(x)); 159 } 160 161 int main(void); 162 163 int 164 main(void) 165 { 166 unsigned i; 167 int auto_boot, fd, nextboot = 0; 168 struct disk_devdesc *devdesc; 169 170 bios_getmem(); 171 172 if (high_heap_size > 0) { 173 heap_top = PTOV(high_heap_base + high_heap_size); 174 heap_bottom = PTOV(high_heap_base); 175 } else { 176 heap_bottom = (char *) 177 (roundup2(__base + (int32_t)&_end, 0x10000) - __base); 178 heap_top = (char *)PTOV(bios_basemem); 179 } 180 setheap(heap_bottom, heap_top); 181 182 /* 183 * Initialise the block cache. Set the upper limit. 184 */ 185 bcache_init(32768, 512); 186 187 archsw.arch_autoload = NULL; 188 archsw.arch_getdev = i386_getdev; 189 archsw.arch_copyin = NULL; 190 archsw.arch_copyout = NULL; 191 archsw.arch_readin = NULL; 192 archsw.arch_isainb = NULL; 193 archsw.arch_isaoutb = NULL; 194 archsw.arch_zfs_probe = i386_zfs_probe; 195 196 bootinfo.bi_version = BOOTINFO_VERSION; 197 bootinfo.bi_size = sizeof(bootinfo); 198 bootinfo.bi_basemem = bios_basemem / 1024; 199 bootinfo.bi_extmem = bios_extmem / 1024; 200 bootinfo.bi_memsizes_valid++; 201 bootinfo.bi_bios_dev = *(uint8_t *)PTOV(ARGS); 202 203 /* Set up fall back device name. */ 204 snprintf(boot_devname, sizeof (boot_devname), "disk%d:", 205 bd_bios2unit(bootinfo.bi_bios_dev)); 206 207 /* Set up currdev variable to have hooks in place. */ 208 env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, 209 env_nounset); 210 211 devinit(); 212 213 /* XXX assumes this will be a disk, but it looks likely give above */ 214 disk_parsedev((struct devdesc **)&devdesc, boot_devname, 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 free(devdesc); 220 221 /* 222 * devformat() can be called only after dv_init 223 */ 224 if (bdev != NULL && bdev->dd.d_dev->dv_type == DEVT_ZFS) { 225 /* set up proper device name string for ZFS */ 226 strncpy(boot_devname, devformat(&bdev->dd), sizeof (boot_devname)); 227 if (zfs_get_bootonce(bdev, OS_BOOTONCE, cmd, 228 sizeof(cmd)) == 0) { 229 nvlist_t *benv; 230 231 nextboot = 1; 232 memcpy(cmddup, cmd, sizeof(cmd)); 233 if (parse_cmd()) { 234 if (!OPT_CHECK(RBX_QUIET)) 235 printf("failed to parse bootonce " 236 "command\n"); 237 exit(0); 238 } 239 if (!OPT_CHECK(RBX_QUIET)) 240 printf("zfs bootonce: %s\n", cmddup); 241 242 if (zfs_get_bootenv(bdev, &benv) == 0) { 243 nvlist_add_string(benv, OS_BOOTONCE_USED, 244 cmddup); 245 zfs_set_bootenv(bdev, benv); 246 } 247 /* Do not process this command twice */ 248 *cmd = 0; 249 } 250 } 251 252 /* now make sure we have bdev on all cases */ 253 free(bdev); 254 i386_getdev((void **)&bdev, boot_devname, NULL); 255 256 env_setenv("currdev", EV_VOLATILE, boot_devname, gen_setcurrdev, 257 env_nounset); 258 259 /* Process configuration file */ 260 auto_boot = 1; 261 262 fd = open(PATH_CONFIG, O_RDONLY); 263 if (fd == -1) 264 fd = open(PATH_DOTCONFIG, O_RDONLY); 265 266 if (fd != -1) { 267 ssize_t cmdlen; 268 269 if ((cmdlen = read(fd, cmd, sizeof(cmd))) > 0) 270 cmd[cmdlen] = '\0'; 271 else 272 *cmd = '\0'; 273 close(fd); 274 } 275 276 if (*cmd) { 277 /* 278 * Note that parse_cmd() is destructive to cmd[] and we also 279 * want to honor RBX_QUIET option that could be present in 280 * cmd[]. 281 */ 282 memcpy(cmddup, cmd, sizeof(cmd)); 283 if (parse_cmd()) 284 auto_boot = 0; 285 if (!OPT_CHECK(RBX_QUIET)) 286 printf("%s: %s\n", PATH_CONFIG, cmddup); 287 /* Do not process this command twice */ 288 *cmd = 0; 289 } 290 291 /* Do not risk waiting at the prompt forever. */ 292 if (nextboot && !auto_boot) 293 exit(0); 294 295 if (auto_boot && !*kname) { 296 /* 297 * Iterate through the list of loader and kernel paths, 298 * trying to load. If interrupted by a keypress, or in case of 299 * failure, drop the user to the boot2 prompt. 300 */ 301 for (i = 0; i < nitems(loadpath); i++) { 302 memcpy(kname, loadpath[i].p, loadpath[i].len); 303 if (keyhit(3)) 304 break; 305 load(); 306 } 307 } 308 309 /* Present the user with the boot2 prompt. */ 310 311 for (;;) { 312 if (!auto_boot || !OPT_CHECK(RBX_QUIET)) { 313 printf("\nFreeBSD/x86 boot\n"); 314 printf("Default: %s%s\nboot: ", boot_devname, kname); 315 } 316 if (ioctrl & IO_SERIAL) 317 sio_flush(); 318 if (!auto_boot || keyhit(5)) 319 getstr(cmd, sizeof(cmd)); 320 else if (!auto_boot || !OPT_CHECK(RBX_QUIET)) 321 putchar('\n'); 322 auto_boot = 0; 323 if (parse_cmd()) 324 putchar('\a'); 325 else 326 load(); 327 } 328 } 329 330 /* XXX - Needed for btxld to link the boot2 binary; do not remove. */ 331 void 332 exit(int x) 333 { 334 __exit(x); 335 } 336 337 static void 338 load(void) 339 { 340 union { 341 struct exec ex; 342 Elf32_Ehdr eh; 343 } hdr; 344 static Elf32_Phdr ep[2]; 345 static Elf32_Shdr es[2]; 346 caddr_t p; 347 uint32_t addr, x; 348 int fd, fmt, i, j; 349 ssize_t size; 350 351 if ((fd = open(kname, O_RDONLY)) == -1) { 352 printf("\nCan't find %s\n", kname); 353 return; 354 } 355 356 size = sizeof(hdr); 357 if (read(fd, &hdr, sizeof (hdr)) != size) { 358 close(fd); 359 return; 360 } 361 if (N_GETMAGIC(hdr.ex) == ZMAGIC) { 362 fmt = 0; 363 } else if (IS_ELF(hdr.eh)) { 364 fmt = 1; 365 } else { 366 printf("Invalid %s\n", "format"); 367 close(fd); 368 return; 369 } 370 if (fmt == 0) { 371 addr = hdr.ex.a_entry & 0xffffff; 372 p = PTOV(addr); 373 lseek(fd, PAGE_SIZE, SEEK_SET); 374 size = hdr.ex.a_text; 375 if (read(fd, p, hdr.ex.a_text) != size) { 376 close(fd); 377 return; 378 } 379 p += roundup2(hdr.ex.a_text, PAGE_SIZE); 380 size = hdr.ex.a_data; 381 if (read(fd, p, hdr.ex.a_data) != size) { 382 close(fd); 383 return; 384 } 385 p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); 386 bootinfo.bi_symtab = VTOP(p); 387 memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); 388 p += sizeof(hdr.ex.a_syms); 389 if (hdr.ex.a_syms) { 390 size = hdr.ex.a_syms; 391 if (read(fd, p, hdr.ex.a_syms) != size) { 392 close(fd); 393 return; 394 } 395 p += hdr.ex.a_syms; 396 size = sizeof (int); 397 if (read(fd, p, sizeof (int)) != size) { 398 close(fd); 399 return; 400 } 401 x = *(uint32_t *)p; 402 p += sizeof(int); 403 x -= sizeof(int); 404 size = x; 405 if (read(fd, p, x) != size) { 406 close(fd); 407 return; 408 } 409 p += x; 410 } 411 } else { 412 lseek(fd, hdr.eh.e_phoff, SEEK_SET); 413 for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { 414 size = sizeof (ep[0]); 415 if (read(fd, ep + j, sizeof (ep[0])) != size) { 416 close(fd); 417 return; 418 } 419 if (ep[j].p_type == PT_LOAD) 420 j++; 421 } 422 for (i = 0; i < 2; i++) { 423 p = PTOV(ep[i].p_paddr & 0xffffff); 424 lseek(fd, ep[i].p_offset, SEEK_SET); 425 size = ep[i].p_filesz; 426 if (read(fd, p, ep[i].p_filesz) != size) { 427 close(fd); 428 return; 429 } 430 } 431 p += roundup2(ep[1].p_memsz, PAGE_SIZE); 432 bootinfo.bi_symtab = VTOP(p); 433 if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { 434 lseek(fd, hdr.eh.e_shoff + 435 sizeof (es[0]) * (hdr.eh.e_shstrndx + 1), 436 SEEK_SET); 437 size = sizeof(es); 438 if (read(fd, &es, sizeof (es)) != size) { 439 close(fd); 440 return; 441 } 442 for (i = 0; i < 2; i++) { 443 memcpy(p, &es[i].sh_size, 444 sizeof(es[i].sh_size)); 445 p += sizeof(es[i].sh_size); 446 lseek(fd, es[i].sh_offset, SEEK_SET); 447 size = es[i].sh_size; 448 if (read(fd, p, es[i].sh_size) != size) { 449 close(fd); 450 return; 451 } 452 p += es[i].sh_size; 453 } 454 } 455 addr = hdr.eh.e_entry & 0xffffff; 456 } 457 close(fd); 458 459 bootinfo.bi_esymtab = VTOP(p); 460 bootinfo.bi_kernelname = VTOP(kname); 461 #ifdef LOADER_GELI_SUPPORT 462 explicit_bzero(gelipw, sizeof(gelipw)); 463 #endif 464 465 if (bdev->dd.d_dev->dv_type == DEVT_ZFS) { 466 zfsargs.size = sizeof(zfsargs); 467 zfsargs.pool = bdev->zfs.pool_guid; 468 zfsargs.root = bdev->zfs.root_guid; 469 #ifdef LOADER_GELI_SUPPORT 470 export_geli_boot_data(&zfsargs.gelidata); 471 #endif 472 /* 473 * Note that the zfsargs struct is passed by value, not by 474 * pointer. Code in btxldr.S copies the values from the entry 475 * stack to a fixed location within loader(8) at startup due 476 * to the presence of KARGS_FLAGS_EXTARG. 477 */ 478 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 479 bootdev, 480 KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, 481 (uint32_t)bdev->zfs.pool_guid, 482 (uint32_t)(bdev->zfs.pool_guid >> 32), 483 VTOP(&bootinfo), 484 zfsargs); 485 } else { 486 #ifdef LOADER_GELI_SUPPORT 487 geliargs.size = sizeof(geliargs); 488 export_geli_boot_data(&geliargs.gelidata); 489 #endif 490 491 /* 492 * Note that the geliargs struct is passed by value, not by 493 * pointer. Code in btxldr.S copies the values from the entry 494 * stack to a fixed location within loader(8) at startup due 495 * to the presence of the KARGS_FLAGS_EXTARG flag. 496 */ 497 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 498 bootdev, 499 #ifdef LOADER_GELI_SUPPORT 500 KARGS_FLAGS_GELI | KARGS_FLAGS_EXTARG, 0, 0, 501 VTOP(&bootinfo), geliargs 502 #else 503 0, 0, 0, VTOP(&bootinfo) 504 #endif 505 ); 506 } 507 } 508 509 static int 510 mount_root(char *arg) 511 { 512 char *root; 513 struct i386_devdesc *ddesc; 514 uint8_t part; 515 516 if (asprintf(&root, "%s:", arg) < 0) 517 return (1); 518 519 if (i386_getdev((void **)&ddesc, root, NULL)) { 520 free(root); 521 return (1); 522 } 523 524 /* we should have new device descriptor, free old and replace it. */ 525 free(bdev); 526 bdev = ddesc; 527 if (bdev->dd.d_dev->dv_type == DEVT_DISK) { 528 if (bdev->disk.d_partition == -1) 529 part = 0xff; 530 else 531 part = bdev->disk.d_partition; 532 bootdev = MAKEBOOTDEV(dev_maj[bdev->dd.d_dev->dv_type], 533 bdev->disk.d_slice + 1, 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, true); 707 else 708 zfs_probe_dev(devname, &pool_guid, true); 709 710 if (pool_guid != 0 && bdev == NULL) { 711 bdev = malloc(sizeof (struct i386_devdesc)); 712 bzero(bdev, sizeof (struct i386_devdesc)); 713 bdev->zfs.dd.d_dev = &zfs_dev; 714 bdev->zfs.pool_guid = pool_guid; 715 } 716 } 717 } 718