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 #include <stand.h> 18 19 #include <sys/param.h> 20 #include <sys/errno.h> 21 #include <sys/diskmbr.h> 22 #include <sys/vtoc.h> 23 #include <sys/disk.h> 24 #include <sys/reboot.h> 25 #include <sys/queue.h> 26 #include <multiboot.h> 27 28 #include <machine/bootinfo.h> 29 #include <machine/elf.h> 30 #include <machine/pc/bios.h> 31 32 #include <stdarg.h> 33 #include <stddef.h> 34 35 #include <a.out.h> 36 #include "bootstrap.h" 37 #include "libi386.h" 38 #include <btxv86.h> 39 40 #include "lib.h" 41 #include "rbx.h" 42 #include "cons.h" 43 #include "bootargs.h" 44 #include "disk.h" 45 #include "part.h" 46 #include "paths.h" 47 48 #include "libzfs.h" 49 50 #define ARGS 0x900 51 #define NOPT 14 52 #define NDEV 3 53 54 #define BIOS_NUMDRIVES 0x475 55 #define DRV_HARD 0x80 56 #define DRV_MASK 0x7f 57 58 #define TYPE_AD 0 59 #define TYPE_DA 1 60 #define TYPE_MAXHARD TYPE_DA 61 #define TYPE_FD 2 62 63 extern uint32_t _end; 64 65 /* 66 * Fake multiboot header to provide versioning and to pass 67 * partition start LBA. Partition is either GPT partition or 68 * VTOC slice. 69 */ 70 extern const struct multiboot_header mb_header; 71 extern uint64_t start_sector; 72 73 static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ 74 static const unsigned char flags[NOPT] = { 75 RBX_DUAL, 76 RBX_SERIAL, 77 RBX_ASKNAME, 78 RBX_CDROM, 79 RBX_CONFIG, 80 RBX_KDB, 81 RBX_GDB, 82 RBX_MUTE, 83 RBX_NOINTR, 84 RBX_PAUSE, 85 RBX_QUIET, 86 RBX_DFLTROOT, 87 RBX_SINGLE, 88 RBX_VERBOSE 89 }; 90 uint32_t opts; 91 92 static const unsigned char dev_maj[NDEV] = {30, 4, 2}; 93 94 static struct i386_devdesc *bdev; 95 static char cmd[512]; 96 static char cmddup[512]; 97 static char kname[1024]; 98 static int comspeed = SIOSPD; 99 static struct bootinfo bootinfo; 100 static uint32_t bootdev; 101 static struct zfs_boot_args zfsargs; 102 103 extern vm_offset_t high_heap_base; 104 extern uint32_t bios_basemem, bios_extmem, high_heap_size; 105 106 static char *heap_top; 107 static char *heap_bottom; 108 109 static void i386_zfs_probe(void); 110 void exit(int); 111 static void load(void); 112 static int parse_cmd(void); 113 114 struct arch_switch archsw; /* MI/MD interface boundary */ 115 static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */ 116 117 struct devsw *devsw[] = { 118 &biosdisk, 119 &zfs_dev, 120 NULL 121 }; 122 123 struct fs_ops *file_system[] = { 124 &zfs_fsops, 125 &ufs_fsops, 126 &dosfs_fsops, 127 NULL 128 }; 129 130 int 131 main(void) 132 { 133 int auto_boot, i, fd; 134 struct disk_devdesc devdesc; 135 136 bios_getmem(); 137 138 if (high_heap_size > 0) { 139 heap_top = PTOV(high_heap_base + high_heap_size); 140 heap_bottom = PTOV(high_heap_base); 141 } else { 142 heap_bottom = (char *) 143 (roundup2(__base + (int32_t)&_end, 0x10000) - __base); 144 heap_top = (char *) PTOV(bios_basemem); 145 } 146 setheap(heap_bottom, heap_top); 147 148 /* 149 * Initialise the block cache. Set the upper limit. 150 */ 151 bcache_init(32768, 512); 152 153 archsw.arch_autoload = NULL; 154 archsw.arch_getdev = i386_getdev; 155 archsw.arch_copyin = NULL; 156 archsw.arch_copyout = NULL; 157 archsw.arch_readin = NULL; 158 archsw.arch_isainb = NULL; 159 archsw.arch_isaoutb = NULL; 160 archsw.arch_zfs_probe = i386_zfs_probe; 161 162 bootinfo.bi_version = BOOTINFO_VERSION; 163 bootinfo.bi_size = sizeof(bootinfo); 164 bootinfo.bi_basemem = bios_basemem / 1024; 165 bootinfo.bi_extmem = bios_extmem / 1024; 166 bootinfo.bi_memsizes_valid++; 167 bootinfo.bi_bios_dev = *(uint8_t *)PTOV(ARGS); 168 169 /* Set up fall back device name. */ 170 snprintf(boot_devname, sizeof (boot_devname), "disk%d:", 171 bd_bios2unit(bootinfo.bi_bios_dev)); 172 173 for (i = 0; devsw[i] != NULL; i++) 174 if (devsw[i]->dv_init != NULL) 175 (devsw[i]->dv_init)(); 176 177 disk_parsedev(&devdesc, boot_devname+4, NULL); 178 179 bootdev = MAKEBOOTDEV(dev_maj[devdesc.d_type], devdesc.d_slice + 1, 180 devdesc.d_unit, devdesc.d_partition >= 0? devdesc.d_partition:0xff); 181 182 /* 183 * zfs_fmtdev() can be called only after dv_init 184 */ 185 if (bdev != NULL && bdev->d_type == DEVT_ZFS) { 186 /* set up proper device name string for ZFS */ 187 strncpy(boot_devname, zfs_fmtdev(bdev), sizeof (boot_devname)); 188 } 189 190 /* now make sure we have bdev on all cases */ 191 if (bdev != NULL) 192 free(bdev); 193 i386_getdev((void **)&bdev, boot_devname, NULL); 194 195 env_setenv("currdev", EV_VOLATILE, boot_devname, i386_setcurrdev, 196 env_nounset); 197 198 /* Process configuration file */ 199 setenv("LINES", "24", 1); 200 auto_boot = 1; 201 202 fd = open(PATH_CONFIG, O_RDONLY); 203 if (fd == -1) 204 fd = open(PATH_DOTCONFIG, O_RDONLY); 205 206 if (fd != -1) { 207 read(fd, cmd, sizeof(cmd)); 208 close(fd); 209 } 210 211 if (*cmd) { 212 /* 213 * Note that parse_cmd() is destructive to cmd[] and we also want 214 * to honor RBX_QUIET option that could be present in cmd[]. 215 */ 216 memcpy(cmddup, cmd, sizeof(cmd)); 217 if (parse_cmd()) 218 auto_boot = 0; 219 if (!OPT_CHECK(RBX_QUIET)) 220 printf("%s: %s\n", PATH_CONFIG, cmddup); 221 /* Do not process this command twice */ 222 *cmd = 0; 223 } 224 225 /* 226 * Try to exec stage 3 boot loader. If interrupted by a keypress, 227 * or in case of failure, switch off auto boot. 228 */ 229 230 if (auto_boot && !*kname) { 231 memcpy(kname, PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS)); 232 if (!keyhit(3)) { 233 load(); 234 auto_boot = 0; 235 } 236 } 237 238 /* Present the user with the boot2 prompt. */ 239 240 for (;;) { 241 if (!auto_boot || !OPT_CHECK(RBX_QUIET)) { 242 printf("\nillumos/x86 boot\n"); 243 printf("Default: %s%s\nboot: ", boot_devname, kname); 244 } 245 if (ioctrl & IO_SERIAL) 246 sio_flush(); 247 if (!auto_boot || keyhit(5)) 248 getstr(cmd, sizeof(cmd)); 249 else if (!auto_boot || !OPT_CHECK(RBX_QUIET)) 250 putchar('\n'); 251 auto_boot = 0; 252 if (parse_cmd()) 253 putchar('\a'); 254 else 255 load(); 256 } 257 } 258 259 /* XXX - Needed for btxld to link the boot2 binary; do not remove. */ 260 void 261 exit(int x) 262 { 263 } 264 265 static void 266 load(void) 267 { 268 union { 269 struct exec ex; 270 Elf32_Ehdr eh; 271 } hdr; 272 static Elf32_Phdr ep[2]; 273 static Elf32_Shdr es[2]; 274 caddr_t p; 275 uint32_t addr, x; 276 int fd, fmt, i, j; 277 278 if ((fd = open(kname, O_RDONLY)) == -1) { 279 printf("\nCan't find %s\n", kname); 280 return; 281 } 282 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { 283 close(fd); 284 return; 285 } 286 if (N_GETMAGIC(hdr.ex) == ZMAGIC) 287 fmt = 0; 288 else if (IS_ELF(hdr.eh)) 289 fmt = 1; 290 else { 291 printf("Invalid %s\n", "format"); 292 close(fd); 293 return; 294 } 295 if (fmt == 0) { 296 addr = hdr.ex.a_entry & 0xffffff; 297 p = PTOV(addr); 298 lseek(fd, PAGE_SIZE, SEEK_SET); 299 if (read(fd, p, hdr.ex.a_text) != hdr.ex.a_text) { 300 close(fd); 301 return; 302 } 303 p += roundup2(hdr.ex.a_text, PAGE_SIZE); 304 if (read(fd, p, hdr.ex.a_data) != hdr.ex.a_data) { 305 close(fd); 306 return; 307 } 308 p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE); 309 bootinfo.bi_symtab = VTOP(p); 310 memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms)); 311 p += sizeof(hdr.ex.a_syms); 312 if (hdr.ex.a_syms) { 313 if (read(fd, p, hdr.ex.a_syms) != hdr.ex.a_syms) { 314 close(fd); 315 return; 316 } 317 p += hdr.ex.a_syms; 318 if (read(fd, p, sizeof(int)) != sizeof(int)) { 319 close(fd); 320 return; 321 } 322 x = *(uint32_t *)p; 323 p += sizeof(int); 324 x -= sizeof(int); 325 if (read(fd, p, x) != x) { 326 close(fd); 327 return; 328 } 329 p += x; 330 } 331 } else { 332 lseek(fd, hdr.eh.e_phoff, SEEK_SET); 333 for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) { 334 if (read(fd, ep + j, sizeof(ep[0])) != sizeof(ep[0])) { 335 close(fd); 336 return; 337 } 338 if (ep[j].p_type == PT_LOAD) 339 j++; 340 } 341 for (i = 0; i < 2; i++) { 342 p = PTOV(ep[i].p_paddr & 0xffffff); 343 lseek(fd, ep[i].p_offset, SEEK_SET); 344 if (read(fd, p, ep[i].p_filesz) != ep[i].p_filesz) { 345 close(fd); 346 return; 347 } 348 } 349 p += roundup2(ep[1].p_memsz, PAGE_SIZE); 350 bootinfo.bi_symtab = VTOP(p); 351 if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) { 352 lseek(fd, hdr.eh.e_shoff + sizeof(es[0]) * (hdr.eh.e_shstrndx + 1), 353 SEEK_SET); 354 if (read(fd, &es, sizeof(es)) != sizeof(es)) { 355 close(fd); 356 return; 357 } 358 for (i = 0; i < 2; i++) { 359 memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size)); 360 p += sizeof(es[i].sh_size); 361 lseek(fd, es[i].sh_offset, SEEK_SET); 362 if (read(fd, p, es[i].sh_size) != es[i].sh_size) { 363 close(fd); 364 return; 365 } 366 p += es[i].sh_size; 367 } 368 } 369 addr = hdr.eh.e_entry & 0xffffff; 370 } 371 close(fd); 372 373 bootinfo.bi_esymtab = VTOP(p); 374 bootinfo.bi_kernelname = VTOP(kname); 375 376 if (bdev->d_type == DEVT_ZFS) { 377 zfsargs.size = sizeof(zfsargs); 378 zfsargs.pool = bdev->d_kind.zfs.pool_guid; 379 zfsargs.root = bdev->d_kind.zfs.root_guid; 380 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 381 bootdev, 382 KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG, 383 (uint32_t) bdev->d_kind.zfs.pool_guid, 384 (uint32_t) (bdev->d_kind.zfs.pool_guid >> 32), 385 VTOP(&bootinfo), 386 zfsargs); 387 } else 388 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), 389 bootdev, 0, 0, 0, VTOP(&bootinfo)); 390 } 391 392 static int 393 mount_root(char *arg) 394 { 395 char *root; 396 struct i386_devdesc *ddesc; 397 uint8_t part; 398 399 root = malloc(strlen(arg) + 2); 400 if (root == NULL) 401 return (1); 402 sprintf(root, "%s:", arg); 403 if (i386_getdev((void **)&ddesc, root, NULL)) { 404 free(root); 405 return (1); 406 } 407 408 /* we should have new device descriptor, free old and replace it. */ 409 if (bdev != NULL) 410 free(bdev); 411 bdev = ddesc; 412 if (bdev->d_type == DEVT_DISK) { 413 if (bdev->d_kind.biosdisk.partition == -1) 414 part = 0xff; 415 else 416 part = bdev->d_kind.biosdisk.partition; 417 bootdev = MAKEBOOTDEV(dev_maj[bdev->d_type], 418 bdev->d_kind.biosdisk.slice + 1, 419 bdev->d_unit, part); 420 bootinfo.bi_bios_dev = bd_unit2bios(bdev->d_unit); 421 } 422 setenv("currdev", root, 1); 423 free(root); 424 return (0); 425 } 426 427 static void 428 fs_list(char *arg) 429 { 430 int fd; 431 struct dirent *d; 432 char line[80]; 433 434 fd = open(arg, O_RDONLY); 435 if (fd < 0) 436 return; 437 pager_open(); 438 while ((d = readdirfd(fd)) != NULL) { 439 sprintf(line, "%s\n", d->d_name); 440 if (pager_output(line)) 441 break; 442 } 443 pager_close(); 444 close(fd); 445 } 446 447 static int 448 parse_cmd(void) 449 { 450 char *arg = cmd; 451 char *ep, *p, *q; 452 const char *cp; 453 char line[80]; 454 int c, i, j; 455 456 while ((c = *arg++)) { 457 if (c == ' ' || c == '\t' || c == '\n') 458 continue; 459 for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); 460 ep = p; 461 if (*p) 462 *p++ = 0; 463 if (c == '-') { 464 while ((c = *arg++)) { 465 if (c == 'P') { 466 if (*(uint8_t *)PTOV(0x496) & 0x10) { 467 cp = "yes"; 468 } else { 469 opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); 470 cp = "no"; 471 } 472 printf("Keyboard: %s\n", cp); 473 continue; 474 } else if (c == 'S') { 475 j = 0; 476 while ((unsigned int)(i = *arg++ - '0') <= 9) 477 j = j * 10 + i; 478 if (j > 0 && i == -'0') { 479 comspeed = j; 480 break; 481 } 482 /* Fall through to error below ('S' not in optstr[]). */ 483 } 484 for (i = 0; c != optstr[i]; i++) 485 if (i == NOPT - 1) 486 return -1; 487 opts ^= OPT_SET(flags[i]); 488 } 489 ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : 490 OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; 491 if (ioctrl & IO_SERIAL) { 492 if (sio_init(115200 / comspeed) != 0) 493 ioctrl &= ~IO_SERIAL; 494 } 495 } if (c == '?') { 496 printf("\n"); 497 fs_list(arg); 498 zfs_list(arg); 499 return -1; 500 } else { 501 arg--; 502 503 /* 504 * Report pool status if the comment is 'status'. Lets 505 * hope no-one wants to load /status as a kernel. 506 */ 507 if (!strcmp(arg, "status")) { 508 pager_open(); 509 for (i = 0; devsw[i] != NULL; i++) { 510 if (devsw[i]->dv_print != NULL) { 511 if (devsw[i]->dv_print(1)) 512 break; 513 } else { 514 sprintf(line, "%s: (unknown)\n", devsw[i]->dv_name); 515 if (pager_output(line)) 516 break; 517 } 518 } 519 pager_close(); 520 return -1; 521 } 522 523 /* 524 * If there is a colon, switch pools. 525 */ 526 if (strncmp(arg, "zfs:", 4) == 0) 527 q = strchr(arg + 4, ':'); 528 else 529 q = strchr(arg, ':'); 530 if (q) { 531 *q++ = '\0'; 532 if (mount_root(arg) != 0) 533 return -1; 534 arg = q; 535 } 536 if ((i = ep - arg)) { 537 if ((size_t)i >= sizeof(kname)) 538 return -1; 539 memcpy(kname, arg, i + 1); 540 } 541 } 542 arg = p; 543 } 544 return 0; 545 } 546 547 /* 548 * probe arguments for partition iterator (see below) 549 */ 550 struct probe_args { 551 int fd; 552 char *devname; 553 u_int secsz; 554 uint64_t offset; 555 }; 556 557 /* 558 * simple wrapper around read() to avoid using device specific 559 * strategy() directly. 560 */ 561 static int 562 parttblread(void *arg, void *buf, size_t blocks, uint64_t offset) 563 { 564 struct probe_args *ppa = arg; 565 size_t size = ppa->secsz * blocks; 566 567 lseek(ppa->fd, offset * ppa->secsz, SEEK_SET); 568 if (read(ppa->fd, buf, size) == size) 569 return (0); 570 return (EIO); 571 } 572 573 /* 574 * scan partition entries to find boot partition starting at start_sector. 575 * in case of MBR partition type PART_SOLARIS2, read VTOC and recurse. 576 */ 577 static int 578 probe_partition(void *arg, const char *partname, 579 const struct ptable_entry *part) 580 { 581 struct probe_args pa, *ppa = arg; 582 struct ptable *table; 583 uint64_t *pool_guid_ptr = NULL; 584 uint64_t pool_guid = 0; 585 char devname[32]; 586 int len, ret = 0; 587 588 len = strlen(ppa->devname); 589 if (len > sizeof (devname)) 590 len = sizeof (devname); 591 592 strncpy(devname, ppa->devname, len - 1); 593 devname[len - 1] = '\0'; 594 snprintf(devname, sizeof (devname), "%s%s:", devname, partname); 595 596 /* filter out partitions *not* used by zfs */ 597 switch (part->type) { 598 case PART_RESERVED: /* efi reserverd */ 599 case PART_VTOC_BOOT: /* vtoc boot area */ 600 case PART_VTOC_SWAP: 601 return (ret); 602 default: 603 break; 604 } 605 606 if (part->type == PART_SOLARIS2) { 607 pa.offset = part->start; 608 pa.fd = open(devname, O_RDONLY); 609 if (pa.fd == -1) 610 return (ret); 611 pa.devname = devname; 612 pa.secsz = ppa->secsz; 613 table = ptable_open(&pa, part->end - part->start + 1, 614 ppa->secsz, parttblread); 615 if (table != NULL) { 616 ret = ptable_iterate(table, &pa, probe_partition); 617 ptable_close(table); 618 } 619 close(pa.fd); 620 return (ret); 621 } 622 623 if (ppa->offset + part->start == start_sector) { 624 /* Ask zfs_probe_dev to provide guid. */ 625 pool_guid_ptr = &pool_guid; 626 /* Set up boot device name for non-zfs case. */ 627 strncpy(boot_devname, devname, sizeof (boot_devname)); 628 } 629 630 ret = zfs_probe_dev(devname, pool_guid_ptr); 631 if (pool_guid != 0 && bdev == NULL) { 632 bdev = malloc(sizeof (struct i386_devdesc)); 633 bzero(bdev, sizeof (struct i386_devdesc)); 634 bdev->d_type = DEVT_ZFS; 635 bdev->d_dev = &zfs_dev; 636 bdev->d_kind.zfs.pool_guid = pool_guid; 637 638 /* 639 * We can not set up zfs boot device name yet, as the 640 * zfs dv_init() is not completed. We will set boot_devname 641 * in main, after devsw setup. 642 */ 643 } 644 645 return (0); 646 } 647 648 /* 649 * open partition table on disk and scan partition entries to find 650 * boot partition starting at start_sector (recorded by installboot). 651 */ 652 static int 653 probe_disk(char *devname) 654 { 655 struct ptable *table; 656 struct probe_args pa; 657 uint64_t mediasz; 658 int ret; 659 660 pa.offset = 0; 661 pa.devname = devname; 662 pa.fd = open(devname, O_RDONLY); 663 if (pa.fd == -1) { 664 return (ENXIO); 665 } 666 667 ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz); 668 if (ret == 0) 669 ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz); 670 if (ret == 0) { 671 table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz, 672 parttblread); 673 if (table != NULL) { 674 ret = ptable_iterate(table, &pa, probe_partition); 675 ptable_close(table); 676 } 677 } 678 close(pa.fd); 679 return (ret); 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, and start_sector LBA recorded by installboot. 687 * 688 * To detect boot pool, we can not use generic zfs_probe_dev() on boot disk, 689 * but we need to walk partitions, as we have no way to pass start_sector 690 * to zfs_probe_dev(). Note we do need to detect the partition correcponding 691 * to non-zfs case, so here we can set boot_devname for both cases. 692 */ 693 static void 694 i386_zfs_probe(void) 695 { 696 char devname[32]; 697 int boot_unit, unit; 698 699 /* Translate bios dev to our unit number. */ 700 boot_unit = bd_bios2unit(bootinfo.bi_bios_dev); 701 702 /* 703 * Open all the disks we can find and see if we can reconstruct 704 * ZFS pools from them. 705 */ 706 for (unit = 0; unit < MAXBDDEV; unit++) { 707 if (bd_unit2bios(unit) == -1) 708 break; 709 710 sprintf(devname, "disk%d:", unit); 711 /* If this is not boot disk, use generic probe. */ 712 if (unit != boot_unit) 713 zfs_probe_dev(devname, NULL); 714 else 715 probe_disk(devname); 716 } 717 } 718 719 uint64_t 720 ldi_get_size(void *priv) 721 { 722 int fd = (uintptr_t) priv; 723 uint64_t size; 724 725 ioctl(fd, DIOCGMEDIASIZE, &size); 726 return (size); 727 } 728