linux-mips-fnet
[Top] [All Lists]

NetBSD partition support for DECStation Linux

To: linux-mips@fnet.fr
Subject: NetBSD partition support for DECStation Linux
From: Karel van Houten <K.H.C.vanHouten@research.kpn.com>
Date: Sun, 07 Mar 1999 17:15:58 +0100
Cc: "Karel van Houten (Kantoor)" <K.H.C.vanHouten@research.kpn.com>
Sender: karel@research.kpn.com
Hi, 

I've cleaned up my hacks. The last open issue is about byte-order,
my changes work OK on a DECStation, but it might not on other platforms.
A few 'b16_to_cpus' might be needed.

Anyhow, this is what my kernel prints during boot:

...
Partition check:
 sda: sda1 sda2 (MSDOS partition table)
 sdb: sdb1 sdb2 sdb3 sdb4 sdb5 (NETBSD partition table, offset 64)
 sdc: sdc1 sdc2 sdc3 sdc4 sdc5 sdc6 sdc7 sdc8 (ULTRIX partition table)
 sdd: sdd1 sdd2 sdd3 (SUN partition table)
...

Attached is the patch, against Haralds 2.2.1-dec kernel source.

Regards,
-- 
Karel van Houten
----------------------------------------------------------
The box said "Requires Windows 95 or better."
I can't understand why it won't work on my Linux computer.
diff -rubN linux-2.2.1-orig/drivers/block/genhd.c 
linux-2.2.1-karel/drivers/block/genhd.c
--- linux-2.2.1-orig/drivers/block/genhd.c      Mon Mar  1 19:44:46 1999
+++ linux-2.2.1-karel/drivers/block/genhd.c     Sun Mar  7 14:34:56 1999
@@ -608,7 +608,7 @@
                        add_partition(hd, current_minor, START_SECT(p), 
NR_SECTS(p));
                }
        }
-       printk("\n");
+       printk(" (MSDOS partition table)\n");
        brelse(bh);
        return 1;
 }
@@ -681,7 +681,7 @@
                                partition->p_size);
                current_minor++;
        }
-       printk("\n");
+       printk(" (OSF partition table)\n");
        brelse(bh);
        return 1;
 }
@@ -727,8 +727,11 @@
        label = (struct sun_disklabel *) bh->b_data;
        p = label->partitions;
        if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
+               /* 
+                * If it is not a sun disk, keep quiet!
                printk("Dev %s Sun disklabel: bad magic %04x\n",
                       kdevname(dev), be16_to_cpu(label->magic));
+               */
                brelse(bh);
                return 0;
        }
@@ -754,7 +757,7 @@
                        add_partition(hd, current_minor, st_sector, 
num_sectors);
                current_minor++;
        }
-       printk("\n");
+       printk(" (SUN partition table)\n");
        brelse(bh);
        return 1;
 }
@@ -822,7 +825,7 @@
                add_partition(hd, current_minor, p->first_block, p->num_blocks);
                current_minor++;
        }
-       printk("\n");
+       printk(" (AMIGA partition table)\n");
        brelse(bh);
        return 1;
 }
@@ -1035,7 +1038,7 @@
                ++current_minor;
        }
        brelse(bh);
-       printk("\n");
+       printk(" (MAC partition table)\n");
        return 1;
 }
 
@@ -1213,7 +1216,7 @@
                                add_partition(hd, minor, 
                                              label->pt_part[i].pi_blkoff,
                                              label->pt_part[i].pi_nblocks);
-               printk("\n");
+               printk(" (ULTRIX partition table)\n");
                brelse(bh);
                return 1;
        } else {
@@ -1224,6 +1227,140 @@
 
 #endif /* CONFIG_ULTRIX_PARTITION */
 
+#ifdef CONFIG_NETBSD_PARTITION
+/*
+ * Native NetBSD disklabels, not inside MSDOS partitions.
+ * 
+ * Support addded by Karel van Houten <vhouten@xs4all.nl>
+ * 1999/03/07
+ *
+ *
+ */
+
+#define LABELOFFSET     64                      /* offset of label in sector */
+#define MAXPARTITIONS   8                       /* number of partitions */
+
+#define DISKMAGIC      ((u_int32_t)0x82564557) /* The disk magic number */
+
+#define NOFFSETS 4
+
+static int label_offset[NOFFSETS] = { 0, 64, 128, 516 };
+
+struct netbsd_disklabel {
+       u_int32_t d_magic;              /* the magic number */
+       u_int16_t d_type;               /* drive type */
+       u_int16_t d_subtype;            /* controller/d_type specific */
+       char      d_typename[16];       /* type name, e.g. "eagle" */
+       union {
+               char    un_d_packname[16];      /* pack identifier */
+               struct {
+                       char *un_d_boot0;       /* primary bootstrap name */
+                       char *un_d_boot1;       /* secondary bootstrap name */
+               } un_b;
+       } d_un;
+#define d_packname     d_un.un_d_packname
+#define d_boot0                d_un.un_b.un_d_boot0
+#define d_boot1                d_un.un_b.un_d_boot1
+       u_int32_t d_secsize;            /* # of bytes per sector */
+       u_int32_t d_nsectors;           /* # of data sectors per track */
+       u_int32_t d_ntracks;            /* # of tracks per cylinder */
+       u_int32_t d_ncylinders;         /* # of data cylinders per unit */
+       u_int32_t d_secpercyl;          /* # of data sectors per cylinder */
+       u_int32_t d_secperunit;         /* # of data sectors per unit */
+       u_int16_t d_sparespertrack;     /* # of spare sectors per track */
+       u_int16_t d_sparespercyl;       /* # of spare sectors per cylinder */
+       u_int32_t d_acylinders;         /* # of alt. cylinders per unit */
+       u_int16_t d_rpm;                /* rotational speed */
+       u_int16_t d_interleave;         /* hardware sector interleave */
+       u_int16_t d_trackskew;          /* sector 0 skew, per track */
+       u_int16_t d_cylskew;            /* sector 0 skew, per cylinder */
+       u_int32_t d_headswitch;         /* head switch time, usec */
+       u_int32_t d_trkseek;            /* track-to-track seek, usec */
+       u_int32_t d_flags;              /* generic flags */
+#define NDDATA 5
+       u_int32_t d_drivedata[NDDATA];  /* drive-type specific information */
+#define NSPARE 5
+       u_int32_t d_spare[NSPARE];      /* reserved for future use */
+       u_int32_t d_magic2;             /* the magic number (again) */
+       u_int16_t d_checksum;           /* xor of data incl. partitions */
+
+                       /* filesystem and partition information: */
+       u_int16_t d_npartitions;        /* number of partitions in following */
+       u_int32_t d_bbsize;             /* size of boot area at sn0, bytes */
+       u_int32_t d_sbsize;             /* max size of fs superblock, bytes */
+       struct  nbsdpartition {         /* the partition table */
+               u_int32_t p_size;       /* number of sectors in partition */
+               u_int32_t p_offset;     /* starting sector */
+               u_int32_t p_fsize;      /* filesystem basic fragment size */
+               u_int8_t p_fstype;      /* filesystem type, see below */
+               u_int8_t p_frag;        /* filesystem fragments per block */
+               union {
+                       u_int16_t cpg;  /* UFS: FS cylinders per group */
+                       u_int16_t sgs;  /* LFS: FS segment shift */
+               } __partition_u1;
+#define        p_cpg   __partition_u1.cpg
+#define        p_sgs   __partition_u1.sgs
+       } d_partitions[MAXPARTITIONS];  /* actually may be more */
+};
+
+/*
+ * Compute checksum for disk label.
+ */
+static u_int
+dkcksum(lp)
+        register struct netbsd_disklabel *lp;
+{
+        register u_short *start, *end;
+        register u_short sum = 0;
+
+        start = (u_short *)lp;
+        end = (u_short *)&lp->d_partitions[lp->d_npartitions];
+        while (start < end)
+                sum ^= *start++;
+        return (sum);
+}
+
+static int netbsd_partition(struct gendisk *hd, kdev_t dev, unsigned long 
first_sector)
+{
+        int i,j, minor = current_minor;
+        struct buffer_head *bh;
+        struct netbsd_disklabel *label;
+
+
+        bh = bread (dev, 0, get_ptable_blocksize(dev));
+        if (!bh) {
+                printk (" unable to read block %d\n", 0);
+                return -1;
+        }
+
+       for (j=0; j<NOFFSETS; j++) {
+           label = (struct netbsd_disklabel *)(bh->b_data + label_offset[j]);
+
+           if (label->d_magic == DISKMAGIC && label->d_magic2 == DISKMAGIC) {
+                   if (dkcksum(label) != 0) {
+                       printk("Dev %s NetBSD disklabel: bad checksum\n");
+
+                       /* KvH: Should we retry a different offset? */
+                       brelse(bh);
+                       return 0;
+                   }
+                   for (i=0; i<8; i++, minor++)
+                           if (label->d_partitions[i].p_size)
+                                   add_partition(hd, minor,
+                                                 
label->d_partitions[i].p_offset,
+                                                 
label->d_partitions[i].p_size);
+                   printk(" (NETBSD partition table, offset %d)\n", 
label_offset[j]);
+                   brelse(bh);
+                   return 1;
+           }
+       }
+       brelse(bh);
+       return 0;
+}
+
+#endif /* CONFIG_NETBSD_PARTITION */
+
+
 static void check_partition(struct gendisk *hd, kdev_t dev)
 {
        static int first_time = 1;
@@ -1276,6 +1413,10 @@
 #ifdef CONFIG_ULTRIX_PARTITION
        if(ultrix_partition(hd, dev, first_sector))
                return;
+#endif
+#ifdef CONFIG_NETBSD_PARTITION
+        if(netbsd_partition(hd, dev, first_sector))
+                return;
 #endif
        printk(" unknown partition table\n");
 }
diff -rubN linux-2.2.1-orig/fs/Config.in linux-2.2.1-karel/fs/Config.in
--- linux-2.2.1-orig/fs/Config.in       Mon Mar  1 19:45:35 1999
+++ linux-2.2.1-karel/fs/Config.in      Sat Mar  6 16:22:19 1999
@@ -115,6 +115,7 @@
 bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
   bool 'Ultrix partition table support (experimental)' CONFIG_ULTRIX_PARTITION
+  bool 'NetBSD partition table support (experimental)' CONFIG_NETBSD_PARTITION
   bool 'Unixware slices support (EXPERIMENTAL)' CONFIG_UNIXWARE_DISKLABEL
 fi
 
<Prev in Thread] Current Thread [Next in Thread>
  • NetBSD partition support for DECStation Linux, Karel van Houten <=