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.
This commit is contained in:
Thomas Schmitt 2015-05-10 09:34:45 +02:00
parent 5a3d84cbbb
commit c47167058a
5 changed files with 28 additions and 16 deletions

View File

@ -128,7 +128,7 @@ Name:
Purpose: Purpose:
Records the IsoHfsplusBlessings blessing of a IsoNode as defined 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 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. the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
@ -152,7 +152,7 @@ Name:
Purpose: Purpose:
Records the iso_hfsplus_xinfo_data information as defined in libisofs.h. 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 attachment for iso_hfsplus_xinfo_func so that it is available for
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced. the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.

View File

@ -2481,6 +2481,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->wthread_is_running = 0; target->wthread_is_running = 0;
target->post_iso_part_pad = 0;
target->prep_part_size = 0; target->prep_part_size = 0;
target->efi_boot_part_size = 0; target->efi_boot_part_size = 0;
target->efi_boot_part_filesrc = NULL; target->efi_boot_part_filesrc = NULL;

View File

@ -798,6 +798,12 @@ struct ecma119_image
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX]; struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
int mbr_req_count; 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; uint32_t prep_part_size;
/* GPT description. To be composed during IsoImageWriter /* GPT description. To be composed during IsoImageWriter

View File

@ -590,7 +590,8 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
part_offset = 1; 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; boot_lba = t->bootsrc[0]->sections[0].block;
head_count = t->partition_heads_per_cyl; head_count = t->partition_heads_per_cyl;

View File

@ -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 /* @param flag bit0= zeroize partitions entries 2, 3, 4
bit0= UEFI protective MBR: start LBA = 1 bit1= UEFI protective MBR: start LBA = 1
*/ */
static 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) int sph, int hpc, uint8_t *buf, int flag)
{ {
uint8_t *wpt; uint8_t *wpt;
uint32_t end_lba, end_sec, end_head, end_cyl; uint32_t end_lba, end_sec, end_head, end_cyl;
uint32_t start_lba, start_sec, start_head, start_cyl; uint32_t start_lba, start_sec, start_head, start_cyl;
uint64_t img_hd_blocks;
int i; int i;
iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph, iso_compute_cyl_head_sec((uint64_t) partition_offset, hpc, sph,
&start_lba, &start_sec, &start_head, &start_cyl, 1); &start_lba, &start_sec, &start_head, &start_cyl, 1);
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph, img_hd_blocks = ((uint64_t) img_blocks) * 4 - post_part_pad / 512;
&end_lba, &end_sec, &end_head, &end_cyl, 0); iso_compute_cyl_head_sec(img_hd_blocks, hpc, sph,
&end_lba, &end_sec, &end_head, &end_cyl, 2);
if (flag & 2) { if (flag & 2) {
start_lba = 1; start_lba = 1;
start_sec = 2; start_sec = 2;
@ -1863,10 +1866,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ret; return ret;
} else if (t->opts->partition_offset == 0) { } else if (t->opts->partition_offset == 0) {
/* Re-write partion entry 1 : start at 0, type Linux */ /* Re-write partion entry 1 : start at 0, type Linux */
ret = write_mbr_partition_entry(1, 0x83, blk = ((uint64_t) img_blocks) * 4 - t->post_iso_part_pad / 512;
(uint64_t) 0, (uint64_t) img_blocks, ret = write_mbr_partition_entry(1, 0x83, (uint64_t) 0, blk,
t->partition_secs_per_head, t->partition_heads_per_cyl, t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0); buf, 2);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -1884,7 +1887,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
} else { } else {
mbrp1_blocks = img_blocks; 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->opts->partition_offset,
t->partition_secs_per_head, t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 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 /* Choose *heads_per_cyl so that
- *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512 - *heads_per_cyl * secs_per_head * 1024 >= imgsize / 512
- *heads_per_cyl * secs_per_head is divisible by 4 - *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 - it is <= 255
@return 1= success , 0= cannot achieve goals @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; frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
if (frac == 0) if (frac == 0)
{ret = ISO_SUCCESS; goto ex;} {ret = ISO_SUCCESS; goto ex;}
t->post_iso_part_pad = 0;
if (frac % 2048) { if (frac % 2048) {
t->post_iso_part_pad = 2048 - frac % 2048;
sprintf(msg, sprintf(msg,
"Cylinder size %d not divisible by 2048. Cannot align partition.", "Cylinder aligned image size is not divisible by 2048. Have to add %d bytes.",
(int) cylsize); t->post_iso_part_pad);
iso_msgs_submit(0, msg, 0, "WARNING", 0); 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; ret = ISO_SUCCESS;
ex:; ex:;
LIBISO_FREE_MEM(msg); LIBISO_FREE_MEM(msg);