Bug fix: The protective MBR partition for GPT started at block 0 instead of 1
This commit is contained in:
parent
91f5ebb376
commit
d5cd610ac7
@ -72,21 +72,25 @@ static int precompute_gpt(Ecma119Image *t);
|
|||||||
/*
|
/*
|
||||||
* @param flag bit0= img_blocks is start address rather than end address:
|
* @param flag bit0= img_blocks is start address rather than end address:
|
||||||
do not subtract 1
|
do not subtract 1
|
||||||
|
bit1= img_blocks is counted in 512-byte units rather than 2 KiB
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
void iso_compute_cyl_head_sec(uint64_t img_blocks, int hpc, int sph,
|
||||||
uint32_t *end_lba, uint32_t *end_sec,
|
uint32_t *end_lba, uint32_t *end_sec,
|
||||||
uint32_t *end_head, uint32_t *end_cyl, int flag)
|
uint32_t *end_head, uint32_t *end_cyl, int flag)
|
||||||
{
|
{
|
||||||
uint32_t secs;
|
uint64_t secs;
|
||||||
|
|
||||||
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
if(flag & 2)
|
||||||
if (*img_blocks >= 0x40000000)
|
secs = img_blocks;
|
||||||
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
|
||||||
if (flag & 1)
|
|
||||||
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
|
|
||||||
else
|
else
|
||||||
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */
|
secs = img_blocks * 4;
|
||||||
|
if (secs > (uint64_t) 0xfffffffc)
|
||||||
|
secs = 0xfffffffc; /* truncate rather than roll over */
|
||||||
|
if (flag & 1)
|
||||||
|
*end_lba = secs; /* first valid 512-lba */
|
||||||
|
else
|
||||||
|
secs = *end_lba = secs - 1; /* last valid 512-lba */
|
||||||
*end_cyl = secs / (sph * hpc);
|
*end_cyl = secs / (sph * hpc);
|
||||||
secs -= *end_cyl * sph * hpc;
|
secs -= *end_cyl * sph * hpc;
|
||||||
*end_head = secs / sph;
|
*end_head = secs / sph;
|
||||||
@ -165,10 +169,12 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Note: partition_offset and partition_size are counted in 2048 blocks
|
/* @param flag
|
||||||
|
bit1= partition_offset and partition_size are counted in
|
||||||
|
blocks of 512 rather than 2048
|
||||||
*/
|
*/
|
||||||
static int write_mbr_partition_entry(int partition_number, int partition_type,
|
static int write_mbr_partition_entry(int partition_number, int partition_type,
|
||||||
uint32_t partition_offset, uint32_t partition_size,
|
uint64_t partition_offset, uint64_t partition_size,
|
||||||
int sph, int hpc, uint8_t *buf, int flag)
|
int sph, int hpc, uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
@ -178,10 +184,12 @@ static int write_mbr_partition_entry(int partition_number, int partition_type,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
after_end = partition_offset + partition_size;
|
after_end = partition_offset + partition_size;
|
||||||
iso_compute_cyl_head_sec(&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,
|
||||||
iso_compute_cyl_head_sec(&after_end, hpc, sph,
|
1 | (flag & 2));
|
||||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
iso_compute_cyl_head_sec((uint64_t) after_end, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl,
|
||||||
|
(flag & 2));
|
||||||
wpt = buf + 446 + (partition_number - 1) * 16;
|
wpt = buf + 446 + (partition_number - 1) * 16;
|
||||||
|
|
||||||
/* Not bootable */
|
/* Not bootable */
|
||||||
@ -244,7 +252,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
|||||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
|
||||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
|
||||||
/* 1) Zero-fill 446-510 */
|
/* 1) Zero-fill 446-510 */
|
||||||
@ -308,9 +316,9 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
|||||||
uint32_t start_lba, start_sec, start_head, start_cyl;
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
iso_compute_cyl_head_sec(&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(&img_blocks, hpc, sph,
|
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
|
||||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
wpt = buf + 446;
|
wpt = buf + 446;
|
||||||
|
|
||||||
@ -805,7 +813,7 @@ int iso_quick_gpt_entry(Ecma119Image *t,
|
|||||||
|
|
||||||
|
|
||||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||||
uint32_t start_block, uint32_t block_count,
|
uint64_t start_block, uint64_t block_count,
|
||||||
uint8_t type_byte, uint8_t status_byte,
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
int desired_slot)
|
int desired_slot)
|
||||||
{
|
{
|
||||||
@ -1126,10 +1134,11 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
|||||||
|
|
||||||
/* <<< Dummy mock-up */
|
/* <<< Dummy mock-up */
|
||||||
if (t->mbr_req_count <= 0) {
|
if (t->mbr_req_count <= 0) {
|
||||||
ret = iso_quick_mbr_entry(t, 0, 0, 0xee, 0, 0);
|
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0, 0xee, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = iso_quick_mbr_entry(t, 100, 0, 0x0c, 0x80, 1);
|
ret = iso_quick_mbr_entry(t, ((uint64_t) 100) * 4, (uint64_t) 0,
|
||||||
|
0x0c, 0x80, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1158,7 +1167,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
|||||||
t->mbr_req[i]->block_count = t->mbr_req[i + 1]->start_block -
|
t->mbr_req[i]->block_count = t->mbr_req[i + 1]->start_block -
|
||||||
t->mbr_req[i]->start_block;
|
t->mbr_req[i]->start_block;
|
||||||
else
|
else
|
||||||
t->mbr_req[i]->block_count = img_blocks -
|
t->mbr_req[i]->block_count = ((uint64_t) img_blocks) * 4 -
|
||||||
t->mbr_req[i]->start_block;
|
t->mbr_req[i]->start_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,7 +1204,7 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
|||||||
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte,
|
ret = write_mbr_partition_entry(i + 1, (int) t->mbr_req[q]->type_byte,
|
||||||
t->mbr_req[q]->start_block, t->mbr_req[q]->block_count,
|
t->mbr_req[q]->start_block, t->mbr_req[q]->block_count,
|
||||||
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;
|
||||||
buf[446 + i * 16] = t->mbr_req[q]->status_byte;
|
buf[446 + i * 16] = t->mbr_req[q]->status_byte;
|
||||||
@ -1577,7 +1586,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
if (t->partition_offset == 0) {
|
if (t->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, 0, img_blocks,
|
ret = write_mbr_partition_entry(1, 0x83,
|
||||||
|
(uint64_t) 0, (uint64_t) img_blocks,
|
||||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
buf, 0);
|
buf, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1612,7 +1622,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
buf, t->appended_partitions[i][0] == 0);
|
buf, t->appended_partitions[i][0] == 0);
|
||||||
} else {
|
} else {
|
||||||
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||||
t->appended_part_start[i], t->appended_part_size[i],
|
(uint64_t) t->appended_part_start[i],
|
||||||
|
(uint64_t) t->appended_part_size[i],
|
||||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
buf, 0);
|
buf, 0);
|
||||||
}
|
}
|
||||||
@ -2248,7 +2259,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
if (t->prep_partition != NULL || t->fat || will_have_gpt ||
|
if (t->prep_partition != NULL || t->fat || will_have_gpt ||
|
||||||
t->mbr_req_count > 0)
|
t->mbr_req_count > 0)
|
||||||
return ISO_BOOT_MBR_OVERLAP;
|
return ISO_BOOT_MBR_OVERLAP;
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) 0, (uint32_t) 0,
|
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0,
|
||||||
0x96, 0x80, 0);
|
0x96, 0x80, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -2263,21 +2274,25 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
|
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
|
||||||
/* Protecting MBR entry for ISO start or whole ISO */
|
/* Protecting MBR entry for ISO start or whole ISO */
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset,
|
ret = iso_quick_mbr_entry(t, will_have_gpt ? (uint64_t) 1 :
|
||||||
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0, 0);
|
((uint64_t) t->partition_offset) * 4,
|
||||||
|
(uint64_t) 0,
|
||||||
|
will_have_gpt ? 0xee : 0xcd, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (t->prep_part_size > 0) {
|
if (t->prep_part_size > 0) {
|
||||||
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41,
|
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
|
||||||
0, 0);
|
((uint64_t) t->prep_part_size) * 4,
|
||||||
|
0x41, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
t->curblock += t->prep_part_size;
|
t->curblock += t->prep_part_size;
|
||||||
}
|
}
|
||||||
if (t->prep_part_size > 0 || t->fat) {
|
if (t->prep_part_size > 0 || t->fat) {
|
||||||
/* FAT partition or protecting MBR entry for ISO end */
|
/* FAT partition or protecting MBR entry for ISO end */
|
||||||
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0,
|
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4,
|
||||||
|
(uint64_t) 0,
|
||||||
t->fat ? 0x0c : 0xcd, 0, 0);
|
t->fat ? 0x0c : 0xcd, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -78,13 +78,13 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
|||||||
*/
|
*/
|
||||||
struct iso_mbr_partition_request {
|
struct iso_mbr_partition_request {
|
||||||
|
|
||||||
/* Always given in blocks of 2 KiB */
|
/* Always given in blocks of 512 bytes */
|
||||||
uint32_t start_block;
|
uint64_t start_block;
|
||||||
|
|
||||||
/* A block count of 0 means that the partition reaches up to the start of
|
/* A block count of 0 means that the partition reaches up to the start of
|
||||||
the next one.
|
the next one.
|
||||||
*/
|
*/
|
||||||
uint32_t block_count;
|
uint64_t block_count;
|
||||||
|
|
||||||
/* Partition type */
|
/* Partition type */
|
||||||
uint8_t type_byte;
|
uint8_t type_byte;
|
||||||
@ -115,7 +115,7 @@ int iso_register_mbr_entry(Ecma119Image *t,
|
|||||||
name and type are 0-terminated strings, which may get silently truncated.
|
name and type are 0-terminated strings, which may get silently truncated.
|
||||||
*/
|
*/
|
||||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||||
uint32_t start_block, uint32_t block_count,
|
uint64_t start_block, uint64_t block_count,
|
||||||
uint8_t type_byte, uint8_t status_byte,
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
int desired_slot);
|
int desired_slot);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user