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
ptov(uintptr_t x)156 ptov(uintptr_t x)
157 {
158 return (PTOV(x));
159 }
160
161 int main(void);
162
163 int
main(void)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
exit(int x)332 exit(int x)
333 {
334 __exit(x);
335 }
336
337 static void
load(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
mount_root(char * arg)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
fs_list(char * arg)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
parse_cmd(void)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
i386_zfs_probe(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