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