When creating images targeted for SD cards, generating partitions on cylinder boundaries makes no sense, because cylinders heads and sectors have no meaning on this linear storage media. What does have meaning are erase block boundaries, and partitions, especially FAT partitions, should start on erase block boundaries.

Reference:
https://lwn.net/Articles/428584/
https://wiki.linaro.org/WorkingGroups/Kernel/Projects/FlashCardSurvey

The attached patch adds a -l (for aLign) option to ptgen to allow it to generate size-aligned partition starts rather than rounding to cylinder boundaries. Example usage, for the recommended generic case of 4MB erase block SD cards:
ptgen -o ${OUTPUT} -h 255 -s 63 -l 4096 -t c -p ${BOOTSIZE}

--- tools/firmware-utils/src/ptgen.c.orig       2012-08-02 16:42:13.528342554 
-0400
+++ tools/firmware-utils/src/ptgen.c    2012-08-03 11:39:39.592992950 -0400
@@ -56,6 +56,7 @@
 int active = 1;
 int heads = -1;
 int sectors = -1;
+int kb_align = 0;
 struct partinfo parts[4];
 char *filename = NULL;
 
@@ -117,6 +118,11 @@
        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)
 {
@@ -132,8 +138,13 @@
                }
                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);
+               start = sect + sectors;
+               if (kb_align != 0)
+                       start = round_to_kb(start);
+               pte[i].start = cpu_to_le16(start);
+               sect = start + parts[i].size * 2;
+               if (kb_align == 0)
+                       sect = round_to_cyl(sect);
                pte[i].length = cpu_to_le16(len = sect - start);
                to_chs(start, pte[i].chs_start);
                to_chs(start + len - 1, pte[i].chs_end);
@@ -167,7 +178,7 @@
 
 static void usage(char *prog)
 {
-       fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> 
[-a 0..4] [[-t <type>] -p <size>...] \n", prog);
+       fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> 
[-a 0..4] [-l <align kB>] [[-t <type>] -p <size>...] \n", prog);
        exit(1);
 }
 
@@ -177,7 +188,7 @@
        int ch;
        int part = 0;
 
-       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:")) != -1) {
                switch (ch) {
                case 'o':
                        filename = optarg;
@@ -207,6 +218,9 @@
                        if ((active < 0) || (active > 4))
                                active = 0;
                        break;
+               case 'l':
+                       kb_align = (int) strtoul(optarg, NULL, 0) * 2;
+                       break;
                case '?':
                default:
                        usage(argv[0]);

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to