Deleted Added
full compact
zfsboot.c (185029) zfsboot.c (185096)
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>
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: head/sys/boot/i386/zfsboot/zfsboot.c 185029 2008-11-17 20:49:29Z pjd $");
17__FBSDID("$FreeBSD: head/sys/boot/i386/zfsboot/zfsboot.c 185096 2008-11-19 16:39:01Z dfr $");
18
19#include <sys/param.h>
20#include <sys/errno.h>
21#include <sys/diskmbr.h>
18
19#include <sys/param.h>
20#include <sys/errno.h>
21#include <sys/diskmbr.h>
22#ifdef GPT
23#include <sys/gpt.h>
24#endif
22#include <sys/reboot.h>
23#include <sys/queue.h>
24
25#include <machine/bootinfo.h>
26#include <machine/elf.h>
27
28#include <stdarg.h>
29#include <stddef.h>
30
31#include <a.out.h>
32
33#include <btxv86.h>
34
25#include <sys/reboot.h>
26#include <sys/queue.h>
27
28#include <machine/bootinfo.h>
29#include <machine/elf.h>
30
31#include <stdarg.h>
32#include <stddef.h>
33
34#include <a.out.h>
35
36#include <btxv86.h>
37
38#ifndef GPT
35#include "zfsboot.h"
39#include "zfsboot.h"
40#endif
36#include "lib.h"
37
38#define IO_KEYBOARD 1
39#define IO_SERIAL 2
40
41#define SECOND 18 /* Circa that many ticks in a second. */
42
43#define RBX_ASKNAME 0x0 /* -a */

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

98#define TYPE_MAXHARD TYPE_DA
99#define TYPE_FD 2
100
101#define OPT_SET(opt) (1 << (opt))
102#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
103
104extern uint32_t _end;
105
41#include "lib.h"
42
43#define IO_KEYBOARD 1
44#define IO_SERIAL 2
45
46#define SECOND 18 /* Circa that many ticks in a second. */
47
48#define RBX_ASKNAME 0x0 /* -a */

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

103#define TYPE_MAXHARD TYPE_DA
104#define TYPE_FD 2
105
106#define OPT_SET(opt) (1 << (opt))
107#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
108
109extern uint32_t _end;
110
111#ifdef GPT
112static const uuid_t freebsd_zfs_uuid = GPT_ENT_TYPE_FREEBSD_ZFS;
113#endif
106static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
107static const unsigned char flags[NOPT] = {
108 RBX_DUAL,
109 RBX_SERIAL,
110 RBX_ASKNAME,
111 RBX_CDROM,
112 RBX_CONFIG,
113 RBX_KDB,

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

403 return (1);
404 }
405 return(0);
406}
407
408static void
409probe_drive(struct dsk *dsk, spa_t **spap)
410{
114static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
115static const unsigned char flags[NOPT] = {
116 RBX_DUAL,
117 RBX_SERIAL,
118 RBX_ASKNAME,
119 RBX_CDROM,
120 RBX_CONFIG,
121 RBX_KDB,

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

411 return (1);
412 }
413 return(0);
414}
415
416static void
417probe_drive(struct dsk *dsk, spa_t **spap)
418{
419#ifdef GPT
420 struct gpt_hdr hdr;
421 struct gpt_ent *ent;
422 daddr_t slba, elba;
423 unsigned part, entries_per_sec;
424#endif
411 struct dos_partition *dp;
412 char *sec;
413 unsigned i;
414
415 if (!int13probe(dsk->drive))
416 return;
417
418 /*
419 * If we find a vdev on the whole disk, stop here. Otherwise dig
420 * out the MBR and probe each slice in turn for a vdev.
421 */
422 if (vdev_probe(vdev_read, dsk, spap) == 0)
423 return;
424
425 sec = dmadat->secbuf;
426 dsk->start = 0;
425 struct dos_partition *dp;
426 char *sec;
427 unsigned i;
428
429 if (!int13probe(dsk->drive))
430 return;
431
432 /*
433 * If we find a vdev on the whole disk, stop here. Otherwise dig
434 * out the MBR and probe each slice in turn for a vdev.
435 */
436 if (vdev_probe(vdev_read, dsk, spap) == 0)
437 return;
438
439 sec = dmadat->secbuf;
440 dsk->start = 0;
441
442#ifdef GPT
443 /*
444 * First check for GPT.
445 */
446 if (drvread(dsk, sec, 1, 1)) {
447 return;
448 }
449 memcpy(&hdr, sec, sizeof(hdr));
450 if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 ||
451 hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 ||
452 hdr.hdr_entsz < sizeof(*ent) || DEV_BSIZE % hdr.hdr_entsz != 0) {
453 goto trymbr;
454 }
455
456 /*
457 * Probe all GPT partitions for the presense of ZFS pools. We
458 * return the spa_t for the first we find (if requested). This
459 * will have the effect of booting from the first pool on the
460 * disk.
461 */
462 entries_per_sec = DEV_BSIZE / hdr.hdr_entsz;
463 slba = hdr.hdr_lba_table;
464 elba = slba + hdr.hdr_entries / entries_per_sec;
465 while (slba < elba) {
466 if (drvread(dsk, sec, slba, 1))
467 return;
468 for (part = 0; part < entries_per_sec; part++) {
469 ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz);
470 if (memcmp(&ent->ent_type, &freebsd_zfs_uuid,
471 sizeof(uuid_t)) == 0) {
472 dsk->start = ent->ent_lba_start;
473 if (vdev_probe(vdev_read, dsk, spap) == 0) {
474 /*
475 * We record the first pool we find (we will try
476 * to boot from that one.
477 */
478 spap = 0;
479
480 /*
481 * This slice had a vdev. We need a new dsk
482 * structure now since the vdev now owns this one.
483 */
484 struct dsk *newdsk;
485 newdsk = malloc(sizeof(struct dsk));
486 *newdsk = *dsk;
487 dsk = newdsk;
488 }
489 break;
490 }
491 }
492 slba++;
493 }
494 return;
495trymbr:
496#endif
497
427 if (drvread(dsk, sec, DOSBBSECTOR, 1))
428 return;
429 dp = (void *)(sec + DOSPARTOFF);
430
431 for (i = 0; i < NDOSPART; i++) {
432 if (!dp[i].dp_typ)
433 continue;
434 dsk->start = dp[i].dp_start;
435 if (vdev_probe(vdev_read, dsk, spap) == 0) {
436 /*
437 * We record the first pool we find (we will try to boot
438 * from that one.
439 */
440 spap = 0;
441
442 /*
443 * This slice had a vdev. We need a new dsk structure now
498 if (drvread(dsk, sec, DOSBBSECTOR, 1))
499 return;
500 dp = (void *)(sec + DOSPARTOFF);
501
502 for (i = 0; i < NDOSPART; i++) {
503 if (!dp[i].dp_typ)
504 continue;
505 dsk->start = dp[i].dp_start;
506 if (vdev_probe(vdev_read, dsk, spap) == 0) {
507 /*
508 * We record the first pool we find (we will try to boot
509 * from that one.
510 */
511 spap = 0;
512
513 /*
514 * This slice had a vdev. We need a new dsk structure now
444 * sice the vdev now owns this one.
515 * since the vdev now owns this one.
445 */
446 struct dsk *newdsk;
447 newdsk = malloc(sizeof(struct dsk));
448 *newdsk = *dsk;
449 dsk = newdsk;
450 }
451 }
452}

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

854static void
855putchar(int c)
856{
857 if (c == '\n')
858 xputc('\r');
859 xputc(c);
860}
861
516 */
517 struct dsk *newdsk;
518 newdsk = malloc(sizeof(struct dsk));
519 *newdsk = *dsk;
520 dsk = newdsk;
521 }
522 }
523}

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

925static void
926putchar(int c)
927{
928 if (c == '\n')
929 xputc('\r');
930 xputc(c);
931}
932
933#ifdef GPT
934static struct {
935 uint16_t len;
936 uint16_t count;
937 uint16_t seg;
938 uint16_t off;
939 uint64_t lba;
940} packet;
941#endif
942
862static int
863drvread(struct dsk *dsk, void *buf, unsigned lba, unsigned nblk)
864{
943static int
944drvread(struct dsk *dsk, void *buf, unsigned lba, unsigned nblk)
945{
946#ifdef GPT
947 static unsigned c = 0x2d5c7c2f;
948
949 if (!OPT_CHECK(RBX_QUIET))
950 printf("%c\b", c = c << 8 | c >> 24);
951 packet.len = 0x10;
952 packet.count = nblk;
953 packet.seg = VTOPOFF(buf);
954 packet.off = VTOPSEG(buf);
955 packet.lba = lba + dsk->start;
956 v86.ctl = V86_FLAGS;
957 v86.addr = 0x13;
958 v86.eax = 0x4200;
959 v86.edx = dsk->drive;
960 v86.ds = VTOPSEG(&packet);
961 v86.esi = VTOPOFF(&packet);
962 v86int();
963 if (V86_CY(v86.efl)) {
964 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
965 return -1;
966 }
967 return 0;
968#else
865 static unsigned c = 0x2d5c7c2f;
866
867 lba += dsk->start;
868 if (!OPT_CHECK(RBX_QUIET))
869 printf("%c\b", c = c << 8 | c >> 24);
870 v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
871 v86.addr = XREADORG; /* call to xread in boot1 */
872 v86.es = VTOPSEG(buf);
873 v86.eax = lba;
874 v86.ebx = VTOPOFF(buf);
875 v86.ecx = lba >> 16;
876 v86.edx = nblk << 8 | dsk->drive;
877 v86int();
878 v86.ctl = V86_FLAGS;
879 if (V86_CY(v86.efl)) {
880 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
881 return -1;
882 }
883 return 0;
969 static unsigned c = 0x2d5c7c2f;
970
971 lba += dsk->start;
972 if (!OPT_CHECK(RBX_QUIET))
973 printf("%c\b", c = c << 8 | c >> 24);
974 v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
975 v86.addr = XREADORG; /* call to xread in boot1 */
976 v86.es = VTOPSEG(buf);
977 v86.eax = lba;
978 v86.ebx = VTOPOFF(buf);
979 v86.ecx = lba >> 16;
980 v86.edx = nblk << 8 | dsk->drive;
981 v86int();
982 v86.ctl = V86_FLAGS;
983 if (V86_CY(v86.efl)) {
984 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
985 return -1;
986 }
987 return 0;
988#endif
884}
885
886static int
887keyhit(unsigned ticks)
888{
889 uint32_t t0, t1;
890
891 if (OPT_CHECK(RBX_NOINTR))

--- 53 unchanged lines hidden ---
989}
990
991static int
992keyhit(unsigned ticks)
993{
994 uint32_t t0, t1;
995
996 if (OPT_CHECK(RBX_NOINTR))

--- 53 unchanged lines hidden ---