diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/gpt.c | 15 | ||||
-rw-r--r-- | src/gpt.h | 3 | ||||
-rw-r--r-- | src/pmbr.c | 93 | ||||
-rw-r--r-- | src/prototypes.h | 5 | ||||
-rw-r--r-- | src/show.c | 2 |
6 files changed, 120 insertions, 5 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 207f842..6bc1acf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,9 +5,12 @@ # Copyright (c) 2007 James McKenzie <james@fishsoup.dhs.org>, # All rights reserved. # -# $Id: Makefile.am,v 1.5 2007/09/10 11:23:08 root Exp $ +# $Id: Makefile.am,v 1.6 2007/11/12 13:28:04 james Exp $ # # $Log: Makefile.am,v $ +# Revision 1.6 2007/11/12 13:28:04 james +# *** empty log message *** +# # Revision 1.5 2007/09/10 11:23:08 root # *** empty log message *** # @@ -31,7 +34,7 @@ noinst_HEADERS=project.h prototypes.h bin_PROGRAMS = gpt -SRCS=gpt.c version.c util.c guid.c crc.c header.c disk.c pmbr.c show.c entry.c new.c modify.c +SRCS=gpt.c version.c util.c guid.c crc.c header.c disk.c pmbr.c show.c entry.c new.c modify.c sync.c gpt_SOURCES = ${SRCS} gpt_LDADD = @@ -6,10 +6,13 @@ * */ -static char rcsid[] = "$Id: gpt.c,v 1.11 2007/10/17 09:51:42 james Exp $"; +static char rcsid[] = "$Id: gpt.c,v 1.12 2007/11/12 13:28:04 james Exp $"; /* * $Log: gpt.c,v $ + * Revision 1.12 2007/11/12 13:28:04 james + * *** empty log message *** + * * Revision 1.11 2007/10/17 09:51:42 james * *** empty log message *** * @@ -68,6 +71,9 @@ fprintf(stderr, "gpt -d disk-device -a n name type start end\n" " set partiton n, type can either be a named\n" " type or a hexadecimal GUID\n" +"gpt -d disk-device -c fill the PMBR with entries taken from\n" +" the first few GPT entries, using dark\n" +" voodoo\n" ); exit(1); } @@ -87,7 +93,7 @@ main (int argc, char *argv[]) extern int optind; - while ((c=getopt(argc,argv,"d:hlsef:una"))!=EOF) { + while ((c=getopt(argc,argv,"d:hlsef:unac"))!=EOF) { switch(c) { case 'd': d=disk_open(optarg); @@ -129,6 +135,11 @@ main (int argc, char *argv[]) if (!d) usage(); show(d); return 0; + case 'c': + if (!d) usage(); + sync_tables(d); + //show(d); + return 0; default: usage(); } @@ -49,6 +49,9 @@ typedef struct #define MBR_PARTITION_TYPE_EFI 0xee +#define MBR_PARTITION_TYPE_LINUX 0x83 +#define MBR_PARTITION_TYPE_SWAP 0x82 +#define MBR_PARTITION_TYPE_UNKOWN 0xff #define MBR_PARTITION_BOOTABLE 0x80 #define MBR_SECTOR(a) ((a) & 0x3f) @@ -62,3 +62,96 @@ mbr_new (uint64_t lbas) return ret; } + + +static CHS +sector_to_chs (uint32_t lba) +{ + CHS ret; + int c; + int h; + int s; + + c = lba / (63 * 255); + + if (c > 1023) + { + ret.head = 254; + ret.cs = MBR_CS (1023, 63); + return ret; + } + + lba -= (c * 63 * 255); + h = lba / 63; + lba -= (h * 63); + s = lba + 1; + + + ret.head = h; + ret.cs = MBR_CS (c, s); + + return ret; +} + +void +mbr_set_entry0_from_gpt_header (MBR_entry * m, GPT_header * h) +{ + MBR ret = { 0 }; + uint32_t start = 1; + uint32_t end = h->first_usable_lba - 1; + + + m->bootable = 0; + m->chs_start = sector_to_chs (start); + m->system = MBR_PARTITION_TYPE_EFI; + m->chs_end = sector_to_chs (end); + m->start = start; + m->size = (end - start) + 1; + +} + +void +mbr_entry_from_gpt_entry (MBR_entry * m, GPT_entry * g, int bootable, + uint8_t type) +{ + MBR ret = { 0 }; + uint32_t start = g->start; + uint32_t end = g->end; + + + m->system = type; + m->bootable = bootable ? MBR_PARTITION_BOOTABLE : 0x00; + m->chs_start = sector_to_chs (start); + m->chs_end = sector_to_chs (end); + m->start = start; + m->size = (end - start) + 1; +} + +void +mbr_wedge_entry (MBR_entry * m) +{ + MBR ret = { 0 }; + + int c = MBR_CYLINDER (m->chs_end.cs); + int s = MBR_SECTOR (m->chs_end.cs); + int h = m->chs_end.head; + + while ((s != 63) || (h != 254)) + { + s++; + if (s == 64) + { + s = 1; + h++; + if (h == 255) + { + c++; + h = 0; + } + } + m->size++; + } + + m->chs_end.head = h; + m->chs_end.cs = MBR_CS (c, s); +} diff --git a/src/prototypes.h b/src/prototypes.h index 28fd0fa..201f984 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -32,6 +32,9 @@ uint64_t disk_lbas(DISK *d); void mbr_entry_show(MBR_entry *e); void mbr_show(MBR *m); MBR mbr_new(uint64_t lbas); +void mbr_set_entry0_from_gpt_header(MBR_entry *m, GPT_header *h); +void mbr_entry_from_gpt_entry(MBR_entry *m, GPT_entry *g, int bootable, uint8_t type); +void mbr_wedge_entry(MBR_entry *m); /* show.c */ void show(DISK *d); /* entry.c */ @@ -43,3 +46,5 @@ void entry_show(GPT_entry *e); void new(DISK *d); /* modify.c */ int modify(DISK *d, int n, char *name, char *type_guid, uint64_t start, uint64_t end); +/* sync.c */ +void sync_tables(DISK *d); @@ -15,7 +15,7 @@ show (DISK * d) m = (MBR *) buf; mbr_show (m); - h=headers_get(d); + h=headers_get(d); header_show (d, &h.header); header_show (d, &h.alt_header); |