Experimental macro Libisofs_mjg_boot_for_grub2 for alternative partition layout

This commit is contained in:
Thomas Schmitt 2015-12-27 16:07:27 +01:00
parent 97eec6162c
commit bd25db9283
2 changed files with 142 additions and 27 deletions

View File

@ -400,6 +400,8 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
/* Find out whether GPT and APM are desired /* Find out whether GPT and APM are desired
flag bit0 = register APM and GPT requests in Ecma119Image flag bit0 = register APM and GPT requests in Ecma119Image
bit1 = do not asses and register APM
bit2 = do not register overall GPT partition
*/ */
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
int *apm_count, int flag) int *apm_count, int flag)
@ -453,7 +455,7 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
return ret; return ret;
} }
} }
if (ilx_opts & 256) { if ((ilx_opts & 256) && !(flag & 2)) {
(*apm_count)++; (*apm_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) { if ((flag & 1) && t->bootsrc[i] != NULL) {
/* Register APM entry */ /* Register APM entry */
@ -471,7 +473,9 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
} }
} }
} }
if ((flag & 1) && *gpt_count > 0) { if (*gpt_count > 0 && !(flag & 4))
(*gpt_count)++;
if ((flag & 1) && *gpt_count > 0 && !(flag & 4)) {
/* Register overall GPT partition */ /* Register overall GPT partition */
memset(gpt_name, 0, 72); memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid"); sprintf((char *) gpt_name, "ISOHybrid");

View File

@ -1187,6 +1187,10 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
qsort(t->apm_req, t->apm_req_count, qsort(t->apm_req, t->apm_req_count,
sizeof(struct iso_apm_partition_request *), cmp_partition_request); sizeof(struct iso_apm_partition_request *), cmp_partition_request);
#ifdef Libisofs_mjg_boot_for_grub2
return 1;
#endif
/* t->apm_req_count will grow during the loop */ /* t->apm_req_count will grow during the loop */
up_to = t->apm_req_count + 1; up_to = t->apm_req_count + 1;
for (i = 1; i < up_to; i++) { for (i = 1; i < up_to; i++) {
@ -1660,6 +1664,13 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
up_to = t->gpt_req_count + 1; up_to = t->gpt_req_count + 1;
goal = 0; goal = 0;
part_end = 0; part_end = 0;
#ifdef Libisofs_mjg_boot_for_grub2
up_to = 0; /* No gap filling */
#endif /* Libisofs_mjg_boot_for_grub2 */
for (i = 0; i < up_to; i++) { for (i = 0; i < up_to; i++) {
if (i < up_to - 1) { if (i < up_to - 1) {
goal = t->gpt_req[i]->start_block; goal = t->gpt_req[i]->start_block;
@ -1738,6 +1749,39 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
} }
#ifdef Libisofs_protective_msdos_plus_boot_dummY
static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
{
/* Add a dummy partition of type 0 with boot flag */
if (mode == 0) {
/* Start LBA 0, block count 1 */
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 1] = 0x00; /* start head */
buf[446 + 16 + 2] = 0x01; /* start sector */
buf[446 + 16 + 3] = 0x00; /* start cylinder */
buf[446 + 16 + 4] = 0x00; /* partition type */
buf[446 + 16 + 5] = 0x00; /* end head */
buf[446 + 16 + 6] = 0x01; /* last sector */
buf[446 + 16 + 7] = 0x00; /* end cylinder */
buf[446 + 16 + 8] = 0x00; /* start LBA */
buf[446 + 16 + 9] = 0x00;
buf[446 + 16 + 10] = 0x00;
buf[446 + 16 + 11] = 0x00;
buf[446 + 16 + 12] = 0x01; /* block count */
buf[446 + 16 + 13] = 0x00;
buf[446 + 16 + 14] = 0x00;
buf[446 + 16 + 15] = 0x00;
} else {
/* copy partition 1 to 2, set boot flag and type 0x00 */
memcpy(buf + 446 + 16, buf + 446, 16);
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 4] = 0x00; /* partition type */
}
}
#endif /* Libisofs_protective_msdos_plus_boot_dummY */
int iso_write_system_area(Ecma119Image *t, uint8_t *buf) int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
{ {
int ret, int_img_blocks, sa_type, i, will_append = 0, do_isohybrid = 0; int ret, int_img_blocks, sa_type, i, will_append = 0, do_isohybrid = 0;
@ -1854,6 +1898,14 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (t->mbr_req_count == 0){ if (t->mbr_req_count == 0){
/* Write GRUB protective msdos label, i.e. a simple partition /* Write GRUB protective msdos label, i.e. a simple partition
table */ table */
#ifdef Libisofs_mjg_boot_for_grub2
part_type = 0xcd;
pml_blocks = img_blocks;
#else
if (t->gpt_req_count > 0) { if (t->gpt_req_count > 0) {
part_type = 0xee; part_type = 0xee;
pml_blocks = gpt_blocks; pml_blocks = gpt_blocks;
@ -1861,6 +1913,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
part_type = 0xcd; part_type = 0xcd;
pml_blocks = img_blocks; pml_blocks = img_blocks;
} }
#endif /* Libisofs_mjg_boot_for_grub2 */
ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head, ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl, t->partition_heads_per_cyl,
(uint8_t) part_type, buf, 0); (uint8_t) part_type, buf, 0);
@ -2014,12 +2069,40 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
wpt[i] = blk >> (i * 8); wpt[i] = blk >> (i * 8);
} }
#ifdef Libisofs_mjg_boot_for_grub2
if (buf[446 + 4] != 0x00) {
if (buf[446 + 4] != 0xef)
buf[446] |= 0x80;
#ifdef Libisofs_protective_msdos_plus_boot_dummY
else if (buf[446 + 16 + 4] == 0x00 && (buf[446 + 16] & 0x80) == 0)
#ifdef Libisofs_pmpbd_on_lba0
iso_dummy_mbr_partition(buf, 0);
#else
iso_dummy_mbr_partition(buf, 1);
#endif /* ! Libisofs_pmpbd_on_lba0 */
#endif
}
/* Prevent MBR partition type 0xee */
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee)) {
#else
/* Prevent partition type 0xee if no GPT emerged */ /* Prevent partition type 0xee if no GPT emerged */
/* >>> check for GPT magic number at byte 512 ff. */; /* >>> check for GPT magic number at byte 512 ff. */;
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) && if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
t->gpt_req_count == 0) { t->gpt_req_count == 0) {
#endif /* ! Libisofs_mjg_boot_for_grub2 */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0xee) { if (buf[446 + 16 * i + 4] == 0xee) {
iso_msgs_submit(0, iso_msgs_submit(0,
@ -2041,32 +2124,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* Add a dummy partition of type 0 with boot flag */ /* Add a dummy partition of type 0 with boot flag */
#ifdef Libisofs_pmpbd_on_lba0 #ifdef Libisofs_pmpbd_on_lba0
iso_dummy_mbr_partition(buf, 0);
/* Start LBA 0, block count 1 */
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 1] = 0x00; /* start head */
buf[446 + 16 + 2] = 0x01; /* start sector */
buf[446 + 16 + 3] = 0x00; /* start cylinder */
buf[446 + 16 + 4] = 0x00; /* partition type */
buf[446 + 16 + 5] = 0x00; /* end head */
buf[446 + 16 + 6] = 0x01; /* last sector */
buf[446 + 16 + 7] = 0x00; /* end cylinder */
buf[446 + 16 + 8] = 0x00; /* start LBA */
buf[446 + 16 + 9] = 0x00;
buf[446 + 16 + 10] = 0x00;
buf[446 + 16 + 11] = 0x00;
buf[446 + 16 + 12] = 0x01; /* block count */
buf[446 + 16 + 13] = 0x00;
buf[446 + 16 + 14] = 0x00;
buf[446 + 16 + 15] = 0x00;
#else #else
iso_dummy_mbr_partition(buf, 1);
/* copy partition 1 to 2, set boot flag and type 0x00 */
memcpy(buf + 446 + 16, buf + 446, 16);
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 4] = 0x00; /* partition type */
#endif /* ! Libisofs_pmpbd_on_lba0 */ #endif /* ! Libisofs_pmpbd_on_lba0 */
} }
@ -2402,6 +2462,14 @@ fallback:;
int assess_appended_gpt(Ecma119Image *t, int flag) int assess_appended_gpt(Ecma119Image *t, int flag)
{ {
#ifdef Libisofs_mjg_boot_for_grub2
int i, ret;
uint8_t gpt_name[72];
#else
static uint8_t basic_data_uuid[16] = { static uint8_t basic_data_uuid[16] = {
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44, 0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
@ -2414,6 +2482,8 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
int i, ret; int i, ret;
uint8_t gpt_name[72], *type_uuid; uint8_t gpt_name[72], *type_uuid;
#endif /* ! Libisofs_mjg_boot_for_grub2 */
#ifndef Libisofs_appended_partitions_inlinE #ifndef Libisofs_appended_partitions_inlinE
if (!t->gpt_backup_outside) if (!t->gpt_backup_outside)
return 2; return 2;
@ -2430,6 +2500,19 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
for (i = 0; i <= 3; i++) { for (i = 0; i <= 3; i++) {
if (t->opts->appended_partitions[i] == NULL) if (t->opts->appended_partitions[i] == NULL)
continue; continue;
#ifdef Libisofs_mjg_boot_for_grub2
sprintf((char *) gpt_name, "Appended%d", i + 1);
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->appended_part_start[i] * t->hfsp_iso_block_fac,
t->appended_part_size[i] * t->hfsp_iso_block_fac,
(char *) gpt_name, "Data");
if (ret < 0)
return ret;
#else /* Libisofs_mjg_boot_for_grub2 */
memset(gpt_name, 0, 72); memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "Appended%d", i + 1); sprintf((char *) gpt_name, "Appended%d", i + 1);
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
@ -2444,6 +2527,9 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
(uint64_t) 0, gpt_name); (uint64_t) 0, gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
#endif /* ! Libisofs_mjg_boot_for_grub2 */
} }
return ISO_SUCCESS; return ISO_SUCCESS;
} }
@ -2457,6 +2543,10 @@ static int precompute_gpt(Ecma119Image *t)
int ret, sa_type; int ret, sa_type;
int gpt_count, gpt_idx[128], apm_count; int gpt_count, gpt_idx[128], apm_count;
#ifdef Libisofs_mjg_boot_for_grub2X
int mjg_gpt_count = 0, mjg_apm_count = 0;
#endif
/* Avoid repetition by gpt_tail_writer_compute_data_blocks */ /* Avoid repetition by gpt_tail_writer_compute_data_blocks */
t->gpt_is_computed = 1; t->gpt_is_computed = 1;
@ -2482,6 +2572,27 @@ static int precompute_gpt(Ecma119Image *t)
return ret; return ret;
} }
#ifdef Libisofs_mjg_boot_for_grub2
/* Experimental:
If no GPT is registered yet, and MBR, but neither CHRP nor ISOLINUX
isohybrid is desired, then try to apply the isohybrid GPT and APM flags
nevertheless. Avoid an overall ISO image GPT partition.
*/
if (t->gpt_req_count <= 0 &&
((t->system_area_options >> 2) & 0x3f) == 0 &&
((t->system_area_options >> 10) & 0xf) != 1 &&
(!(t->system_area_options & 2))) {
ret = assess_isohybrid_gpt_apm(t, &gpt_count, gpt_idx, &apm_count,
1 | ((t->apm_req_count > 0) << 1) | 4);
if (ret <= 0)
return ret;
t->apm_req_flags |= 2; /* Do not fill APM gaps,
do not adjust final APM partition size */
}
#endif /* Libisofs_mjg_boot_for_grub2 */
/* Rectify APM requests early in order to learn the size of GPT. /* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here. iso_write_apm() relies on this being already done here.