Thomas Schmitt
2015-Feb-20 07:20 UTC
[syslinux] isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
Hi, my proposal is based on a mathematical proof (see mail before) and yours is correct too. They cannot but match. Let's inspect your examples: Ady wrote:> ISO size: 1'085'736'960 bytes ( > 1GiB)This are exactly 132 cylinders of 255x63. 132 is divisible by 4. So there is no padding needed.> Cylinders (1st attempt)=132 > [...] > 2120580 / 4 = 530145, so the answer is "yes".My calculation gets align_factor = 4. So isohybrid would pad up to quadruple cylinders. Well, 132 is already such a quadruple.> When comparing your code with my suggested calculation, I see that your > conditionals do not account for the ISO image size, but only for > "Heads" and "Sectors_per_track".The existing code in isohybrid already handles the size for padding up to a target granularity. Currently the target is always a single cylinder. My new code only decides about the granularity of 1, 2, or 4 cylinders.> ISO size: 1'085'736'960 bytes+2048 bytes > [...] > 136 * 255 * 63 = 2184840 > 2184840 / 4 = 546210 so the answer is "yes".My proposal: Granularity is still 4 cylinders. Image size is 132.0002489884843 cylinders. So the target size is the next multiple of 4: 136 cylinders. Your algorithm is more complicated than mine, because it tries to do the part of the job which is already implemented in isohybrid: cylsize = head * sector * 512; frac = isostat.st_size % cylsize; padding = (frac > 0) ? cylsize - frac : 0; isostat.st_size is the ISO image size in bytes. cylsize is the current granularity of 1 cylinder. My proposal has 1, 2, or 4 cylinders instead. cylsize = head * sector * 512; align_cylsize = cylsize * align_factor; frac = isostat.st_size % align_cylsize; padding = (frac > 0) ? align_cylsize - frac : 0; Numbers inserted: cylsize = 255 * 63 * 512 = 8225280 align_cylsize = 8225280 * 4 = 32901120 frac = (1085736960 + 2048) % 32901120 = 2048 padding = 32901120 - 2048 = 32899072 This means that the image will be padded up by nearly 32 MB to 1085736960 + 2048 + 32899072 = 1118638080 bytes. This are 1118638080 / 255 / 63 / 512 = 136 cylinders. Same result as yours. Have a nice day :) Thomas
Ady
2015-Feb-20 08:36 UTC
[syslinux] isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
> > Same result as yours. > > > Have a nice day :) > > Thomas >I was under the impression (apparently the wrong one) that your pseudo-code was adding 4 cylinders to the first example, from 132 to 136, which would be non-optimal. Since I am not a developer, I believe you when you say that such jump won't happen :). Perhaps the code will be more clear to me when I'll see it included in isohybrid.c (and/or in the Perl variant). I understand the math. Your code is focused on the valid values for the amount of cylinders, and my focus was on the padding ranges. Of course they are equivalent. Now, I have a question: what about the "offset" parameter? How it modifies our assumptions and calculations if the "offset" parameter is not zero? For example, in isohybrid.c I see: 660: psize = c * head * sector - offset; and 1135: psize = isosize / 512; among others. There are partial equivalents in the Perl variant. Since I am not a developer, I am not really asking about the code. My interest is about how the "partition offset" parameter ([0, 64]) could affect the optimization we have been discussing. Regards, Ady.> _______________________________________________ > Syslinux mailing list > Submissions to Syslinux at zytor.com > Unsubscribe or set options at: > http://www.zytor.com/mailman/listinfo/syslinux >
Thomas Schmitt
2015-Feb-20 10:29 UTC
[syslinux] isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
Hi,> Now, I have a question: what about the "offset" parameter? How it > modifies our assumptions and calculations if the "offset" parameter is > not zero?The offset influences only the start address of the partition. The alignment goal is about the end address. So these concepts are nearly independent. Of course, partition start must be smaller than partition end. But a mountable ISO cannot be smaller than 18 * 2048 bytes = 72 in units of -o. And -o is limited to 64. (Not so clear why ...) A non-zero offset makes the MBR ISO partition unmountable unless the ISO is specially prepared by a second superblock and directory tree. So isohybrid option -o is for experts, anyway. The ISO partition covers the block range at least up to the end of the ISO filesystem and includes the padding. Even if it is not mountable, it still protects the ISO filesystem from being regarded as free space by partition editors.> Perhaps the code will > be more clear to me when I'll see it included in isohybrid.cThis is a patch against http://git.kernel.org/cgit/boot/syslinux/syslinux.git/plain/utils/isohybrid.c It roughly compiles here. (Up to missing uuid_generate.) ------------------------------------------------------------------------ --- isohybrid.c 2015-02-20 10:43:49.000000000 +0100 +++ isohybrid_test.c 2015-02-20 11:01:33.000000000 +0100 @@ -947,7 +947,7 @@ main(int argc, char *argv[]) int i = 0; FILE *fp = NULL; uint8_t *buf = NULL, *bufz = NULL; - int cylsize = 0, frac = 0; + int cylsize = 0, frac = 0, align_factor, align_cylsize; size_t orig_gpt_size, free_space, gpt_size; struct iso_primary_descriptor descriptor; @@ -1058,9 +1058,20 @@ main(int argc, char *argv[]) isosize = lendian_int(descriptor.size) * lendian_short(descriptor.block_size); free_space = isostat.st_size - isosize; + /* Making sure that the resulting image size is divisible by 2048. + (Can waste nearly 32 MB. Should be done on user request only.) + */ + if ((head * sector) % 4 == 0) + align_factor = 1; + else if ((head * sector) % 2 == 0) + align_factor = 2; + else + align_factor = 4; + cylsize = head * sector * 512; - frac = isostat.st_size % cylsize; - padding = (frac > 0) ? cylsize - frac : 0; + align_cylsize = cylsize * align_factor; + frac = isostat.st_size % align_cylsize; + padding = (frac > 0) ? align_cylsize - frac : 0; if (mode & VERBOSE) printf("imgsize: %zu, padding: %d\n", (size_t)isostat.st_size, padding); ------------------------------------------------------------------------ I wrapped the essential code into a standalone program for playing with a few numbers: -h 255 -s 63 , ISO size 1085739008 : align_factor= 4 , padding= 32899072 , image size= 136.000000 cylinders -h 252 -s 63 , ISO size 1085739008 : align_factor= 1 , padding= 3481600 , image size= 134.000000 cylinders -h 128 -s 32 , ISO size 1085739008 : align_factor= 1 , padding= 585728 , image size= 518.000000 cylinders "padding" is the actual waste. Well, ISO size 1085739008 was designed to let -h 255 -s 63 look bad. Let's choose some random size around 1.5 GB: 2048 * 723452 -h 255 -s 63 , ISO size 1481629696 : align_factor= 4 , padding= 31821824 , image size= 184.000000 cylinders -h 252 -s 63 , ISO size 1481629696 : align_factor= 1 , padding= 5888000 , image size= 183.000000 cylinders -h 128 -s 32 , ISO size 1481629696 : align_factor= 1 , padding= 1056768 , image size= 707.000000 cylinders Bad luck again. I swear i just toggled a 7 and then blindly 5 digits for the "random" number. More tries -h 255 -s 63 , ISO size 1478760448 : align_factor= 4 , padding= 1789952 , image size= 180.000000 cylinders -h 255 -s 63 , ISO size 1630908416 : align_factor= 4 , padding= 14147584 , image size= 200.000000 cylinders I expect the average waste to be a bit less than 16 MB. Have a nice day :) Thomas
Reasonably Related Threads
- isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
- isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
- isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
- isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox
- isohybrid and ISO images whose size is not a multiple of 2048 bytes vs. VirtualBox