From c47167058aced3f7ffa1ef84b6573fbea5a9110a Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 10 May 2015 09:34:45 +0200 Subject: [PATCH] Improved handling of cylinder alignment if the resulting image size size is not divisible by 2048. Old behavior was to not align. New is to pad up by a few blocks of 512 bytes. --- doc/susp_aaip_isofs_names.txt | 4 ++-- libisofs/ecma119.c | 1 + libisofs/ecma119.h | 6 ++++++ libisofs/make_isohybrid_mbr.c | 3 ++- libisofs/system_area.c | 30 +++++++++++++++++------------- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/doc/susp_aaip_isofs_names.txt b/doc/susp_aaip_isofs_names.txt index 77fba28..cf2dd09 100644 --- a/doc/susp_aaip_isofs_names.txt +++ b/doc/susp_aaip_isofs_names.txt @@ -128,7 +128,7 @@ Name: Purpose: Records the IsoHfsplusBlessings blessing of a IsoNode as defined - in libisofs.h. At image load time, this info shall be converted back + in libisofs.h. At image load time, this info may be converted back into a relation between IsoImage and IsoNode so that it is available for the HFS+ writer when a new ISO 9660 / HFS+ image gets produced. @@ -152,7 +152,7 @@ Name: Purpose: Records the iso_hfsplus_xinfo_data information as defined in libisofs.h. - At image load time, this info shall be converted back into an xinfo + At image load time, this info may be converted back into an xinfo attachment for iso_hfsplus_xinfo_func so that it is available for the HFS+ writer when a new ISO 9660 / HFS+ image gets produced. diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 1b54fe8..fb43c3c 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -2481,6 +2481,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img) target->wthread_is_running = 0; + target->post_iso_part_pad = 0; target->prep_part_size = 0; target->efi_boot_part_size = 0; target->efi_boot_part_filesrc = NULL; diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 23cc223..a7b514d 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -798,6 +798,12 @@ struct ecma119_image struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX]; int mbr_req_count; + /* Number of bytes which have to be added after the cylinder aligned end + of the overall ISO partition because clinder size is not a multiple + of 2048 + */ + int post_iso_part_pad; + uint32_t prep_part_size; /* GPT description. To be composed during IsoImageWriter diff --git a/libisofs/make_isohybrid_mbr.c b/libisofs/make_isohybrid_mbr.c index b137950..2f29655 100644 --- a/libisofs/make_isohybrid_mbr.c +++ b/libisofs/make_isohybrid_mbr.c @@ -590,7 +590,8 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t, part_offset = 1; } - hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4; + hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4 - + t->post_iso_part_pad / 512; boot_lba = t->bootsrc[0]->sections[0].block; head_count = t->partition_heads_per_cyl; diff --git a/libisofs/system_area.c b/libisofs/system_area.c index e245228..943dd2a 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -329,21 +329,24 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc, /* @param flag bit0= zeroize partitions entries 2, 3, 4 - bit0= UEFI protective MBR: start LBA = 1 + bit1= UEFI protective MBR: start LBA = 1 */ static -int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset, +int iso_offset_partition_start(uint32_t img_blocks, int post_part_pad, + uint32_t partition_offset, int sph, int hpc, uint8_t *buf, int flag) { uint8_t *wpt; uint32_t end_lba, end_sec, end_head, end_cyl; uint32_t start_lba, start_sec, start_head, start_cyl; + uint64_t img_hd_blocks; int i; iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph, &start_lba, &start_sec, &start_head, &start_cyl, 1); - iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph, - &end_lba, &end_sec, &end_head, &end_cyl, 0); + img_hd_blocks = ((uint64_t) img_blocks) * 4 - post_part_pad / 512; + iso_compute_cyl_head_sec(img_hd_blocks, hpc, sph, + &end_lba, &end_sec, &end_head, &end_cyl, 2); if (flag & 2) { start_lba = 1; start_sec = 2; @@ -1863,10 +1866,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) return ret; } else if (t->opts->partition_offset == 0) { /* Re-write partion entry 1 : start at 0, type Linux */ - ret = write_mbr_partition_entry(1, 0x83, - (uint64_t) 0, (uint64_t) img_blocks, + blk = ((uint64_t) img_blocks) * 4 - t->post_iso_part_pad / 512; + ret = write_mbr_partition_entry(1, 0x83, (uint64_t) 0, blk, t->partition_secs_per_head, t->partition_heads_per_cyl, - buf, 0); + buf, 2); if (ret < 0) return ret; } @@ -1884,7 +1887,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) } else { mbrp1_blocks = img_blocks; } - ret = iso_offset_partition_start(mbrp1_blocks, + ret = iso_offset_partition_start(mbrp1_blocks, t->post_iso_part_pad, t->opts->partition_offset, t->partition_secs_per_head, t->partition_heads_per_cyl, buf, @@ -1936,7 +1939,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) /* Choose *heads_per_cyl so that - *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512 - *heads_per_cyl * secs_per_head is divisible by 4 - - it is as small as possible (to reduce aligment overhead) + - it is as small as possible (to reduce alignment overhead) - it is <= 255 @return 1= success , 0= cannot achieve goals */ @@ -2053,14 +2056,15 @@ int iso_align_isohybrid(Ecma119Image *t, int flag) frac = imgsize - ((off_t) img_blocks) * (off_t) 2048; if (frac == 0) {ret = ISO_SUCCESS; goto ex;} + t->post_iso_part_pad = 0; if (frac % 2048) { + t->post_iso_part_pad = 2048 - frac % 2048; sprintf(msg, - "Cylinder size %d not divisible by 2048. Cannot align partition.", - (int) cylsize); + "Cylinder aligned image size is not divisible by 2048. Have to add %d bytes.", + t->post_iso_part_pad); iso_msgs_submit(0, msg, 0, "WARNING", 0); - } else { - t->opts->tail_blocks += frac / 2048; } + t->opts->tail_blocks += (frac + 2047) / 2048; ret = ISO_SUCCESS; ex:; LIBISO_FREE_MEM(msg);