diff options
| -rw-r--r-- | src/disk.c | 15 | ||||
| -rw-r--r-- | src/gpt.c | 200 | ||||
| -rw-r--r-- | src/gpt.h | 1 | ||||
| -rw-r--r-- | src/header.c | 80 | ||||
| -rw-r--r-- | src/modify.c | 44 | ||||
| -rw-r--r-- | src/pmbr.c | 60 | ||||
| -rw-r--r-- | src/prototypes.h | 4 | ||||
| -rw-r--r-- | src/show.c | 2 | ||||
| -rw-r--r-- | src/sync.c | 68 | ||||
| -rw-r--r-- | src/util.c | 16 | ||||
| -rw-r--r-- | version-md5sums | 1 | ||||
| -rw-r--r-- | version-micro | 2 | 
12 files changed, 263 insertions, 230 deletions
@@ -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"); +    } +} @@ -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;  } @@ -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;  } @@ -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 */ @@ -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); @@ -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); @@ -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  | 
