aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james>2007-11-13 15:18:30 +0000
committerjames <james>2007-11-13 15:18:30 +0000
commitd52733329923b5379f6a2d6e74a08ac8a7dddf5b (patch)
tree43b8ba10ca9d2400a44648a13c08f82bdd34cd2d
parentb36757811f3dd70d522a8da82e335d86ebd63142 (diff)
downloadgpt-d52733329923b5379f6a2d6e74a08ac8a7dddf5b.tar.gz
gpt-d52733329923b5379f6a2d6e74a08ac8a7dddf5b.tar.bz2
gpt-d52733329923b5379f6a2d6e74a08ac8a7dddf5b.zip
*** empty log message ***
-rw-r--r--src/disk.c15
-rw-r--r--src/gpt.c200
-rw-r--r--src/gpt.h1
-rw-r--r--src/header.c80
-rw-r--r--src/modify.c44
-rw-r--r--src/pmbr.c60
-rw-r--r--src/prototypes.h4
-rw-r--r--src/show.c2
-rw-r--r--src/sync.c68
-rw-r--r--src/util.c16
-rw-r--r--version-md5sums1
-rw-r--r--version-micro2
12 files changed, 263 insertions, 230 deletions
diff --git a/src/disk.c b/src/disk.c
index 3772862..c9a230f 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -1,5 +1,6 @@
#include "project.h"
+#include <linux/fs.h>
DISK *
@@ -45,7 +46,7 @@ disk_read (DISK * d, void *buf, uint64_t lba, int lbas)
if (read (d->fd, buf, lbas) != lbas)
{
perror ("read");
- // abort ();
+ // abort ();
}
}
void
@@ -72,3 +73,15 @@ disk_lbas (DISK * d)
{
return d->lbas;
}
+
+disk_reread_kernel_table (DISK * d)
+{
+ if (ioctl (d->fd, BLKRRPART, NULL))
+ {
+ perror ("Telling kernel to re-read partition table failed:");
+ }
+ else
+ {
+ fprintf (stderr, "Kernel has re-read partition table\n");
+ }
+}
diff --git a/src/gpt.c b/src/gpt.c
index b81964d..7824fef 100644
--- a/src/gpt.c
+++ b/src/gpt.c
@@ -6,10 +6,13 @@
*
*/
-static char rcsid[] = "$Id: gpt.c,v 1.12 2007/11/12 13:28:04 james Exp $";
+static char rcsid[] = "$Id: gpt.c,v 1.13 2007/11/13 15:18:30 james Exp $";
/*
* $Log: gpt.c,v $
+ * Revision 1.13 2007/11/13 15:18:30 james
+ * *** empty log message ***
+ *
* Revision 1.12 2007/11/12 13:28:04 james
* *** empty log message ***
*
@@ -49,115 +52,130 @@ static char rcsid[] = "$Id: gpt.c,v 1.12 2007/11/12 13:28:04 james Exp $";
#include "project.h"
-void usage(void)
+void
+usage (void)
{
-fprintf(stderr,
-"Usage:\n"
-"gpt -h show help\n"
-"gpt -d disk-device -l list partitions\n"
-"gpt -d disk-device -s print the address of frist usable sector\n"
-" on the disk\n"
-" the last usable sector on the disk\n"
+ fprintf (stderr,
+ "Usage:\n"
+ "gpt -h show help\n"
+ "gpt -d disk-device -l list partitions\n"
+ "gpt -d disk-device -s print the address of frist usable sector\n"
+ " on the disk\n"
+ " the last usable sector on the disk\n"
#if 0
-"gpt -d disk-device -e print the address of the sector after the\n"
-" the last addressable sector on the disk\n"
+ "gpt -d disk-device -e print the address of the sector after the\n"
+ " the last addressable sector on the disk\n"
#endif
-"gpt -d disk-device -e print the address of the last sector\n"
-" usable in a partition\n"
-"gpt -d disk-device -f n print the lba of the last sector in\n"
-" parition n\n"
-"gpt -d disk-device -n write a new blank parition table to the disk\n"
-" the end of parition n\n"
-"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);
+ "gpt -d disk-device -e print the address of the last sector\n"
+ " usable in a partition\n"
+ "gpt -d disk-device -f n print the lba of the last sector in\n"
+ " parition n\n"
+ "gpt -d disk-device -n write a new blank parition table to the disk\n"
+ " the end of parition n\n"
+ "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);
}
int
main (int argc, char *argv[])
{
- DISK *d=NULL;
+ DISK *d = NULL;
GPT_headers h;
GPT_entry e;
int c;
int n;
- int aflag=0;
- uint64_t start_lba,end_lba;
+ int aflag = 0;
+ uint64_t start_lba, end_lba;
extern char *optarg;
extern int optind;
- while ((c=getopt(argc,argv,"d:hlsef:unac"))!=EOF) {
- switch(c) {
- case 'd':
- d=disk_open(optarg);
- if (!d) {
- fprintf(stderr,"failed to open disk %s\n",optarg);
- perror("open");
- return -1;
- }
- break;
- case 'e':
- if (!d) usage();
- h=headers_get(d);
- printf("%lld\n",(long long) h.header.last_usable_lba);
- return 0;
- case 's':
- if (!d) usage();
- h=headers_get(d);
- printf("%lld\n",(long long) h.header.first_usable_lba);
- return 0;
- case 'u':
- if (!d) usage();
- h=headers_get(d);
- printf("%lld\n",(long long) h.header.last_usable_lba);
- return 0;
- case 'f':
- h=headers_get(d);
- n=atoi(optarg);
- e=entry_read(d,&h.header,n);
- printf("%lld\n",e.end);
- return 0;
- case 'n':
- if (!d) usage();
- new(d);
- return 0;
- case 'a':
- aflag++;
- break;
- case 'l':
- if (!d) usage();
- show(d);
- return 0;
- case 'c':
- if (!d) usage();
- sync_tables(d);
- //show(d);
- return 0;
- default:
- usage();
- }
-}
-
- if (!aflag) usage();
-if (!d) usage();
-
-if ((argc-optind)!=5) usage();
-
-start_lba=strtoll(argv[optind+3],NULL,0);
-end_lba=strtoll(argv[optind+4],NULL,0);
+ while ((c = getopt (argc, argv, "d:hlsef:unac")) != EOF)
+ {
+ switch (c)
+ {
+ case 'd':
+ d = disk_open (optarg);
+ if (!d)
+ {
+ fprintf (stderr, "failed to open disk %s\n", optarg);
+ perror ("open");
+ return -1;
+ }
+ break;
+ case 'e':
+ if (!d)
+ usage ();
+ h = headers_get (d);
+ printf ("%lld\n", (long long) h.header.last_usable_lba);
+ return 0;
+ case 's':
+ if (!d)
+ usage ();
+ h = headers_get (d);
+ printf ("%lld\n", (long long) h.header.first_usable_lba);
+ return 0;
+ case 'u':
+ if (!d)
+ usage ();
+ h = headers_get (d);
+ printf ("%lld\n", (long long) h.header.last_usable_lba);
+ return 0;
+ case 'f':
+ h = headers_get (d);
+ n = atoi (optarg);
+ e = entry_read (d, &h.header, n);
+ printf ("%lld\n", e.end);
+ return 0;
+ case 'n':
+ if (!d)
+ usage ();
+ new (d);
+ disk_reread_kernel_table (d);
+ return 0;
+ case 'a':
+ aflag++;
+ break;
+ case 'l':
+ if (!d)
+ usage ();
+ show (d);
+ return 0;
+ case 'c':
+ if (!d)
+ usage ();
+ sync_tables (d);
+ show (d);
+ disk_reread_kernel_table (d);
+ return 0;
+ default:
+ usage ();
+ }
+ }
+
+ if (!aflag)
+ usage ();
+ if (!d)
+ usage ();
+
+ if ((argc - optind) != 5)
+ usage ();
+
+ start_lba = strtoll (argv[optind + 3], NULL, 0);
+ end_lba = strtoll (argv[optind + 4], NULL, 0);
//printf("%lld %lld\n",(long long)start_lba,(long long) end_lba);
-n=atoi(argv[optind]);
+ n = atoi (argv[optind]);
-modify(d,n,argv[optind+1] ,argv[optind+2],start_lba,end_lba);
+ modify (d, n, argv[optind + 1], argv[optind + 2], start_lba, end_lba);
-show(d);
-return 0;
+ show (d);
+ disk_reread_kernel_table (d);
+ return 0;
}
diff --git a/src/gpt.h b/src/gpt.h
index 16711df..dff9dc4 100644
--- a/src/gpt.h
+++ b/src/gpt.h
@@ -51,6 +51,7 @@ typedef struct
#define MBR_PARTITION_TYPE_EFI 0xee
#define MBR_PARTITION_TYPE_LINUX 0x83
#define MBR_PARTITION_TYPE_SWAP 0x82
+#define MBR_PARTITION_TYPE_HFS 0xaf
#define MBR_PARTITION_TYPE_UNKOWN 0xff
#define MBR_PARTITION_BOOTABLE 0x80
diff --git a/src/header.c b/src/header.c
index 6c3133d..81caf29 100644
--- a/src/header.c
+++ b/src/header.c
@@ -117,75 +117,81 @@ header_show (DISK * d, GPT_header * h)
}
-int header_validate(DISK *d,GPT_header *h)
+int
+header_validate (DISK * d, GPT_header * h)
{
GPT_header c = *h;
-uint32_t crc;
+ uint32_t crc;
c.header_crc = 0;
-if (memcmp (h->signature, GPT_HEADER_SIGNATURE, sizeof (h->signature)))
- return 0;
+ if (memcmp (h->signature, GPT_HEADER_SIGNATURE, sizeof (h->signature)))
+ return 0;
crc = crc32 (0, &c, sizeof (c));
- if (crc != h->header_crc) return 0;
+ if (crc != h->header_crc)
+ return 0;
crc = header_calc_ent_crc (d, h);
-if (crc == h->partition_entry_crc) return 0;
+ if (crc == h->partition_entry_crc)
+ return 0;
-return 1;
+ return 1;
}
-void header_redo_ent_crc(DISK *d,GPT_header *h)
+void
+header_redo_ent_crc (DISK * d, GPT_header * h)
{
-h->partition_entry_crc=header_calc_ent_crc(d,h);
-h->header_crc=0;
-h->header_crc=crc32(0,h,sizeof(*h));
+ h->partition_entry_crc = header_calc_ent_crc (d, h);
+ h->header_crc = 0;
+ h->header_crc = crc32 (0, h, sizeof (*h));
}
-void header_write(DISK *d,GPT_header *h)
+
+void
+header_write (DISK * d, GPT_header * h)
{
-uint8_t buf[512];
-memcpy(buf,h,sizeof(*h));
+ uint8_t buf[512];
+ memcpy (buf, h, sizeof (*h));
-printf("Writing header to lba %lld\n",(long long) h->my_lba);
-disk_write(d,buf,h->my_lba,1);
+ printf ("Writing header to lba %lld\n", (long long) h->my_lba);
+ disk_write (d, buf, h->my_lba, 1);
}
-int headers_validate(DISK *d,GPT_headers *h)
+int
+headers_validate (DISK * d, GPT_headers * h)
{
-if (!header_validate(d,&h->header)) return 0;
-return header_validate(d,&h->alt_header);
+ if (!header_validate (d, &h->header))
+ return 0;
+ return header_validate (d, &h->alt_header);
}
-GPT_headers headers_get(DISK *d)
+GPT_headers
+headers_get (DISK * d)
{
-GPT_headers ret;
-uint8_t buf[512];
-uint64_t lbas;
+ GPT_headers ret;
+ uint8_t buf[512];
+ uint64_t lbas;
-lbas=disk_lbas(d);
+ lbas = disk_lbas (d);
-disk_read(d,buf,1,1);
-memcpy(&ret.header,buf,sizeof(ret.header));
+ disk_read (d, buf, 1, 1);
+ memcpy (&ret.header, buf, sizeof (ret.header));
-lbas--;
+ lbas--;
-if (lbas!=ret.header.alternate_lba) {
- fprintf(stderr,"WARNING: alternate lba is not at end of disk\n");
-}
+ if (lbas != ret.header.alternate_lba)
+ {
+ fprintf (stderr, "WARNING: alternate lba is not at end of disk\n");
+ }
-disk_read(d,buf,ret.header.alternate_lba,1);
-memcpy(&ret.alt_header,buf,sizeof(ret.alt_header));
+ disk_read (d, buf, ret.header.alternate_lba, 1);
+ memcpy (&ret.alt_header, buf, sizeof (ret.alt_header));
-return ret;
+ return ret;
}
-
-
-
-
diff --git a/src/modify.c b/src/modify.c
index 89500ac..3632ec7 100644
--- a/src/modify.c
+++ b/src/modify.c
@@ -3,36 +3,38 @@
int
-modify (DISK * d, int n, char *name,char *type_guid, uint64_t start, uint64_t end)
+modify (DISK * d, int n, char *name, char *type_guid, uint64_t start,
+ uint64_t end)
{
GPT_headers h;
- GPT_entry e={0};
+ GPT_entry e = { 0 };
- h=headers_get(d);
+ h = headers_get (d);
- if(a_to_guid(type_guid,&e.type)) {
- fprintf(stderr,"GUID type %s was not parsed\n",type_guid);
- exit(1);
- }
- printf("guid=%s became=%s\n",type_guid,guid_to_a(e.type));
- e.label=guid_random();
- e.start=start;
- e.end=end;
-
+ if (a_to_guid (type_guid, &e.type))
+ {
+ fprintf (stderr, "GUID type %s was not parsed\n", type_guid);
+ exit (1);
+ }
+ printf ("guid=%s became=%s\n", type_guid, guid_to_a (e.type));
+ e.label = guid_random ();
+ e.start = start;
+ e.end = end;
- ascii_to_utf16(name,-1,e.name,sizeof(e.name));
+ ascii_to_utf16 (name, -1, e.name, sizeof (e.name));
- entry_show(&e);
+
+ entry_show (&e);
/*Odd order because efi says so*/
- entry_write(d,&h.header,n,&e);
- header_redo_ent_crc(d,&h.header);
- header_write(d,&h.header);
+ entry_write (d, &h.header, n, &e);
+ header_redo_ent_crc (d, &h.header);
+ header_write (d, &h.header);
- entry_write(d,&h.alt_header,n,&e);
- header_redo_ent_crc(d,&h.alt_header);
- header_write(d,&h.alt_header);
-return 0;
+ entry_write (d, &h.alt_header, n, &e);
+ header_redo_ent_crc (d, &h.alt_header);
+ header_write (d, &h.alt_header);
+ return 0;
}
diff --git a/src/pmbr.c b/src/pmbr.c
index a958f83..b110850 100644
--- a/src/pmbr.c
+++ b/src/pmbr.c
@@ -12,7 +12,8 @@ mbr_entry_show (MBR_entry * e)
printf (" system %02x end chs %5d/%3d/%2d end sector %10d\n",
e->system,
MBR_CYLINDER (e->chs_end.cs),
- e->chs_end.head, MBR_SECTOR (e->chs_end.cs), e->size + e->start);
+ e->chs_end.head, MBR_SECTOR (e->chs_end.cs),
+ e->size + e->start - 1);
}
void
@@ -93,26 +94,23 @@ sector_to_chs (uint32_t lba)
return ret;
}
-void
-mbr_set_entry0_from_gpt_header (MBR_entry * m, GPT_header * h)
+static CHS
+invalid_chs (void)
{
- MBR ret = { 0 };
- uint32_t start = 1;
- uint32_t end = h->first_usable_lba - 1;
+ CHS ret;
+
+ ret.head = 254;
+ ret.cs = MBR_CS (1023, 63);
+ return ret;
+}
+
- 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_entry_from_gpt_entry (MBR_entry * m, GPT_header * h, GPT_entry * g,
+ int bootable, uint8_t type)
{
MBR ret = { 0 };
uint32_t start = g->start;
@@ -121,37 +119,15 @@ mbr_entry_from_gpt_entry (MBR_entry * m, GPT_entry * g, int bootable,
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->chs_start = invalid_chs ();
+ m->chs_end = invalid_chs ();
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))
+ if (type == MBR_PARTITION_TYPE_EFI)
{
- s++;
- if (s == 64)
- {
- s = 1;
- h++;
- if (h == 255)
- {
- c++;
- h = 0;
- }
- }
- m->size++;
+ m->size += m->start -1;
+ m->start = 1;
}
- m->chs_end.head = h;
- m->chs_end.cs = MBR_CS (c, s);
}
diff --git a/src/prototypes.h b/src/prototypes.h
index 201f984..3b9bb81 100644
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -32,9 +32,7 @@ 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);
+void mbr_entry_from_gpt_entry(MBR_entry *m, GPT_header *h, GPT_entry *g, int bootable, uint8_t type);
/* show.c */
void show(DISK *d);
/* entry.c */
diff --git a/src/show.c b/src/show.c
index 20decd1..aa1123a 100644
--- a/src/show.c
+++ b/src/show.c
@@ -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);
diff --git a/src/sync.c b/src/sync.c
index 1b0638b..38bb84f 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -8,37 +8,59 @@ sync_tables (DISK * d)
uint8_t mbuf[512];
GPT_headers h;
int i;
- GUID guid_ext3=GUID_TYPE_LINUX_EXT3;
- GUID guid_swap=GUID_TYPE_LINUX_SWAP;
- int me=0;
+ GUID guid_ext3 = GUID_TYPE_LINUX_EXT3;
+ GUID guid_swap = GUID_TYPE_LINUX_SWAP;
+ GUID guid_hfs = GUID_TYPE_APPLE_HFS;
+ GUID guid_efi = GUID_TYPE_SYSTEM;
+ int mbr_entry = 0;
+ int seen_linux = 0;
disk_read (d, mbuf, 0, 1);
m = (MBR *) mbuf;
- h=headers_get(d);
-
- mbr_set_entry0_from_gpt_header(&m->entry[me++],&h.header);
+ h = headers_get (d);
for (i = 0; i < h.header.n_partition_entries; ++i)
{
- GPT_entry e = entry_read (d, &h.header, i);
- if (!guid_cmp(&e.type,&guid_swap)) {
- mbr_entry_from_gpt_entry (&m->entry[me++],&e,(me==1),MBR_PARTITION_TYPE_LINUX);
- } else if (!guid_cmp(&e.type,&guid_ext3)) {
- mbr_entry_from_gpt_entry (&m->entry[me++],&e,(me==1),MBR_PARTITION_TYPE_SWAP);
-
-
- }
- if (me==4) break;
- }
-
- for (i=0;i<me;++i ) {
- if ((m->entry[i].system==MBR_PARTITION_TYPE_SWAP) || (i==(me-1))) {
- mbr_wedge_entry(&m->entry[i]);
- break;
- }
- }
+ GPT_entry e = entry_read (d, &h.header, i);
+ uint8_t type = 0, bootable = 0;
+
+ if (!guid_cmp (&e.type, &guid_efi))
+ {
+ type = MBR_PARTITION_TYPE_EFI;
+ }
+ else if (!guid_cmp (&e.type, &guid_ext3))
+ {
+ type = MBR_PARTITION_TYPE_LINUX;
+ }
+ else if (!guid_cmp (&e.type, &guid_swap))
+ {
+ type = MBR_PARTITION_TYPE_SWAP;
+ }
+ else if (!guid_cmp (&e.type, &guid_hfs))
+ {
+ type = MBR_PARTITION_TYPE_HFS;
+ }
+
+ if ((type == MBR_PARTITION_TYPE_LINUX) && (!seen_linux))
+ {
+ seen_linux++;
+ bootable++;
+ }
+
+ mbr_entry_from_gpt_entry (&m->entry[mbr_entry++], &h.header, &e,
+ bootable, type);
+
+ if (mbr_entry == 4)
+ break;
+ }
+
+ for (; mbr_entry < 4; ++mbr_entry)
+ {
+ memset (&m->entry[mbr_entry], 0, sizeof (MBR_entry));
+ }
+
disk_write (d, mbuf, 0, 1);
diff --git a/src/util.c b/src/util.c
index f59ccb9..1356fd9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -53,10 +53,10 @@ hexdump (FILE * f, uint8_t * data, int s, int l)
}
void
-utf16_to_ascii (void * _u16, int u16_len, void * _u8, int u8_len)
+utf16_to_ascii (void *_u16, int u16_len, void *_u8, int u8_len)
{
- uint16_t *u16=(uint16_t *) _u16;
- uint8_t *u8=(uint8_t *) _u8;
+ uint16_t *u16 = (uint16_t *) _u16;
+ uint8_t *u8 = (uint8_t *) _u8;
u16_len >>= 1;
@@ -83,10 +83,10 @@ utf16_to_ascii (void * _u16, int u16_len, void * _u8, int u8_len)
}
void
-ascii_to_utf16 (void * _u8, int u8_len, void * _u16, int u16_len)
+ascii_to_utf16 (void *_u8, int u8_len, void *_u16, int u16_len)
{
- uint16_t *u16=(uint16_t *) _u16;
- uint8_t *u8=(uint8_t *) _u8;
+ uint16_t *u16 = (uint16_t *) _u16;
+ uint8_t *u8 = (uint8_t *) _u8;
u16_len >>= 1;
@@ -111,7 +111,3 @@ ascii_to_utf16 (void * _u8, int u8_len, void * _u16, int u16_len)
*u16 = 0;
return;
}
-
-
-
-
diff --git a/version-md5sums b/version-md5sums
index b65eb1e..fe0bab8 100644
--- a/version-md5sums
+++ b/version-md5sums
@@ -1 +1,2 @@
745c00d2207e046f159b63dffbfbe491 1.0.1
+95b82ac0870dc040a8a810114160e7c7 1.0.2
diff --git a/version-micro b/version-micro
index d00491f..0cfbf08 100644
--- a/version-micro
+++ b/version-micro
@@ -1 +1 @@
-1
+2