sgi dislabel support for libfdisk
Hi,
the attached patch by Henning Heinold and me adds sgi disklabel support
to libfdisk. He told me this is required to get working boot-disks for the
mips-architecture. I've not been involved with the bootfloppies stuff before,
but I hope this is the right place to post it.
Regards,
-- Guido
diff -Naur libfdisk.orig/Makefile libfdisk/Makefile
--- libfdisk.orig/Makefile Wed Nov 1 14:44:18 2000
+++ libfdisk/Makefile Wed Nov 1 14:45:16 2000
@@ -25,7 +25,7 @@
PROGS =
OBJS = fdisk.o partbl_msdos.o partbl_osf.o partbl_sun.o partbl_amiga.o \
- partbl_atari.o partbl_mac.o partbl_acorn.o
+ partbl_atari.o partbl_mac.o partbl_acorn.o partbl_sgi.o
HEADERS = fdisk.h byteorder.h config.h
SOURCES = $(OBJS:%.o=%.c) testing.c
@@ -41,7 +41,7 @@
depend: $(SOURCES:%.c=.depend/%)
clean:
- rm -f $(OBJS) libfdisk.a testing.o
+ rm -f $(OBJS) libfdisk.a testing.o tags
distclean: clean
rm -f $(PROGS)
diff -Naur libfdisk.orig/config.h libfdisk/config.h
--- libfdisk.orig/config.h Wed Nov 1 14:44:18 2000
+++ libfdisk/config.h Mon Oct 16 23:23:51 2000
@@ -13,6 +13,8 @@
#define HAVE_MAC_PARTITION 1
#define HAVE_ACORN_PARTITION 1
#define HAVE_LOOP_PARTITION 1
+#define HAVE_SGI_PARTITION 1
+
#endif /* _config_h */
diff -Naur libfdisk.orig/fdisk.c libfdisk/fdisk.c
--- libfdisk.orig/fdisk.c Wed Nov 1 14:44:18 2000
+++ libfdisk/fdisk.c Sun Oct 29 02:00:28 2000
@@ -126,6 +126,10 @@
{ PTYPE_ACORN_ICS_EXT2, FSTYPE_EXT2 },
{ PTYPE_ACORN_ICS_SWAP, FSTYPE_SWAP },
#endif /* HAVE_ACORN_PARTITION */
+#if HAVE_SGI_PARTITION
+ { PTYPE_SGI_L_SWAP, FSTYPE_SWAP },
+ { PTYPE_SGI_L_NATIVE, FSTYPE_EXT2 },
+#endif /* HAVE_SGI_PARTITION */
#if HAVE_LOOP_PARTITION
/* Fake partition types for loop mounts */
{ PTYPE_LOOP_EXT2, FSTYPE_EXT2 },
@@ -342,6 +346,23 @@
{ PTYPE_ACORN_ICS_EXT2, "Linux ext2 (ICS/APDL)" },
{ PTYPE_ACORN_ICS_SWAP, "Linux swap (ICS/APDL)" },
#endif /* HAVE_ACORN_PARTITION */
+#if HAVE_SGI_PARTITION
+ { PTYPE_SGI_VOLHDR, "SGI volhdr" },
+ { PTYPE_SGI_TREPL, "SGI trkrepl" },
+ { PTYPE_SGI_SREPL, "SGI secrepl" },
+ { PTYPE_SGI_SWAP, "SGI swap" },
+ { PTYPE_SGI_BSD, "BSD " },
+ { PTYPE_SGI_SYSV, "System V" },
+ { PTYPE_SGI_VOL, "SGI disk" },
+ { PTYPE_SGI_EFS, "SGI efs" },
+ { PTYPE_SGI_LVOL, "SGI lvol" },
+ { PTYPE_SGI_RLVOL, "SGI rlvol" },
+ { PTYPE_SGI_XFS, "SGI xfs" },
+ { PTYPE_SGI_XLVOL, "SGI xlvol" },
+ { PTYPE_SGI_RXLVOL, "SGI rxlvol" },
+ { PTYPE_SGI_L_SWAP, "Linux Swap" },
+ { PTYPE_SGI_L_NATIVE, "Linux native" },
+#endif /* HAVE_SGI_PARTITION */
#if HAVE_LOOP_PARTITION
{ PTYPE_LOOP_EXT2, "Linux native (loop mounted)" },
{ PTYPE_LOOP_SWAP, "Linux swap (loop mounted)" },
@@ -1025,7 +1046,8 @@
{ "amiga", parse_amiga_partition },
{ "atari", parse_atari_partition },
{ "mac", parse_mac_partition },
- { "acorn", parse_acorn_partition }
+ { "acorn", parse_acorn_partition },
+ { "sgi", parse_sgi_partition }
};
static void
diff -Naur libfdisk.orig/fdisk.h libfdisk/fdisk.h
--- libfdisk.orig/fdisk.h Wed Nov 1 14:44:18 2000
+++ libfdisk/fdisk.h Sun Oct 29 02:59:54 2000
@@ -110,6 +110,10 @@
#if HAVE_ACORN_PARTITION
int parse_acorn_partition(char *device, int fd);
#endif
+#if HAVE_SGI_PARTITION
+int parse_sgi_partition(char *device, int fd);
+#endif
+
/* -------------------- partition type numbers -------------------- */
/*
@@ -285,6 +289,24 @@
#define PTYPE_ACORN_ICS_ADFS (PTYPE_PREFIX_ACORN|0x05)
#define PTYPE_ACORN_ICS_EXT2 (PTYPE_PREFIX_ACORN|0x06)
#define PTYPE_ACORN_ICS_SWAP (PTYPE_PREFIX_ACORN|0x07)
+
+/* SGI partition ids */
+#define PTYPE_SGI_VOLHDR 0x00 /* volhdr */
+#define PTYPE_SGI_TREPL 0x01 /* trkrep */
+#define PTYPE_SGI_SREPL 0x02 /* secrepl */
+#define PTYPE_SGI_SWAP 0x03 /* swap */
+#define PTYPE_SGI_BSD 0x04 /* bsd */
+#define PTYPE_SGI_SYSV 0x05 /* sysv */
+#define PTYPE_SGI_VOL 0x06 /* entire disk/volume */
+#define PTYPE_SGI_EFS 0x07 /* efs */
+#define PTYPE_SGI_LVOL 0x08 /* lvol */
+#define PTYPE_SGI_RLVOL 0x09 /* rlvol */
+#define PTYPE_SGI_XFS 0x0A /* xfs */
+#define PTYPE_SGI_XLVOL 0x0B /* xlvo */
+#define PTYPE_SGI_RXLVOL 0x0C /* rxlvol */
+#define PTYPE_SGI_L_SWAP 0x82
+#define PTYPE_SGI_L_NATIVE 0x83
+
/* Fake partition types for loop mounts */
#define PTYPE_PREFIX_LOOP 0x4c4f5000
diff -Naur libfdisk.orig/partbl_sgi.c libfdisk/partbl_sgi.c
--- libfdisk.orig/partbl_sgi.c Thu Jan 1 01:00:00 1970
+++ libfdisk/partbl_sgi.c Wed Nov 1 14:48:11 2000
@@ -0,0 +1,108 @@
+#include "config.h"
+#if HAVE_SGI_PARTITION
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <asm/types.h>
+#include "byteorder.h"
+
+#include "fdisk.h"
+
+#define SGI_LABEL_MAGIC 0x0be5a941
+#define sgilabel ((struct sgi_disklabel *)data)
+
+
+struct sgi_disklabel {
+ __u32 magic; /* expect SGI_LABEL_MAGIC */
+ __u16 boot_part; /* active boot partition */
+ __u16 swap_part; /* active swap partition */
+ __u8 boot_file[16]; /* name of the bootfile */
+ struct device_parameter { /* 1 * 48 bytes */
+ __u8 skew;
+ __u8 gap1;
+ __u8 gap2;
+ __u8 sparecyl;
+ __u16 pcylcount;
+ __u16 head_vol0;
+ __u16 ntrks; /* tracks in cyl 0 or vol 0 */
+ __u8 cmd_tag_queue_depth;
+ __u8 unused0;
+ __u16 unused1;
+ __u16 nsect; /* sectors/tracks in cyl 0 or vol 0 */
+ __u16 bytes;
+ __u16 ilfact;
+ __u32 flags; /* controller flags */
+ __u32 datarate;
+ __u32 retries_on_error;
+ __u32 ms_per_word;
+ __u16 xylogics_gap1;
+ __u16 xylogics_syncdelay;
+ __u16 xylogics_readdelay;
+ __u16 xylogics_gap2;
+ __u16 xylogics_readgate;
+ __u16 xylogics_writecont;
+ };
+ struct volume_directory { /* 15 * 16 bytes */
+ __u8 vol_file_name[8]; /* an character array */
+ __u32 vol_file_start; /* number of logical block */
+ __u32 vol_file_size; /* number of bytes */
+ } directory[15];
+ struct sgi_partition { /* 16 * 12 bytes */
+ __u32 num_sectors; /* number of blocks */
+ __u32 start_sector; /* sector must be cylinder aligned */
+ __u32 id;
+ }partitions[16];
+ __u32 csum;
+ __u32 fillbytes;
+};
+
+
+static unsigned int two_s_complement_32bit_sum(
+ unsigned int* base,
+ int size /* in bytes */ )
+{
+ int i=0;
+ unsigned int sum=0;
+ size = size / sizeof( unsigned int );
+ for( i=0; i<size; i++ )
+ {
+ sum -= __cpu_to_be32(base[i]);
+ }
+ return sum;
+}
+
+int parse_sgi_partition(char *device, int fd)
+{
+ struct sgi_disklabel* label;
+ struct sgi_partition *p;
+ unsigned i, blocks, minor = 1;
+
+ unsigned char data[512];
+
+ if (!sread( fd, 0, data ))
+ return -1;
+ label = (struct sgi_disklabel *) data;
+ if (__be32_to_cpu(label->magic) != SGI_LABEL_MAGIC) {
+ return 0;
+ }
+ /* Look at the checksum */
+ if( two_s_complement_32bit_sum( (unsigned int*)sgilabel,
+ sizeof(*sgilabel) ) ) {
+ return 0;
+ }
+
+ /* SGI Disklabel can have up to 16 partitions */
+ p = label->partitions;
+ for( i = 0; i < 16; i++, p++ ) {
+ blocks = __cpu_to_be32(p->num_sectors);
+ if(!blocks)
+ continue;
+ /* XXX: blocksize? */
+ fdisk_add_partition(device, minor, p->id, blocks/2);
+ ++minor;
+ }
+ return 1;
+}
+#endif /*HAVE_SGI_PARTITION */
Reply to: