Bug fix: isohybrid image size was not aligned to cylinder boundary.
Now the cylinder size gets adjusted if the image does not fit into 1024 cyl.
This commit is contained in:
parent
de3e21629f
commit
e035146e01
@ -1108,7 +1108,35 @@ int zero_writer_free_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
int tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Image *target;
|
||||||
|
struct iso_zero_writer_data_struct *data;
|
||||||
|
|
||||||
|
target = writer->target;
|
||||||
|
ret = iso_align_isohybrid(target, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||||
|
if (data->num_blocks != target->tail_blocks) {
|
||||||
|
iso_msg_debug(target->image->id,
|
||||||
|
"Aligned image size for isohybrid by %d blocks",
|
||||||
|
target->tail_blocks - data->num_blocks);
|
||||||
|
data->num_blocks = target->tail_blocks;
|
||||||
|
}
|
||||||
|
if (target->tail_blocks <= 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
ret = zero_writer_compute_data_blocks(writer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag bit0= use tail_writer_compute_data_blocks rather than
|
||||||
|
zero_writer_compute_data_blocks
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
||||||
{
|
{
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
struct iso_zero_writer_data_struct *data;
|
struct iso_zero_writer_data_struct *data;
|
||||||
@ -1124,7 +1152,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
|||||||
}
|
}
|
||||||
data->num_blocks = num_blocks;
|
data->num_blocks = num_blocks;
|
||||||
|
|
||||||
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
if (flag & 1) {
|
||||||
|
writer->compute_data_blocks = tail_writer_compute_data_blocks;
|
||||||
|
} else {
|
||||||
|
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
||||||
|
}
|
||||||
writer->write_vol_desc = zero_writer_write_vol_desc;
|
writer->write_vol_desc = zero_writer_write_vol_desc;
|
||||||
writer->write_data = zero_writer_write_data;
|
writer->write_data = zero_writer_write_data;
|
||||||
writer->free_data = zero_writer_free_data;
|
writer->free_data = zero_writer_free_data;
|
||||||
@ -1695,9 +1727,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->partition_secs_per_head = opts->partition_secs_per_head;
|
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||||
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||||
if (target->partition_secs_per_head == 0)
|
if (target->partition_secs_per_head == 0)
|
||||||
target->partition_secs_per_head = 63;
|
target->partition_secs_per_head = 32;
|
||||||
if (target->partition_heads_per_cyl == 0)
|
if (target->partition_heads_per_cyl == 0)
|
||||||
target->partition_heads_per_cyl = 255;
|
target->partition_heads_per_cyl = 64;
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
target->partition_root = NULL;
|
target->partition_root = NULL;
|
||||||
target->partition_l_table_pos = 0;
|
target->partition_l_table_pos = 0;
|
||||||
@ -1893,11 +1925,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
|
|
||||||
|
|
||||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||||
if (target->tail_blocks > 0) {
|
ret = zero_writer_create(target, target->tail_blocks, 1);
|
||||||
ret = zero_writer_create(target, target->tail_blocks);
|
if (ret < 0)
|
||||||
if (ret < 0)
|
goto target_cleanup;
|
||||||
goto target_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
ret = checksum_writer_create(target);
|
ret = checksum_writer_create(target);
|
||||||
@ -1951,8 +1981,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (i == el_torito_writer_index)
|
if (i == el_torito_writer_index)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Exposing address of data start to IsoWriteOpts iand memorizing
|
/* Exposing address of data start to IsoWriteOpts and memorizing
|
||||||
this address for for all files which have no block address:
|
this address for all files which have no block address:
|
||||||
symbolic links, device files, empty data files.
|
symbolic links, device files, empty data files.
|
||||||
filesrc_writer_compute_data_blocks() and filesrc_writer_write_data()
|
filesrc_writer_compute_data_blocks() and filesrc_writer_write_data()
|
||||||
will account resp. write this single block.
|
will account resp. write this single block.
|
||||||
|
@ -3120,6 +3120,8 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
|||||||
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
|
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
|
||||||
* if the type of boot image is known.
|
* if the type of boot image is known.
|
||||||
*
|
*
|
||||||
|
* @param bootimg
|
||||||
|
* The image to set options on
|
||||||
* @param options
|
* @param options
|
||||||
* bitmask style flag. The following values are defined:
|
* bitmask style flag. The following values are defined:
|
||||||
*
|
*
|
||||||
@ -3147,8 +3149,6 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
|||||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||||
* IMPORTANT: The application has to take care that the image
|
* IMPORTANT: The application has to take care that the image
|
||||||
* on media gets padded up to the next full MB.
|
* on media gets padded up to the next full MB.
|
||||||
* @param bootimg
|
|
||||||
* The image to set options on
|
|
||||||
* @param flag
|
* @param flag
|
||||||
* Reserved for future usage, set to 0.
|
* Reserved for future usage, set to 0.
|
||||||
* @return
|
* @return
|
||||||
|
@ -386,21 +386,19 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
int part_offset, int part_number, int fs_type,
|
int part_offset, int part_number, int fs_type,
|
||||||
uint8_t *buf, int flag)
|
uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint32_t spc, id, part, nominal_part_size;
|
uint32_t id, part, nominal_part_size;
|
||||||
off_t hd_img_blocks, hd_boot_lba;
|
off_t hd_img_blocks, hd_boot_lba;
|
||||||
char *wpt;
|
char *wpt;
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
/* Pad image_size to a multiple of sector_count*head_count
|
|
||||||
*/
|
|
||||||
spc = head_count * sector_count;
|
|
||||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||||
if (hd_img_blocks % spc) {
|
|
||||||
hd_img_blocks += spc - (hd_img_blocks % spc);
|
/* Padding of image_size to a multiple of sector_count*head_count
|
||||||
*img_blocks = hd_img_blocks / 4 + !!(hd_img_blocks % 4);
|
happens already at compute time and is implemented by
|
||||||
}
|
an appropriate increase of Ecma119Image->tail_blocks.
|
||||||
|
*/
|
||||||
|
|
||||||
wpt = (char *) buf + 432;
|
wpt = (char *) buf + 432;
|
||||||
|
|
||||||
|
@ -809,3 +809,100 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 <= 255
|
||||||
|
@return 1= success , 0= cannot achieve goals
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int try_sph(off_t imgsize, int secs_per_head, int *heads_per_cyl, int flag)
|
||||||
|
{
|
||||||
|
off_t hd_blocks, hpc;
|
||||||
|
|
||||||
|
hd_blocks= imgsize / 512;
|
||||||
|
hpc = hd_blocks / secs_per_head / 1024;
|
||||||
|
if (hpc * secs_per_head * 1024 < hd_blocks)
|
||||||
|
hpc++;
|
||||||
|
if ((secs_per_head % 4) == 0) {
|
||||||
|
;
|
||||||
|
} else if ((secs_per_head % 2) == 0) {
|
||||||
|
hpc += (hpc % 2);
|
||||||
|
} else if(hpc % 4) {
|
||||||
|
hpc += 4 - (hpc % 4);
|
||||||
|
}
|
||||||
|
if (hpc > 255)
|
||||||
|
return 0;
|
||||||
|
*heads_per_cyl = hpc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||||
|
{
|
||||||
|
int sa_type, ret;
|
||||||
|
uint32_t img_blocks;
|
||||||
|
off_t imgsize, cylsize = 0, frac;
|
||||||
|
|
||||||
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||||
|
if (sa_type != 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
img_blocks = t->curblock;
|
||||||
|
imgsize = ((off_t) img_blocks) * (off_t) 2048;
|
||||||
|
if ((t->system_area_options & 3)
|
||||||
|
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||||
|
* 1024) * (off_t) 512 < imgsize) {
|
||||||
|
/* Choose small values which can represent the image size */
|
||||||
|
/* First try 32 sectors per head */
|
||||||
|
ret = try_sph(imgsize, 32, &(t->partition_heads_per_cyl), 0);
|
||||||
|
if (ret == 1) {
|
||||||
|
t->partition_secs_per_head = 32;
|
||||||
|
} else {
|
||||||
|
/* Did not work with 32. Try 63 */
|
||||||
|
t->partition_secs_per_head = 63;
|
||||||
|
ret = try_sph(imgsize, 63, &(t->partition_heads_per_cyl), 0);
|
||||||
|
if (ret != 1)
|
||||||
|
t->partition_heads_per_cyl = 255;
|
||||||
|
}
|
||||||
|
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head *512;
|
||||||
|
frac = imgsize % cylsize;
|
||||||
|
iso_msg_debug(t->image->id,
|
||||||
|
"Automatically adjusted MBR geometry to %d/%d/%d",
|
||||||
|
(int) (imgsize / cylsize + !!frac),
|
||||||
|
t->partition_heads_per_cyl, t->partition_secs_per_head);
|
||||||
|
}
|
||||||
|
|
||||||
|
cylsize = 0;
|
||||||
|
if (sa_type == 0 && t->catalog != NULL &&
|
||||||
|
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
||||||
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
|
*/
|
||||||
|
if (img_blocks >= 0x40000000)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
cylsize = 64 * 32 * 512;
|
||||||
|
} else if (sa_type == 0 && (t->system_area_options & 2)) {
|
||||||
|
/* Patch externally provided system area as isohybrid MBR */
|
||||||
|
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||||
|
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||||
|
and externally provided System Area.
|
||||||
|
*/
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||||
|
* 512;
|
||||||
|
}
|
||||||
|
if (cylsize == 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
frac = imgsize % cylsize;
|
||||||
|
imgsize += (frac > 0 ? cylsize - frac : 0);
|
||||||
|
|
||||||
|
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
|
||||||
|
if (frac == 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
t->tail_blocks += frac / 2048 + !!(frac % 2048);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
@ -46,6 +46,11 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust t->tail_blocks to the eventual alignment needs of isohybrid booting.
|
||||||
|
*/
|
||||||
|
int iso_align_isohybrid(Ecma119Image *t, int flag);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the necessary ELF information from the first MIPS boot file.
|
* Read the necessary ELF information from the first MIPS boot file.
|
||||||
|
Loading…
Reference in New Issue
Block a user