X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=tools%2Ffirmware-utils%2Fsrc%2Fptgen.c;h=8466d35bcc3f5364c318594b092ead2aae9e95b9;hb=997fed94e328315c6055331dbd8d6d4b56d1b454;hp=ce93016667e1715457650f5bb34224ccdcc5abe1;hpb=41ac34a2a29b21ff42c51336db6df34c134eb658;p=openwrt%2Fstaging%2Frmilecki.git diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c index ce93016667e..8466d35bcc3 100644 --- a/tools/firmware-utils/src/ptgen.c +++ b/tools/firmware-utils/src/ptgen.c @@ -1,6 +1,6 @@ /* * ptgen - partition table generator - * Copyright (C) 2006 by Felix Fietkau + * Copyright (C) 2006 by Felix Fietkau * * uses parts of afdisk * Copyright (C) 2002 by David Roetzel @@ -26,25 +26,27 @@ #include #include #include +#include #include #include +#include #if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le16(x) bswap_16(x) +#define cpu_to_le32(x) bswap_32(x) #elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) #else #error unknown endianness! #endif /* Partition table entry */ -struct pte { - unsigned char active; - unsigned char chs_start[3]; - unsigned char type; - unsigned char chs_end[3]; - unsigned int start; - unsigned int length; +struct pte { + uint8_t active; + uint8_t chs_start[3]; + uint8_t type; + uint8_t chs_end[3]; + uint32_t start; + uint32_t length; }; struct partinfo { @@ -56,6 +58,7 @@ int verbose = 0; int active = 1; int heads = -1; int sectors = -1; +int kb_align = 0; struct partinfo parts[4]; char *filename = NULL; @@ -90,7 +93,9 @@ static long to_kbytes(const char *string) { } /* result: number + 1024^(exp) */ - return result * ((2 << ((10 * exp) - 1)) ?: 1); + if (exp == 0) + return result; + return result * (2 << ((10 * exp) - 1)); } /* convert the sector number into a CHS value for the partition table */ @@ -117,8 +122,13 @@ static inline unsigned long round_to_cyl(long sect) { return sect + cyl_size - (sect % cyl_size); } +/* round the sector number up to the kb_align boundary */ +static inline unsigned long round_to_kb(long sect) { + return ((sect - 1) / kb_align + 1) * kb_align; +} + /* check the partition sizes and write the partition table */ -static int gen_ptable(int nr) +static int gen_ptable(uint32_t signature, int nr) { struct pte pte[4]; unsigned long sect = 0; @@ -132,22 +142,33 @@ static int gen_ptable(int nr) } pte[i].active = ((i + 1) == active) ? 0x80 : 0; pte[i].type = parts[i].type; - pte[i].start = cpu_to_le16(start = sect + sectors); - sect = round_to_cyl(start + parts[i].size * 2); - pte[i].length = cpu_to_le16(len = sect - start); + start = sect + sectors; + if (kb_align != 0) + start = round_to_kb(start); + pte[i].start = cpu_to_le32(start); + sect = start + parts[i].size * 2; + if (kb_align == 0) + sect = round_to_cyl(sect); + pte[i].length = cpu_to_le32(len = sect - start); to_chs(start, pte[i].chs_start); to_chs(start + len - 1, pte[i].chs_end); if (verbose) fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long) start * 512, ((long) start + (long) len) * 512, (long) len * 512); printf("%ld\n", ((long) start * 512)); + printf("%ld\n", ((long) len * 512)); } - printf("%ld\n", ((long) (start + len) * 512)); - if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) < 0) { + if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { fprintf(stderr, "Can't open output file '%s'\n",filename); return -1; } + lseek(fd, 440, SEEK_SET); + if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { + fprintf(stderr, "write failed.\n"); + goto fail; + } + lseek(fd, 446, SEEK_SET); if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) { fprintf(stderr, "write failed.\n"); @@ -167,7 +188,7 @@ fail: static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] -h -s -o [-a 0..4] [[-t ] -p ...] \n", prog); + fprintf(stderr, "Usage: %s [-v] -h -s -o [-a 0..4] [-l ] [[-t ] -p ...] \n", prog); exit(1); } @@ -176,8 +197,9 @@ int main (int argc, char **argv) char type = 0x83; int ch; int part = 0; + uint32_t signature = 0x5452574F; /* 'OWRT' */ - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:v")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vl:S:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -207,6 +229,12 @@ int main (int argc, char **argv) if ((active < 0) || (active > 4)) active = 0; break; + case 'l': + kb_align = (int) strtoul(optarg, NULL, 0) * 2; + break; + case 'S': + signature = strtoul(optarg, NULL, 0); + break; case '?': default: usage(argv[0]); @@ -215,6 +243,6 @@ int main (int argc, char **argv) argc -= optind; if (argc || (heads <= 0) || (sectors <= 0) || !filename) usage(argv[0]); - - return gen_ptable(part); + + return gen_ptable(signature, part); }