zfsboot.c (ec82884e87b9ad05278081e33749133247063f59) zfsboot.c (c1418270b28edf9b99044181e9f48dfc0a7dc160)
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.

--- 113 unchanged lines hidden (view full) ---

122void exit(int);
123void reboot(void);
124static void load(void);
125static int parse_cmd(void);
126static void bios_getmem(void);
127int main(void);
128
129#ifdef LOADER_GELI_SUPPORT
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.

--- 113 unchanged lines hidden (view full) ---

122void exit(int);
123void reboot(void);
124static void load(void);
125static int parse_cmd(void);
126static void bios_getmem(void);
127int main(void);
128
129#ifdef LOADER_GELI_SUPPORT
130#include "geliboot.c"
130#include "geliboot.h"
131static char gelipw[GELI_PW_MAXLEN];
132static struct keybuf *gelibuf;
133#endif
134
131static char gelipw[GELI_PW_MAXLEN];
132static struct keybuf *gelibuf;
133#endif
134
135struct zfsdsk {
136 struct dsk dsk;
137#ifdef LOADER_GELI_SUPPORT
138 struct geli_dev *gdev;
139#endif
140};
141
135#include "zfsimpl.c"
136
137/*
138 * Read from a dnode (which must be from a ZPL filesystem).
139 */
140static int
141zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t size)
142{

--- 26 unchanged lines hidden (view full) ---

169 */
170static int
171vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes)
172{
173 char *p;
174 daddr_t lba, alignlba;
175 off_t diff;
176 unsigned int nb, alignnb;
142#include "zfsimpl.c"
143
144/*
145 * Read from a dnode (which must be from a ZPL filesystem).
146 */
147static int
148zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t size)
149{

--- 26 unchanged lines hidden (view full) ---

176 */
177static int
178vdev_read(void *xvdev, void *priv, off_t off, void *buf, size_t bytes)
179{
180 char *p;
181 daddr_t lba, alignlba;
182 off_t diff;
183 unsigned int nb, alignnb;
177 struct dsk *dsk = (struct dsk *) priv;
184 struct zfsdsk *zdsk = (struct zfsdsk *) priv;
178
179 if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
180 return -1;
181
182 p = buf;
183 lba = off / DEV_BSIZE;
185
186 if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
187 return -1;
188
189 p = buf;
190 lba = off / DEV_BSIZE;
184 lba += dsk->start;
191 lba += zdsk->dsk.start;
185 /*
186 * Align reads to 4k else 4k sector GELIs will not decrypt.
187 * Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes.
188 */
189 alignlba = rounddown2(off, DEV_GELIBOOT_BSIZE) / DEV_BSIZE;
190 /*
191 * The read must be aligned to DEV_GELIBOOT_BSIZE bytes relative to the
192 * start of the GELI partition, not the start of the actual disk.
193 */
192 /*
193 * Align reads to 4k else 4k sector GELIs will not decrypt.
194 * Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes.
195 */
196 alignlba = rounddown2(off, DEV_GELIBOOT_BSIZE) / DEV_BSIZE;
197 /*
198 * The read must be aligned to DEV_GELIBOOT_BSIZE bytes relative to the
199 * start of the GELI partition, not the start of the actual disk.
200 */
194 alignlba += dsk->start;
201 alignlba += zdsk->dsk.start;
195 diff = (lba - alignlba) * DEV_BSIZE;
196
197 while (bytes > 0) {
198 nb = bytes / DEV_BSIZE;
199 /*
200 * Ensure that the read size plus the leading offset does not
201 * exceed the size of the read buffer.
202 */
203 if (nb > (READ_BUF_SIZE - diff) / DEV_BSIZE)
204 nb = (READ_BUF_SIZE - diff) / DEV_BSIZE;
205 /*
206 * Round the number of blocks to read up to the nearest multiple
207 * of DEV_GELIBOOT_BSIZE.
208 */
209 alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE)
210 / DEV_BSIZE;
211
202 diff = (lba - alignlba) * DEV_BSIZE;
203
204 while (bytes > 0) {
205 nb = bytes / DEV_BSIZE;
206 /*
207 * Ensure that the read size plus the leading offset does not
208 * exceed the size of the read buffer.
209 */
210 if (nb > (READ_BUF_SIZE - diff) / DEV_BSIZE)
211 nb = (READ_BUF_SIZE - diff) / DEV_BSIZE;
212 /*
213 * Round the number of blocks to read up to the nearest multiple
214 * of DEV_GELIBOOT_BSIZE.
215 */
216 alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE)
217 / DEV_BSIZE;
218
212 if (dsk->size > 0 && alignlba + alignnb > dsk->size + dsk->start) {
213 printf("Shortening read at %lld from %d to %lld\n", alignlba,
214 alignnb, (dsk->size + dsk->start) - alignlba);
215 alignnb = (dsk->size + dsk->start) - alignlba;
219 if (zdsk->dsk.size > 0 && alignlba + alignnb >
220 zdsk->dsk.size + zdsk->dsk.start) {
221 printf("Shortening read at %lld from %d to %lld\n",
222 alignlba, alignnb,
223 (zdsk->dsk.size + zdsk->dsk.start) - alignlba);
224 alignnb = (zdsk->dsk.size + zdsk->dsk.start) - alignlba;
216 }
217
225 }
226
218 if (drvread(dsk, dmadat->rdbuf, alignlba, alignnb))
227 if (drvread(&zdsk->dsk, dmadat->rdbuf, alignlba, alignnb))
219 return -1;
220#ifdef LOADER_GELI_SUPPORT
221 /* decrypt */
228 return -1;
229#ifdef LOADER_GELI_SUPPORT
230 /* decrypt */
222 if (is_geli(dsk) == 0) {
223 if (geli_read(dsk, ((alignlba - dsk->start) *
231 if (zdsk->gdev != NULL) {
232 if (geli_read(zdsk->gdev, ((alignlba - zdsk->dsk.start) *
224 DEV_BSIZE), dmadat->rdbuf, alignnb * DEV_BSIZE))
225 return (-1);
226 }
227#endif
228 memcpy(p, dmadat->rdbuf + diff, nb * DEV_BSIZE);
229 p += nb * DEV_BSIZE;
230 lba += nb;
231 alignlba += alignnb;

--- 13 unchanged lines hidden (view full) ---

245
246
247static int
248vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
249{
250 char *p;
251 daddr_t lba;
252 unsigned int nb;
233 DEV_BSIZE), dmadat->rdbuf, alignnb * DEV_BSIZE))
234 return (-1);
235 }
236#endif
237 memcpy(p, dmadat->rdbuf + diff, nb * DEV_BSIZE);
238 p += nb * DEV_BSIZE;
239 lba += nb;
240 alignlba += alignnb;

--- 13 unchanged lines hidden (view full) ---

254
255
256static int
257vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
258{
259 char *p;
260 daddr_t lba;
261 unsigned int nb;
253 struct dsk *dsk = (struct dsk *) priv;
262 struct zfsdsk *zdsk = (struct zfsdsk *) priv;
254
255 if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
256 return -1;
257
258 p = buf;
259 lba = off / DEV_BSIZE;
263
264 if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
265 return -1;
266
267 p = buf;
268 lba = off / DEV_BSIZE;
260 lba += dsk->start;
269 lba += zdsk->dsk.start;
261 while (bytes > 0) {
262 nb = bytes / DEV_BSIZE;
263 if (nb > READ_BUF_SIZE / DEV_BSIZE)
264 nb = READ_BUF_SIZE / DEV_BSIZE;
265 memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE);
270 while (bytes > 0) {
271 nb = bytes / DEV_BSIZE;
272 if (nb > READ_BUF_SIZE / DEV_BSIZE)
273 nb = READ_BUF_SIZE / DEV_BSIZE;
274 memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE);
266 if (drvwrite(dsk, dmadat->rdbuf, lba, nb))
275 if (drvwrite(&zdsk->dsk, dmadat->rdbuf, lba, nb))
267 return -1;
268 p += nb * DEV_BSIZE;
269 lba += nb;
270 bytes -= nb * DEV_BSIZE;
271 }
272
273 return 0;
274}

--- 161 unchanged lines hidden (view full) ---

436 }
437 return(0);
438}
439
440/*
441 * We call this when we find a ZFS vdev - ZFS consumes the dsk
442 * structure so we must make a new one.
443 */
276 return -1;
277 p += nb * DEV_BSIZE;
278 lba += nb;
279 bytes -= nb * DEV_BSIZE;
280 }
281
282 return 0;
283}

--- 161 unchanged lines hidden (view full) ---

445 }
446 return(0);
447}
448
449/*
450 * We call this when we find a ZFS vdev - ZFS consumes the dsk
451 * structure so we must make a new one.
452 */
444static struct dsk *
445copy_dsk(struct dsk *dsk)
453static struct zfsdsk *
454copy_dsk(struct zfsdsk *zdsk)
446{
455{
447 struct dsk *newdsk;
456 struct zfsdsk *newdsk;
448
457
449 newdsk = malloc(sizeof(struct dsk));
450 *newdsk = *dsk;
458 newdsk = malloc(sizeof(struct zfsdsk));
459 *newdsk = *zdsk;
451 return (newdsk);
452}
453
454/*
455 * Get disk size from eax=0x800 and 0x4800. We need to probe both
456 * because 0x4800 may not be available and we would like to get more
457 * or less correct disk size - if it is possible at all.
458 * Note we do not really want to touch drv.c because that code is shared
459 * with boot2 and we can not afford to grow that code.
460 */
461static uint64_t
460 return (newdsk);
461}
462
463/*
464 * Get disk size from eax=0x800 and 0x4800. We need to probe both
465 * because 0x4800 may not be available and we would like to get more
466 * or less correct disk size - if it is possible at all.
467 * Note we do not really want to touch drv.c because that code is shared
468 * with boot2 and we can not afford to grow that code.
469 */
470static uint64_t
462drvsize_ext(struct dsk *dskp)
471drvsize_ext(struct zfsdsk *zdsk)
463{
472{
473 struct dsk *dskp;
464 uint64_t size, tmp;
465 int cyl, hds, sec;
466
474 uint64_t size, tmp;
475 int cyl, hds, sec;
476
477 dskp = &zdsk->dsk;
478
467 v86.ctl = V86_FLAGS;
468 v86.addr = 0x13;
469 v86.eax = 0x800;
470 v86.edx = dskp->drive;
471 v86int();
472
473 /* Don't error out if we get bad sector number, try EDD as well */
474 if (V86_CY(v86.efl) || /* carry set */

--- 28 unchanged lines hidden (view full) ---

503/*
504 * The "layered" ioctl to read disk/partition size. Unfortunately
505 * the zfsboot case is hardest, because we do not have full software
506 * stack available, so we need to do some manual work here.
507 */
508uint64_t
509ldi_get_size(void *priv)
510{
479 v86.ctl = V86_FLAGS;
480 v86.addr = 0x13;
481 v86.eax = 0x800;
482 v86.edx = dskp->drive;
483 v86int();
484
485 /* Don't error out if we get bad sector number, try EDD as well */
486 if (V86_CY(v86.efl) || /* carry set */

--- 28 unchanged lines hidden (view full) ---

515/*
516 * The "layered" ioctl to read disk/partition size. Unfortunately
517 * the zfsboot case is hardest, because we do not have full software
518 * stack available, so we need to do some manual work here.
519 */
520uint64_t
521ldi_get_size(void *priv)
522{
511 struct dsk *dskp = priv;
512 uint64_t size = dskp->size;
523 struct zfsdsk *zdsk = priv;
524 uint64_t size = zdsk->dsk.size;
513
525
514 if (dskp->start == 0)
515 size = drvsize_ext(dskp);
526 if (zdsk->dsk.start == 0)
527 size = drvsize_ext(zdsk);
516
517 return (size * DEV_BSIZE);
518}
519
520static void
528
529 return (size * DEV_BSIZE);
530}
531
532static void
521probe_drive(struct dsk *dsk)
533probe_drive(struct zfsdsk *zdsk)
522{
523#ifdef GPT
524 struct gpt_hdr hdr;
525 struct gpt_ent *ent;
526 unsigned part, entries_per_sec;
527 daddr_t slba;
528#endif
529#if defined(GPT) || defined(LOADER_GELI_SUPPORT)
530 daddr_t elba;
531#endif
532
533 struct dos_partition *dp;
534 char *sec;
535 unsigned i;
536
537 /*
538 * If we find a vdev on the whole disk, stop here.
539 */
534{
535#ifdef GPT
536 struct gpt_hdr hdr;
537 struct gpt_ent *ent;
538 unsigned part, entries_per_sec;
539 daddr_t slba;
540#endif
541#if defined(GPT) || defined(LOADER_GELI_SUPPORT)
542 daddr_t elba;
543#endif
544
545 struct dos_partition *dp;
546 char *sec;
547 unsigned i;
548
549 /*
550 * If we find a vdev on the whole disk, stop here.
551 */
540 if (vdev_probe(vdev_read2, dsk, NULL) == 0)
552 if (vdev_probe(vdev_read2, zdsk, NULL) == 0)
541 return;
542
543#ifdef LOADER_GELI_SUPPORT
544 /*
545 * Taste the disk, if it is GELI encrypted, decrypt it and check to see if
546 * it is a usable vdev then. Otherwise dig
547 * out the partition table and probe each slice/partition
548 * in turn for a vdev or GELI encrypted vdev.
549 */
553 return;
554
555#ifdef LOADER_GELI_SUPPORT
556 /*
557 * Taste the disk, if it is GELI encrypted, decrypt it and check to see if
558 * it is a usable vdev then. Otherwise dig
559 * out the partition table and probe each slice/partition
560 * in turn for a vdev or GELI encrypted vdev.
561 */
550 elba = drvsize_ext(dsk);
562 elba = drvsize_ext(zdsk);
551 if (elba > 0) {
552 elba--;
553 }
563 if (elba > 0) {
564 elba--;
565 }
554 if (geli_taste(vdev_read, dsk, elba) == 0) {
555 if (geli_havekey(dsk) == 0 || geli_passphrase(gelipw, dsk->unit,
556 ':', 0, dsk) == 0) {
557 if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
566 zdsk->gdev = geli_taste(vdev_read, zdsk, elba, "disk%u:0:");
567 if (zdsk->gdev != NULL) {
568 if (geli_havekey(zdsk->gdev) == 0 ||
569 geli_passphrase(zdsk->gdev, gelipw) == 0) {
570 if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
558 return;
559 }
560 }
561 }
562#endif /* LOADER_GELI_SUPPORT */
563
564 sec = dmadat->secbuf;
571 return;
572 }
573 }
574 }
575#endif /* LOADER_GELI_SUPPORT */
576
577 sec = dmadat->secbuf;
565 dsk->start = 0;
578 zdsk->dsk.start = 0;
566
567#ifdef GPT
568 /*
569 * First check for GPT.
570 */
579
580#ifdef GPT
581 /*
582 * First check for GPT.
583 */
571 if (drvread(dsk, sec, 1, 1)) {
584 if (drvread(&zdsk->dsk, sec, 1, 1)) {
572 return;
573 }
574 memcpy(&hdr, sec, sizeof(hdr));
575 if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 ||
576 hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 ||
577 hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) {
578 goto trymbr;
579 }

--- 5 unchanged lines hidden (view full) ---

585 * disk.
586 *
587 * If no vdev is found, GELI decrypting the device and try again
588 */
589 entries_per_sec = DEV_BSIZE / hdr.hdr_entsz;
590 slba = hdr.hdr_lba_table;
591 elba = slba + hdr.hdr_entries / entries_per_sec;
592 while (slba < elba) {
585 return;
586 }
587 memcpy(&hdr, sec, sizeof(hdr));
588 if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 ||
589 hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 ||
590 hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) {
591 goto trymbr;
592 }

--- 5 unchanged lines hidden (view full) ---

598 * disk.
599 *
600 * If no vdev is found, GELI decrypting the device and try again
601 */
602 entries_per_sec = DEV_BSIZE / hdr.hdr_entsz;
603 slba = hdr.hdr_lba_table;
604 elba = slba + hdr.hdr_entries / entries_per_sec;
605 while (slba < elba) {
593 dsk->start = 0;
594 if (drvread(dsk, sec, slba, 1))
606 zdsk->dsk.start = 0;
607 if (drvread(&zdsk->dsk, sec, slba, 1))
595 return;
596 for (part = 0; part < entries_per_sec; part++) {
597 ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz);
598 if (memcmp(&ent->ent_type, &freebsd_zfs_uuid,
599 sizeof(uuid_t)) == 0) {
608 return;
609 for (part = 0; part < entries_per_sec; part++) {
610 ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz);
611 if (memcmp(&ent->ent_type, &freebsd_zfs_uuid,
612 sizeof(uuid_t)) == 0) {
600 dsk->start = ent->ent_lba_start;
601 dsk->size = ent->ent_lba_end - ent->ent_lba_start + 1;
602 dsk->slice = part + 1;
603 dsk->part = 255;
604 if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
613 zdsk->dsk.start = ent->ent_lba_start;
614 zdsk->dsk.size = ent->ent_lba_end - ent->ent_lba_start + 1;
615 zdsk->dsk.slice = part + 1;
616 zdsk->dsk.part = 255;
617 if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
605 /*
606 * This slice had a vdev. We need a new dsk
607 * structure now since the vdev now owns this one.
608 */
618 /*
619 * This slice had a vdev. We need a new dsk
620 * structure now since the vdev now owns this one.
621 */
609 dsk = copy_dsk(dsk);
622 zdsk = copy_dsk(zdsk);
610 }
611#ifdef LOADER_GELI_SUPPORT
623 }
624#ifdef LOADER_GELI_SUPPORT
612 else if (geli_taste(vdev_read, dsk, ent->ent_lba_end -
613 ent->ent_lba_start) == 0) {
614 if (geli_havekey(dsk) == 0 || geli_passphrase(gelipw,
615 dsk->unit, 'p', dsk->slice, dsk) == 0) {
625 else if ((zdsk->gdev = geli_taste(vdev_read, zdsk,
626 ent->ent_lba_end - ent->ent_lba_start, "disk%up%u:",
627 zdsk->dsk.unit, zdsk->dsk.slice)) != NULL) {
628 if (geli_havekey(zdsk->gdev) == 0 ||
629 geli_passphrase(zdsk->gdev, gelipw) == 0) {
616 /*
617 * This slice has GELI, check it for ZFS.
618 */
630 /*
631 * This slice has GELI, check it for ZFS.
632 */
619 if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
633 if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
620 /*
621 * This slice had a vdev. We need a new dsk
622 * structure now since the vdev now owns this one.
623 */
634 /*
635 * This slice had a vdev. We need a new dsk
636 * structure now since the vdev now owns this one.
637 */
624 dsk = copy_dsk(dsk);
638 zdsk = copy_dsk(zdsk);
625 }
626 break;
627 }
628 }
629#endif /* LOADER_GELI_SUPPORT */
630 }
631 }
632 slba++;
633 }
634 return;
635trymbr:
636#endif /* GPT */
637
639 }
640 break;
641 }
642 }
643#endif /* LOADER_GELI_SUPPORT */
644 }
645 }
646 slba++;
647 }
648 return;
649trymbr:
650#endif /* GPT */
651
638 if (drvread(dsk, sec, DOSBBSECTOR, 1))
652 if (drvread(&zdsk->dsk, sec, DOSBBSECTOR, 1))
639 return;
640 dp = (void *)(sec + DOSPARTOFF);
641
642 for (i = 0; i < NDOSPART; i++) {
643 if (!dp[i].dp_typ)
644 continue;
653 return;
654 dp = (void *)(sec + DOSPARTOFF);
655
656 for (i = 0; i < NDOSPART; i++) {
657 if (!dp[i].dp_typ)
658 continue;
645 dsk->start = dp[i].dp_start;
646 dsk->size = dp[i].dp_size;
647 dsk->slice = i + 1;
648 if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
649 dsk = copy_dsk(dsk);
659 zdsk->dsk.start = dp[i].dp_start;
660 zdsk->dsk.size = dp[i].dp_size;
661 zdsk->dsk.slice = i + 1;
662 if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
663 zdsk = copy_dsk(zdsk);
650 }
651#ifdef LOADER_GELI_SUPPORT
664 }
665#ifdef LOADER_GELI_SUPPORT
652 else if (geli_taste(vdev_read, dsk, dp[i].dp_size -
653 dp[i].dp_start) == 0) {
654 if (geli_havekey(dsk) == 0 || geli_passphrase(gelipw, dsk->unit,
655 's', i, dsk) == 0) {
666 else if ((zdsk->gdev = geli_taste(vdev_read, zdsk, dp[i].dp_size -
667 dp[i].dp_start, "disk%us%u:")) != NULL) {
668 if (geli_havekey(zdsk->gdev) == 0 ||
669 geli_passphrase(zdsk->gdev, gelipw) == 0) {
656 /*
657 * This slice has GELI, check it for ZFS.
658 */
670 /*
671 * This slice has GELI, check it for ZFS.
672 */
659 if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
673 if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
660 /*
661 * This slice had a vdev. We need a new dsk
662 * structure now since the vdev now owns this one.
663 */
674 /*
675 * This slice had a vdev. We need a new dsk
676 * structure now since the vdev now owns this one.
677 */
664 dsk = copy_dsk(dsk);
678 zdsk = copy_dsk(zdsk);
665 }
666 break;
667 }
668 }
669#endif /* LOADER_GELI_SUPPORT */
670 }
671}
672
673int
674main(void)
675{
676 dnode_phys_t dn;
677 off_t off;
679 }
680 break;
681 }
682 }
683#endif /* LOADER_GELI_SUPPORT */
684 }
685}
686
687int
688main(void)
689{
690 dnode_phys_t dn;
691 off_t off;
678 struct dsk *dsk;
692 struct zfsdsk *zdsk;
679 int autoboot, i;
680 int nextboot;
681 int rc;
682
683 dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
684
685 bios_getmem();
686
687 if (high_heap_size > 0) {
688 heap_end = PTOV(high_heap_base + high_heap_size);
689 heap_next = PTOV(high_heap_base);
690 } else {
691 heap_next = (char *)dmadat + sizeof(*dmadat);
692 heap_end = (char *)PTOV(bios_basemem);
693 }
694 setheap(heap_next, heap_end);
695
693 int autoboot, i;
694 int nextboot;
695 int rc;
696
697 dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
698
699 bios_getmem();
700
701 if (high_heap_size > 0) {
702 heap_end = PTOV(high_heap_base + high_heap_size);
703 heap_next = PTOV(high_heap_base);
704 } else {
705 heap_next = (char *)dmadat + sizeof(*dmadat);
706 heap_end = (char *)PTOV(bios_basemem);
707 }
708 setheap(heap_next, heap_end);
709
696 dsk = malloc(sizeof(struct dsk));
697 dsk->drive = *(uint8_t *)PTOV(ARGS);
698 dsk->type = dsk->drive & DRV_HARD ? TYPE_AD : TYPE_FD;
699 dsk->unit = dsk->drive & DRV_MASK;
700 dsk->slice = *(uint8_t *)PTOV(ARGS + 1) + 1;
701 dsk->part = 0;
702 dsk->start = 0;
703 dsk->size = drvsize_ext(dsk);
710 zdsk = malloc(sizeof(struct zfsdsk));
711 zdsk->gdev = NULL;
712 zdsk->dsk.drive = *(uint8_t *)PTOV(ARGS);
713 zdsk->dsk.type = zdsk->dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
714 zdsk->dsk.unit = zdsk->dsk.drive & DRV_MASK;
715 zdsk->dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1;
716 zdsk->dsk.part = 0;
717 zdsk->dsk.start = 0;
718 zdsk->dsk.size = drvsize_ext(zdsk);
704
705 bootinfo.bi_version = BOOTINFO_VERSION;
706 bootinfo.bi_size = sizeof(bootinfo);
707 bootinfo.bi_basemem = bios_basemem / 1024;
708 bootinfo.bi_extmem = bios_extmem / 1024;
709 bootinfo.bi_memsizes_valid++;
719
720 bootinfo.bi_version = BOOTINFO_VERSION;
721 bootinfo.bi_size = sizeof(bootinfo);
722 bootinfo.bi_basemem = bios_basemem / 1024;
723 bootinfo.bi_extmem = bios_extmem / 1024;
724 bootinfo.bi_memsizes_valid++;
710 bootinfo.bi_bios_dev = dsk->drive;
725 bootinfo.bi_bios_dev = zdsk->dsk.drive;
711
726
712 bootdev = MAKEBOOTDEV(dev_maj[dsk->type],
713 dsk->slice, dsk->unit, dsk->part);
727 bootdev = MAKEBOOTDEV(dev_maj[zdsk->dsk.type],
728 zdsk->dsk.slice, zdsk->dsk.unit, zdsk->dsk.part);
714
715 /* Process configuration file */
716
717 autoboot = 1;
718
729
730 /* Process configuration file */
731
732 autoboot = 1;
733
719#ifdef LOADER_GELI_SUPPORT
720 geli_init();
721#endif
722 zfs_init();
723
724 /*
725 * Probe the boot drive first - we will try to boot from whatever
726 * pool we find on that drive.
727 */
734 zfs_init();
735
736 /*
737 * Probe the boot drive first - we will try to boot from whatever
738 * pool we find on that drive.
739 */
728 probe_drive(dsk);
740 probe_drive(zdsk);
729
730 /*
731 * Probe the rest of the drives that the bios knows about. This
732 * will find any other available pools and it may fill in missing
733 * vdevs for the boot pool.
734 */
735#ifndef VIRTUALBOX
736 for (i = 0; i < *(unsigned char *)PTOV(BIOS_NUMDRIVES); i++)
737#else
738 for (i = 0; i < MAXBDDEV; i++)
739#endif
740 {
741 if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS))
742 continue;
743
744 if (!int13probe(i | DRV_HARD))
745 break;
746
741
742 /*
743 * Probe the rest of the drives that the bios knows about. This
744 * will find any other available pools and it may fill in missing
745 * vdevs for the boot pool.
746 */
747#ifndef VIRTUALBOX
748 for (i = 0; i < *(unsigned char *)PTOV(BIOS_NUMDRIVES); i++)
749#else
750 for (i = 0; i < MAXBDDEV; i++)
751#endif
752 {
753 if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS))
754 continue;
755
756 if (!int13probe(i | DRV_HARD))
757 break;
758
747 dsk = malloc(sizeof(struct dsk));
748 dsk->drive = i | DRV_HARD;
749 dsk->type = dsk->drive & TYPE_AD;
750 dsk->unit = i;
751 dsk->slice = 0;
752 dsk->part = 0;
753 dsk->start = 0;
754 dsk->size = drvsize_ext(dsk);
755 probe_drive(dsk);
759 zdsk = malloc(sizeof(struct zfsdsk));
760 zdsk->dsk.drive = i | DRV_HARD;
761 zdsk->dsk.type = zdsk->dsk.drive & TYPE_AD;
762 zdsk->dsk.unit = i;
763 zdsk->dsk.slice = 0;
764 zdsk->dsk.part = 0;
765 zdsk->dsk.start = 0;
766 zdsk->dsk.size = drvsize_ext(zdsk);
767 probe_drive(zdsk);
756 }
757
758 /*
759 * The first discovered pool, if any, is the pool.
760 */
761 spa = spa_get_primary();
762 if (!spa) {
763 printf("%s: No ZFS pools located, can't boot\n", BOOTPROG);

--- 214 unchanged lines hidden (view full) ---

978 bootinfo.bi_kernelname = VTOP(kname);
979 zfsargs.size = sizeof(zfsargs);
980 zfsargs.pool = zfsmount.spa->spa_guid;
981 zfsargs.root = zfsmount.rootobj;
982 zfsargs.primary_pool = primary_spa->spa_guid;
983#ifdef LOADER_GELI_SUPPORT
984 explicit_bzero(gelipw, sizeof(gelipw));
985 gelibuf = malloc(sizeof(struct keybuf) + (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
768 }
769
770 /*
771 * The first discovered pool, if any, is the pool.
772 */
773 spa = spa_get_primary();
774 if (!spa) {
775 printf("%s: No ZFS pools located, can't boot\n", BOOTPROG);

--- 214 unchanged lines hidden (view full) ---

990 bootinfo.bi_kernelname = VTOP(kname);
991 zfsargs.size = sizeof(zfsargs);
992 zfsargs.pool = zfsmount.spa->spa_guid;
993 zfsargs.root = zfsmount.rootobj;
994 zfsargs.primary_pool = primary_spa->spa_guid;
995#ifdef LOADER_GELI_SUPPORT
996 explicit_bzero(gelipw, sizeof(gelipw));
997 gelibuf = malloc(sizeof(struct keybuf) + (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
986 geli_fill_keybuf(gelibuf);
998 geli_export_key_buffer(gelibuf);
987 zfsargs.notapw = '\0';
988 zfsargs.keybuf_sentinel = KEYBUF_SENTINEL;
989 zfsargs.keybuf = gelibuf;
990#else
991 zfsargs.gelipw[0] = '\0';
992#endif
993 if (primary_vdev != NULL)
994 zfsargs.primary_vdev = primary_vdev->v_guid;

--- 138 unchanged lines hidden ---
999 zfsargs.notapw = '\0';
1000 zfsargs.keybuf_sentinel = KEYBUF_SENTINEL;
1001 zfsargs.keybuf = gelibuf;
1002#else
1003 zfsargs.gelipw[0] = '\0';
1004#endif
1005 if (primary_vdev != NULL)
1006 zfsargs.primary_vdev = primary_vdev->v_guid;

--- 138 unchanged lines hidden ---