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
ptov(uintptr_t x)159 ptov(uintptr_t x)
160 {
161 return (PTOV(x));
162 }
163
164 int main(void);
165
166 int
main(void)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 for (i = 0; devsw[i] != NULL; i++)
215 if (devsw[i]->dv_init != NULL)
216 (devsw[i]->dv_init)();
217
218 disk_parsedev(&devdesc, boot_devname + 4, NULL);
219
220 bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc.d_slice + 1,
221 devdesc.dd.d_unit,
222 devdesc.d_partition >= 0 ? devdesc.d_partition : 0xff);
223
224 /*
225 * zfs_fmtdev() 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, zfs_fmtdev(bdev), 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
exit(int x)335 exit(int x)
336 {
337 __exit(x);
338 }
339
340 static void
load(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->d_kind.zfs.pool_guid;
471 zfsargs.root = bdev->d_kind.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->d_kind.zfs.pool_guid,
485 (uint32_t)(bdev->d_kind.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
mount_root(char * arg)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->d_kind.biosdisk.partition == -1)
532 part = 0xff;
533 else
534 part = bdev->d_kind.biosdisk.partition;
535 bootdev = MAKEBOOTDEV(dev_maj[bdev->dd.d_dev->dv_type],
536 bdev->d_kind.biosdisk.slice + 1,
537 bdev->dd.d_unit, part);
538 bootinfo.bi_bios_dev = bd_unit2bios(bdev);
539 }
540 strncpy(boot_devname, root, sizeof (boot_devname));
541 setenv("currdev", root, 1);
542 free(root);
543 return (0);
544 }
545
546 static void
fs_list(char * arg)547 fs_list(char *arg)
548 {
549 int fd;
550 struct dirent *d;
551 char line[80];
552
553 fd = open(arg, O_RDONLY);
554 if (fd < 0)
555 return;
556 pager_open();
557 while ((d = readdirfd(fd)) != NULL) {
558 sprintf(line, "%s\n", d->d_name);
559 if (pager_output(line))
560 break;
561 }
562 pager_close();
563 close(fd);
564 }
565
566 static int
parse_cmd(void)567 parse_cmd(void)
568 {
569 char *arg = cmd;
570 char *ep, *p, *q;
571 const char *cp;
572 char line[80];
573 int c, i, j;
574
575 while ((c = *arg++)) {
576 if (c == ' ' || c == '\t' || c == '\n')
577 continue;
578 for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++)
579 ;
580 ep = p;
581 if (*p)
582 *p++ = 0;
583 if (c == '-') {
584 while ((c = *arg++)) {
585 if (c == 'P') {
586 if (*(uint8_t *)PTOV(0x496) & 0x10) {
587 cp = "yes";
588 } else {
589 opts |= OPT_SET(RBX_DUAL);
590 opts |= OPT_SET(RBX_SERIAL);
591 cp = "no";
592 }
593 printf("Keyboard: %s\n", cp);
594 continue;
595 } else if (c == 'S') {
596 j = 0;
597 while ((unsigned int)
598 (i = *arg++ - '0') <= 9)
599 j = j * 10 + i;
600 if (j > 0 && i == -'0') {
601 comspeed = j;
602 break;
603 }
604 /*
605 * Fall through to error below
606 * ('S' not in optstr[]).
607 */
608 }
609 for (i = 0; c != optstr[i]; i++)
610 if (i == NOPT - 1)
611 return (-1);
612 opts ^= OPT_SET(flags[i]);
613 }
614 ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
615 OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
616 if (ioctrl & IO_SERIAL) {
617 if (sio_init(115200 / comspeed) != 0)
618 ioctrl &= ~IO_SERIAL;
619 }
620 } if (c == '?') {
621 printf("\n");
622 if (*arg == '\0')
623 arg = (char *)"/";
624 fs_list(arg);
625 zfs_list(arg);
626 return (-1);
627 } else {
628 char *ptr;
629 printf("\n");
630 arg--;
631
632 /*
633 * Report pool status if the comment is 'status'. Lets
634 * hope no-one wants to load /status as a kernel.
635 */
636 if (strcmp(arg, "status") == 0) {
637 pager_open();
638 for (i = 0; devsw[i] != NULL; i++) {
639 if (devsw[i]->dv_print != NULL) {
640 if (devsw[i]->dv_print(1))
641 break;
642 } else {
643 snprintf(line, sizeof(line),
644 "%s: (unknown)\n",
645 devsw[i]->dv_name);
646 if (pager_output(line))
647 break;
648 }
649 }
650 pager_close();
651 return (-1);
652 }
653
654 /*
655 * If there is "zfs:" prefix simply ignore it.
656 */
657 ptr = arg;
658 if (strncmp(ptr, "zfs:", 4) == 0)
659 ptr += 4;
660
661 /*
662 * If there is a colon, switch pools.
663 */
664 q = strchr(ptr, ':');
665 if (q) {
666 *q++ = '\0';
667 if (mount_root(arg) != 0) {
668 return (-1);
669 }
670 arg = q;
671 }
672 if ((i = ep - arg)) {
673 if ((size_t)i >= sizeof(kname))
674 return (-1);
675 memcpy(kname, arg, i + 1);
676 }
677 }
678 arg = p;
679 }
680 return (0);
681 }
682
683 /*
684 * Probe all disks to discover ZFS pools. The idea is to walk all possible
685 * disk devices, however, we also need to identify possible boot pool.
686 * For boot pool detection we have boot disk passed us from BIOS, recorded
687 * in bootinfo.bi_bios_dev.
688 */
689 static void
i386_zfs_probe(void)690 i386_zfs_probe(void)
691 {
692 char devname[32];
693 int boot_unit;
694 struct i386_devdesc dev;
695 uint64_t pool_guid = 0;
696
697 dev.dd.d_dev = &bioshd;
698 /* Translate bios dev to our unit number. */
699 boot_unit = bd_bios2unit(bootinfo.bi_bios_dev);
700
701 /*
702 * Open all the disks we can find and see if we can reconstruct
703 * ZFS pools from them.
704 */
705 for (dev.dd.d_unit = 0; bd_unit2bios(&dev) >= 0; dev.dd.d_unit++) {
706 snprintf(devname, sizeof (devname), "%s%d:", bioshd.dv_name,
707 dev.dd.d_unit);
708 /* If this is not boot disk, use generic probe. */
709 if (dev.dd.d_unit != boot_unit)
710 zfs_probe_dev(devname, NULL);
711 else
712 zfs_probe_dev(devname, &pool_guid);
713
714 if (pool_guid != 0 && bdev == NULL) {
715 bdev = malloc(sizeof (struct i386_devdesc));
716 bzero(bdev, sizeof (struct i386_devdesc));
717 bdev->dd.d_dev = &zfs_dev;
718 bdev->d_kind.zfs.pool_guid = pool_guid;
719 }
720 }
721 }
722