summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/boot/alpha/common/conf.c3
-rw-r--r--sys/boot/alpha/loader/Makefile2
-rw-r--r--sys/boot/common/ls.c62
-rw-r--r--sys/boot/i386/libi386/biosdisk.c325
-rw-r--r--sys/boot/i386/loader/conf.c1
-rw-r--r--sys/boot/powerpc/loader/conf.c3
-rw-r--r--sys/boot/powerpc/ofw/conf.c3
7 files changed, 236 insertions, 163 deletions
diff --git a/sys/boot/alpha/common/conf.c b/sys/boot/alpha/common/conf.c
index d243399..5f2f519 100644
--- a/sys/boot/alpha/common/conf.c
+++ b/sys/boot/alpha/common/conf.c
@@ -59,6 +59,9 @@ struct fs_ops *file_system[] = {
#ifdef LOADER_CDROM_SUPPORT
&cd9660_fsops,
#endif
+#ifdef LOADER_EXT2FS_SUPPORT
+ &ext2fs_fsops,
+#endif
#ifdef LOADER_NET_SUPPORT
&nfs_fsops,
#endif
diff --git a/sys/boot/alpha/loader/Makefile b/sys/boot/alpha/loader/Makefile
index dbb75dd..470562d 100644
--- a/sys/boot/alpha/loader/Makefile
+++ b/sys/boot/alpha/loader/Makefile
@@ -8,6 +8,6 @@ INSTALL_HELP= yes
LOAD_ADDRESS= ${SECONDARY_LOAD_ADDRESS}
# Only disk support
-CFLAGS+= -DLOADER_DISK_SUPPORT
+CFLAGS+= -DLOADER_DISK_SUPPORT # -DLOADER_EXT2FS_SUPPORT
.include <${.CURDIR}/../common/Makefile.common>
diff --git a/sys/boot/common/ls.c b/sys/boot/common/ls.c
index ef99d70..71aa53b 100644
--- a/sys/boot/common/ls.c
+++ b/sys/boot/common/ls.c
@@ -60,7 +60,7 @@ command_ls(int argc, char *argv[])
int fd;
size_t size;
struct stat sb;
- static char dirbuf[DIRBLKSIZ];
+ struct dirent *d;
char *buf, *path;
char lbuf[128]; /* one line */
int result, ch;
@@ -100,50 +100,24 @@ command_ls(int argc, char *argv[])
pager_output(path);
pager_output("\n");
-
- while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
- struct direct *dp, *edp;
-
- dp = (struct direct *) dirbuf;
- edp = (struct direct *) (dirbuf + size);
-
- while (dp < edp) {
- if (dp->d_ino != (ino_t) 0) {
-
- if ((dp->d_namlen > MAXNAMLEN + 1) || (dp->d_type > sizeof(typestr))) {
- /*
- * This does not handle "old"
- * filesystems properly. On little
- * endian machines, we get a bogus
- * type name if the namlen matches a
- * valid type identifier. We could
- * check if we read namlen "0" and
- * handle this case specially, if
- * there were a pressing need...
- */
- command_errmsg = "bad dir entry";
- result = CMD_ERROR;
- goto out;
- }
-
- if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
- if (verbose) {
- /* stat the file, if possible */
- sb.st_size = 0;
- buf = malloc(strlen(path) + strlen(dp->d_name) + 2);
- sprintf(buf, "%s/%s", path, dp->d_name);
- /* ignore return, could be symlink, etc. */
- if (stat(buf, &sb))
- sb.st_size = 0;
- free(buf);
- sprintf(lbuf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name);
- } else
- sprintf(lbuf, " %c %s\n", typestr[dp->d_type], dp->d_name);
- if (pager_output(lbuf))
- goto out;
- }
+ while ((d = readdirfd(fd)) != NULL) {
+ if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
+ if (verbose) {
+ /* stat the file, if possible */
+ sb.st_size = 0;
+ buf = malloc(strlen(path) + strlen(d->d_name) + 2);
+ sprintf(buf, "%s/%s", path, d->d_name);
+ /* ignore return, could be symlink, etc. */
+ if (stat(buf, &sb))
+ sb.st_size = 0;
+ free(buf);
+ sprintf(lbuf, " %c %8d %s\n", typestr[d->d_type],
+ (int)sb.st_size, d->d_name);
+ } else {
+ sprintf(lbuf, " %c %s\n", typestr[d->d_type], d->d_name);
}
- dp = (struct direct *) ((char *) dp + dp->d_reclen);
+ if (pager_output(lbuf))
+ goto out;
}
}
out:
diff --git a/sys/boot/i386/libi386/biosdisk.c b/sys/boot/i386/libi386/biosdisk.c
index c748117..bee8a52 100644
--- a/sys/boot/i386/libi386/biosdisk.c
+++ b/sys/boot/i386/libi386/biosdisk.c
@@ -72,15 +72,16 @@ struct open_disk {
int od_sec;
int od_boff; /* block offset from beginning of BIOS disk */
int od_flags;
-#define BD_MODEMASK 0x3
-#define BD_MODEINT13 0x0
-#define BD_MODEEDD1 0x1
-#define BD_MODEEDD3 0x2
-#define BD_FLOPPY (1<<2)
+#define BD_MODEINT13 0x0000
+#define BD_MODEEDD1 0x0001
+#define BD_MODEEDD3 0x0002
+#define BD_MODEMASK 0x0003
+#define BD_FLOPPY 0x0004
+#define BD_LABELOK 0x0008
+#define BD_PARTTABOK 0x0010
struct disklabel od_disklabel;
- struct dos_partition od_parttab[NDOSPART]; /* XXX needs to grow for extended partitions */
-#define BD_LABELOK (1<<3)
-#define BD_PARTTABOK (1<<4)
+ int od_nslices; /* slice count */
+ struct dos_partition od_slicetab[MAX_SLICES];
};
/*
@@ -96,15 +97,20 @@ static struct bdinfo
static int nbdinfo = 0;
static int bd_getgeom(struct open_disk *od);
-static int bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest);
+static int bd_read(struct open_disk *od, daddr_t dblk, int blks,
+ caddr_t dest);
static int bd_int13probe(struct bdinfo *bd);
-static void bd_printslice(struct open_disk *od, int offset, char *prefix);
+static void bd_printslice(struct open_disk *od, struct dos_partition *dp,
+ char *prefix);
+static void bd_printbsdslice(struct open_disk *od, int offset, char *prefix);
static int bd_init(void);
-static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
-static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
+static int bd_strategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, void *buf, size_t *rsize);
+static int bd_realstrategy(void *devdata, int flag, daddr_t dblk,
+ size_t size, void *buf, size_t *rsize);
static int bd_open(struct open_file *f, ...);
static int bd_close(struct open_file *f);
static void bd_print(int verbose);
@@ -122,7 +128,8 @@ struct devsw biosdisk = {
static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev);
static void bd_closedisk(struct open_disk *od);
-static int bd_bestslice(struct dos_partition *dptr);
+static int bd_bestslice(struct open_disk *od);
+static void bd_checkextended(struct open_disk *od, int slicenum);
/*
* Translate between BIOS device numbers and our private unit numbers.
@@ -228,58 +235,75 @@ bd_print(int verbose)
/* Do we have a partition table? */
if (od->od_flags & BD_PARTTABOK) {
- dptr = &od->od_parttab[0];
+ dptr = &od->od_slicetab[0];
/* Check for a "truly dedicated" disk */
if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
(dptr[3].dp_start == 0) &&
(dptr[3].dp_size == 50000)) {
sprintf(line, " disk%d", i);
- bd_printslice(od, 0, line);
+ bd_printbsdslice(od, 0, line);
} else {
- for (j = 0; j < NDOSPART; j++) {
- switch(dptr[j].dp_typ) {
- case DOSPTYP_386BSD:
- sprintf(line, " disk%ds%d", i, j + 1);
- bd_printslice(od, dptr[j].dp_start, line);
- break;
- case 0x00: /* unused partition */
- break;
- case 0x01:
- sprintf(line, " disk%ds%d: FAT-12\n", i,
- j + 1);
- pager_output(line);
- break;
- case 0x04:
- case 0x06:
- case 0x0e:
- sprintf(line, " disk%ds%d: FAT-16\n", i,
- j + 1);
- pager_output(line);
- break;
- case 0x0b:
- case 0x0c:
- sprintf(line, " disk%ds%d: FAT-32\n", i,
- j + 1);
- pager_output(line);
- break;
- default:
- sprintf(line, " disk%ds%d: Unknown fs: 0x%x\n",
- i, j + 1, dptr[j].dp_typ);
- pager_output(line);
- break;
- }
- }
-
- }
+ for (j = 0; j < od->od_nslices; j++) {
+ sprintf(line, " disk%ds%d", i, j + 1);
+ bd_printslice(od, &dptr[j], line);
+ }
+ }
}
bd_closedisk(od);
}
}
}
+/*
+ * Print information about slices on a disk
+ */
+static void
+bd_printslice(struct open_disk *od, struct dos_partition *dp, char *prefix)
+{
+ char line[80];
+
+ switch (dp->dp_typ) {
+ case DOSPTYP_386BSD:
+ bd_printbsdslice(od, dp->dp_start, prefix);
+ return;
+ case DOSPTYP_LINSWP:
+ sprintf(line, "%s: Linux swap %.6dMB (%d - %d)\n", prefix,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
+ break;
+ case DOSPTYP_LINUX:
+ /*
+ * XXX
+ * read the superblock to confirm this is an ext2fs partition?
+ */
+ sprintf(line, "%s: ext2fs %.6dMB (%d - %d)\n", prefix,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
+ break;
+ case 0x00: /* unused partition */
+ case DOSPTYP_EXT:
+ return;
+ case 0x01:
+ sprintf(line, "%s: FAT-12\n", prefix);
+ break;
+ case 0x04:
+ case 0x06:
+ case 0x0e:
+ sprintf(line, "%s: FAT-16\n", prefix);
+ break;
+ case 0x0b:
+ case 0x0c:
+ sprintf(line, "%s: FAT-32\n", prefix);
+ break;
+ default:
+ sprintf(line, "%s: Unknown fs: 0x%x\n", prefix, dp->dp_typ);
+ }
+ pager_output(line);
+}
+
static void
-bd_printslice(struct open_disk *od, int offset, char *prefix)
+bd_printbsdslice(struct open_disk *od, int offset, char *prefix)
{
char line[80];
u_char buf[BIOSDISK_SECSIZE];
@@ -352,7 +376,6 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
int sector, slice, i;
int error;
u_char buf[BUFSIZE];
- daddr_t pref_slice[4];
if (dev->d_kind.biosdisk.unit >= nbdinfo) {
DEBUG("attempt to open nonexistent disk");
@@ -370,6 +393,7 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
od->od_unit = bdinfo[od->od_dkunit].bd_unit;
od->od_flags = bdinfo[od->od_dkunit].bd_flags;
od->od_boff = 0;
+ od->od_nslices = 0;
error = 0;
DEBUG("open '%s', unit 0x%x slice %d partition %c",
i386_fmtdev(dev), dev->d_kind.biosdisk.unit,
@@ -410,9 +434,17 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
sector = 0;
goto unsliced; /* may be a floppy */
}
- bcopy(buf + DOSPARTOFF, &od->od_parttab, sizeof(struct dos_partition) * NDOSPART);
- dptr = &od->od_parttab[0];
+
+ /*
+ * copy the partition table, then pick up any extended partitions.
+ */
+ bcopy(buf + DOSPARTOFF, &od->od_slicetab,
+ sizeof(struct dos_partition) * NDOSPART);
+ od->od_nslices = 4; /* extended slices start here */
+ for (i = 0; i < NDOSPART; i++)
+ bd_checkextended(od, i);
od->od_flags |= BD_PARTTABOK;
+ dptr = &od->od_slicetab[0];
/* Is this a request for the whole disk? */
if (dev->d_kind.biosdisk.slice == -1) {
@@ -420,21 +452,39 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
goto unsliced;
}
- /* Try to auto-detect the best slice; this should always give a slice number */
- if (dev->d_kind.biosdisk.slice == 0)
- dev->d_kind.biosdisk.slice = bd_bestslice(dptr);
+ /*
+ * if a slice number was supplied but not found, this is an error.
+ */
+ if (dev->d_kind.biosdisk.slice > 0) {
+ slice = dev->d_kind.biosdisk.slice - 1;
+ if (slice >= od->od_nslices) {
+ DEBUG("slice %d not found", slice);
+ error = ENOENT;
+ goto out;
+ }
+ }
- switch (dev->d_kind.biosdisk.slice) {
- case -1:
- error = ENOENT;
- goto out;
- case 0:
- sector = 0;
- goto unsliced;
- default:
- break;
+ /*
+ * Check for the historically bogus MBR found on true dedicated disks
+ */
+ if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
+ (dptr[3].dp_start == 0) &&
+ (dptr[3].dp_size == 50000)) {
+ sector = 0;
+ goto unsliced;
}
+ /* Try to auto-detect the best slice; this should always give a slice number */
+ if (dev->d_kind.biosdisk.slice == 0) {
+ slice = bd_bestslice(od);
+ if (slice == -1) {
+ error = ENOENT;
+ goto out;
+ }
+ dev->d_kind.biosdisk.slice = slice;
+ }
+
+ dptr = &od->od_slicetab[0];
/*
* Accept the supplied slice number unequivocally (we may be looking
* at a DOS partition).
@@ -501,74 +551,113 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
return(error);
}
+static void
+bd_checkextended(struct open_disk *od, int slicenum)
+{
+ u_char buf[BIOSDISK_SECSIZE];
+ struct dos_partition *dp;
+ u_int base;
+ int i, start, end;
+
+ dp = &od->od_slicetab[slicenum];
+ start = od->od_nslices;
+
+ if (dp->dp_size == 0)
+ goto done;
+ if (dp->dp_typ != DOSPTYP_EXT)
+ goto done;
+ if (bd_read(od, dp->dp_start, 1, buf))
+ goto done;
+ if ((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) {
+ DEBUG("no magic in extended table");
+ goto done;
+ }
+ base = dp->dp_start;
+ dp = (struct dos_partition *)(&buf[DOSPARTOFF]);
+ for (i = 0; i < NDOSPART; i++, dp++) {
+ if (dp->dp_size == 0)
+ continue;
+ if (od->od_nslices == MAX_SLICES)
+ goto done;
+ dp->dp_start += base;
+ bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp));
+ od->od_nslices++;
+ }
+ end = od->od_nslices;
+
+ /*
+ * now, recursively check the slices we just added
+ */
+ for (i = start; i < end; i++)
+ bd_checkextended(od, i);
+done:
+ return;
+}
/*
* Search for a slice with the following preferences:
*
* 1: Active FreeBSD slice
* 2: Non-active FreeBSD slice
- * 3: Active FAT/FAT32 slice
- * 4: non-active FAT/FAT32 slice
+ * 3: Active Linux slice
+ * 4: non-active Linux slice
+ * 5: Active FAT/FAT32 slice
+ * 6: non-active FAT/FAT32 slice
*/
-#define PREF_FBSD_ACT 0
-#define PREF_FBSD 1
-#define PREF_DOS_ACT 2
-#define PREF_DOS 3
-#define PREF_NONE 4
+#define PREF_RAWDISK 0
+#define PREF_FBSD_ACT 1
+#define PREF_FBSD 2
+#define PREF_LINUX_ACT 3
+#define PREF_LINUX 4
+#define PREF_DOS_ACT 5
+#define PREF_DOS 6
+#define PREF_NONE 7
+/*
+ * slicelimit is in the range 0 .. NDOSPART
+ */
static int
-bd_bestslice(struct dos_partition *dptr)
+bd_bestslice(struct open_disk *od)
{
- int i;
- int preflevel, pref;
-
+ struct dos_partition *dp;
+ int pref, preflevel;
+ int i, prefslice;
- /*
- * Check for the historically bogus MBR found on true dedicated disks
- */
- if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
- (dptr[3].dp_start == 0) &&
- (dptr[3].dp_size == 50000))
- return(0);
+ prefslice = 0;
+ preflevel = PREF_NONE;
+
+ dp = &od->od_slicetab[0];
+ for (i = 0; i < od->od_nslices; i++, dp++) {
+
+ switch (dp->dp_typ) {
+ case DOSPTYP_386BSD: /* FreeBSD */
+ pref = dp->dp_flag & 0x80 ? PREF_FBSD_ACT : PREF_FBSD;
+ break;
- preflevel = PREF_NONE;
- pref = -1;
+ case DOSPTYP_LINUX:
+ pref = dp->dp_flag & 0x80 ? PREF_LINUX_ACT : PREF_LINUX;
+ break;
- /*
- * XXX No support here for 'extended' slices
- */
- for (i = 0; i < NDOSPART; i++) {
- switch(dptr[i].dp_typ) {
- case DOSPTYP_386BSD: /* FreeBSD */
- if ((dptr[i].dp_flag & 0x80) && (preflevel > PREF_FBSD_ACT)) {
- pref = i;
- preflevel = PREF_FBSD_ACT;
- } else if (preflevel > PREF_FBSD) {
- pref = i;
- preflevel = PREF_FBSD;
- }
- break;
-
- case 0x01: /* DOS/Windows */
- case 0x04:
- case 0x06:
- case 0x0b:
- case 0x0c:
- case 0x0e:
- if ((dptr[i].dp_flag & 0x80) && (preflevel > PREF_DOS_ACT)) {
- pref = i;
- preflevel = PREF_DOS_ACT;
- } else if (preflevel > PREF_DOS) {
- pref = i;
- preflevel = PREF_DOS;
- }
- break;
+ case 0x01: /* DOS/Windows */
+ case 0x04:
+ case 0x06:
+ case 0x0b:
+ case 0x0c:
+ case 0x0e:
+ pref = dp->dp_flag & 0x80 ? PREF_DOS_ACT : PREF_DOS;
+ break;
+
+ default:
+ pref = PREF_NONE;
+ }
+ if (pref < preflevel) {
+ preflevel = pref;
+ prefslice = i + 1;
+ }
}
- }
- return(pref + 1); /* slices numbered 1-4 */
+ return (prefslice);
}
-
static int
bd_close(struct open_file *f)
{
diff --git a/sys/boot/i386/loader/conf.c b/sys/boot/i386/loader/conf.c
index ab1f122..dfdcc2c 100644
--- a/sys/boot/i386/loader/conf.c
+++ b/sys/boot/i386/loader/conf.c
@@ -56,6 +56,7 @@ struct devsw *devsw[] = {
struct fs_ops *file_system[] = {
&ufs_fsops,
+ &ext2fs_fsops,
&dosfs_fsops,
&zipfs_fsops,
#ifdef LOADER_NFS_SUPPORT
diff --git a/sys/boot/powerpc/loader/conf.c b/sys/boot/powerpc/loader/conf.c
index d243399..5f2f519 100644
--- a/sys/boot/powerpc/loader/conf.c
+++ b/sys/boot/powerpc/loader/conf.c
@@ -59,6 +59,9 @@ struct fs_ops *file_system[] = {
#ifdef LOADER_CDROM_SUPPORT
&cd9660_fsops,
#endif
+#ifdef LOADER_EXT2FS_SUPPORT
+ &ext2fs_fsops,
+#endif
#ifdef LOADER_NET_SUPPORT
&nfs_fsops,
#endif
diff --git a/sys/boot/powerpc/ofw/conf.c b/sys/boot/powerpc/ofw/conf.c
index d243399..5f2f519 100644
--- a/sys/boot/powerpc/ofw/conf.c
+++ b/sys/boot/powerpc/ofw/conf.c
@@ -59,6 +59,9 @@ struct fs_ops *file_system[] = {
#ifdef LOADER_CDROM_SUPPORT
&cd9660_fsops,
#endif
+#ifdef LOADER_EXT2FS_SUPPORT
+ &ext2fs_fsops,
+#endif
#ifdef LOADER_NET_SUPPORT
&nfs_fsops,
#endif
OpenPOWER on IntegriCloud