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 */