Committing the yet incomplete implementation of SYSLINUX isohybrid
for MBR, UEFI and x86-Mac. This shall avoid tangling with ongoing HFS+ efforts.
This commit is contained in:
parent
a8b20b87aa
commit
6cb5f802af
@ -197,14 +197,14 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
|
|||||||
*/
|
*/
|
||||||
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
||||||
{
|
{
|
||||||
bootimg->isolinux_options = (options & 0x03);
|
bootimg->isolinux_options = (options & 0x01ff);
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
||||||
{
|
{
|
||||||
return bootimg->isolinux_options & 0x03;
|
return bootimg->isolinux_options & 0x01ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
|
@ -63,8 +63,14 @@ struct el_torito_boot_image {
|
|||||||
* bit 0 -> whether to patch image
|
* bit 0 -> whether to patch image
|
||||||
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
||||||
* System Area (deprecated)
|
* System Area (deprecated)
|
||||||
|
*
|
||||||
|
* >>> bit2-7= Mentioning in isohybrid GPT
|
||||||
|
* >>> 0= do not mention in GPT
|
||||||
|
* >>> 1= mention as EFI partition
|
||||||
|
* >>> 2= Mention as HFS+ partition
|
||||||
|
* >>> bit8= Mention in isohybrid Apple partition map
|
||||||
*/
|
*/
|
||||||
unsigned int isolinux_options:2;
|
unsigned int isolinux_options;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char type; /**< The type of image */
|
||||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||||
short load_seg; /**< Load segment for the initial boot image. */
|
short load_seg; /**< Load segment for the initial boot image. */
|
||||||
@ -75,6 +81,7 @@ struct el_torito_boot_image {
|
|||||||
uint8_t platform_id;
|
uint8_t platform_id;
|
||||||
uint8_t id_string[28];
|
uint8_t id_string[28];
|
||||||
uint8_t selection_crit[20];
|
uint8_t selection_crit[20];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** El-Torito, 2.1 */
|
/** El-Torito, 2.1 */
|
||||||
|
@ -23,6 +23,21 @@
|
|||||||
/* for gettimeofday() */
|
/* for gettimeofday() */
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
/* >>> ISOHYBRID : Need ./configure test for uuid_generate() which checks for:
|
||||||
|
uuid_t, uuid_generate, the need for -luuid
|
||||||
|
*/
|
||||||
|
/* <<<
|
||||||
|
#define Libisofs_with_uuid_generatE 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_uuid_generatE
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "filesrc.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
#include "eltorito.h"
|
||||||
|
|
||||||
|
|
||||||
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
||||||
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
||||||
@ -45,7 +60,7 @@ license from above stem licenses, typically from LGPL.
|
|||||||
In case its generosity is needed, here is the 2-clause BSD license:
|
In case its generosity is needed, here is the 2-clause BSD license:
|
||||||
|
|
||||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||||
and 2008-2010 Thomas Schmitt
|
and 2008-2012 Thomas Schmitt
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
@ -353,6 +368,9 @@ Main:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> ISOHYBRID : mention the new stuff learned from mjg and isohybrid.c */
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
||||||
{
|
{
|
||||||
@ -377,28 +395,381 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Find out whether GPT and APM are desired */
|
||||||
|
static int assess_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
||||||
|
int *apm_count)
|
||||||
|
{
|
||||||
|
int i, ilx_opts;
|
||||||
|
|
||||||
|
for (i = 0; i < t->catalog->num_bootimages; i++) {
|
||||||
|
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
|
||||||
|
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
|
||||||
|
if (*gpt_count < 128)
|
||||||
|
gpt_idx[*gpt_count]= i;
|
||||||
|
(*gpt_count)++;
|
||||||
|
}
|
||||||
|
if (ilx_opts & 256)
|
||||||
|
(*apm_count)++;
|
||||||
|
}
|
||||||
|
if (*apm_count > 6) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"Too many entries desired for Apple Partition Map. (max 6)",
|
||||||
|
0, "FAILURE", 0);
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Insert APM head into MBR */
|
||||||
|
static int insert_apm_head(uint8_t *buf, int apm_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static uint8_t apm_mbr_start[32] = {
|
||||||
|
0x33, 0xed, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
};
|
||||||
|
static uint8_t apm_head[32] = {
|
||||||
|
0x45, 0x52, 0x08, 0x00, 0x00, 0x00, 0x90, 0x90,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
if (apm_count) {
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if(buf[i] != apm_mbr_start[i])
|
||||||
|
break;
|
||||||
|
if (i < 32) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"MBR template file seems not prepared for Apple Partition Map.",
|
||||||
|
0, "FAILURE", 0);
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
buf[i] = apm_head[i];
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_uuid_generatE
|
||||||
|
|
||||||
|
static void swap_uuid(void *u_pt)
|
||||||
|
{
|
||||||
|
uint8_t tr, *u;
|
||||||
|
|
||||||
|
u = (uint8_t *) u_pt;
|
||||||
|
tr = u[0]; u[0] = u[3]; u[3] = tr;
|
||||||
|
tr = u[1]; u[1] = u[2]; u[2] = tr;
|
||||||
|
tr = u[4]; u[4] = u[5]; u[5] = tr;
|
||||||
|
tr = u[6]; u[6] = u[7]; u[7] = tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_uuid_generatE */
|
||||||
|
|
||||||
|
|
||||||
|
/* CRC-32 as of GPT and Ethernet.
|
||||||
|
Parameters are deduced from a table driven implementation in isohybrid.c
|
||||||
|
*/
|
||||||
|
static unsigned int crc32_gpt(unsigned char *data, int count, int flag)
|
||||||
|
{
|
||||||
|
unsigned int acc, top, result = 0;
|
||||||
|
long int i;
|
||||||
|
|
||||||
|
/* Chosen so that the CRC of 0 bytes of input is 0x00000000 */
|
||||||
|
acc = 0x46af6449;
|
||||||
|
|
||||||
|
/* Process data bits and flush numerator by 32 zero bits */
|
||||||
|
for (i = 0; i < count * 8 + 32; i++) {
|
||||||
|
top = acc & 0x80000000;
|
||||||
|
acc = (acc << 1);
|
||||||
|
if (i < count * 8)
|
||||||
|
/* The least significant bits of input bytes get processed first */
|
||||||
|
acc |= ((data[i / 8] >> (i % 8)) & 1);
|
||||||
|
if (top)
|
||||||
|
/* Division by the generating polynomial */
|
||||||
|
acc ^= 0x04c11db7;
|
||||||
|
}
|
||||||
|
/* Mirror residue bits */
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if (acc & (1 << i))
|
||||||
|
result |= 1 << (31 - i);
|
||||||
|
/* Return bit complement */
|
||||||
|
return result ^ 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void random_uuid(Ecma119Image *t, uint8_t *uuid)
|
||||||
|
{
|
||||||
|
#ifdef Libisofs_with_uuid_generatE
|
||||||
|
uuid_t u;
|
||||||
|
#else
|
||||||
|
uint8_t u[16];
|
||||||
|
/* produced by uuidgen(1) by Andreas Dilger */
|
||||||
|
static uint8_t uuid_template[16] = {
|
||||||
|
0x6e, 0xf5, 0xa3, 0x8b, 0xcb, 0xfa, 0xdd, 0x4e,
|
||||||
|
0x36, 0x9f, 0x0b, 0x12, 0x51, 0xc3, 0x7d, 0x1a
|
||||||
|
};
|
||||||
|
uint32_t rnd, salt;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
static int counter = 0;
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_uuid_generatE
|
||||||
|
|
||||||
|
uuid_generate(u);
|
||||||
|
swap_uuid((void *) u);
|
||||||
|
memcpy(wpt, u, 16);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
salt = crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0);
|
||||||
|
|
||||||
|
/* This relies on the uniqueness of the template and the rareness of
|
||||||
|
bootable ISO image production via libisofs. Estimated 53 bits of
|
||||||
|
entropy should influence the production of a single day.
|
||||||
|
So first collisions are to be expected with about 100 million images
|
||||||
|
per day.
|
||||||
|
*/
|
||||||
|
memcpy(u, uuid_template, 16);
|
||||||
|
gettimeofday(&tv, &tz);
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
u[3 + i] = (salt >> (8 * i)) & 0xff;
|
||||||
|
u[8] = (salt >> 8) & 0xff;
|
||||||
|
rnd = ((0xffffffffff & tv.tv_sec) << 8) |
|
||||||
|
(((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff);
|
||||||
|
u[9] ^= counter & 0xff;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
u[10 + i] ^= (rnd >> (8 * i)) & 0xff;
|
||||||
|
u[14] ^= (tv.tv_usec >> 8) & 0xff;
|
||||||
|
u[15] ^= tv.tv_usec & 0xff;
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_with_uuid_generatE */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Describe the first three GPT boot images as MBR partitions */
|
||||||
|
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||||
|
int gpt_idx[128], int *gpt_cursor)
|
||||||
|
{
|
||||||
|
int ilx_opts;
|
||||||
|
off_t hd_blocks;
|
||||||
|
static uint8_t dummy_chs[3] = {
|
||||||
|
0xfe, 0xff, 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
wpt[0] = 0;
|
||||||
|
memcpy(wpt + 1, dummy_chs, 3);
|
||||||
|
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
|
||||||
|
if (((ilx_opts >> 2) & 63) == 2)
|
||||||
|
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
|
||||||
|
else
|
||||||
|
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
|
||||||
|
|
||||||
|
memcpy(wpt + 5, dummy_chs, 3);
|
||||||
|
|
||||||
|
/* Start LBA (in 512 blocks) */
|
||||||
|
wpt += 8;
|
||||||
|
lsb_to_buf(&wpt, t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].block * 4,
|
||||||
|
32, 0);
|
||||||
|
|
||||||
|
/* Number of blocks */
|
||||||
|
hd_blocks = t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].size;
|
||||||
|
hd_blocks = hd_blocks / 512 + !!(hd_blocks % 512);
|
||||||
|
lsb_to_buf(&wpt, (int) hd_blocks, 32, 0);
|
||||||
|
|
||||||
|
(*gpt_cursor)++;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void write_gpt_entry(Ecma119Image *t, char *buf, uint8_t type_guid[16],
|
||||||
|
off_t start_lba, off_t end_lba, uint8_t flags[8],
|
||||||
|
uint8_t name[72])
|
||||||
|
{
|
||||||
|
char *wpt = buf;
|
||||||
|
|
||||||
|
memcpy(wpt, type_guid, 16);
|
||||||
|
wpt += 16;
|
||||||
|
random_uuid(t, (uint8_t *) wpt);
|
||||||
|
wpt += 16;
|
||||||
|
lsb_to_buf(&wpt, start_lba & 0xffffffff, 32, 0);
|
||||||
|
lsb_to_buf(&wpt, (start_lba >> 32) & 0xffffffff, 32, 0);
|
||||||
|
lsb_to_buf(&wpt, end_lba & 0xffffffff, 32, 0);
|
||||||
|
lsb_to_buf(&wpt, (end_lba >> 32) & 0xffffffff, 32, 0);
|
||||||
|
memcpy(wpt, name, 72);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_gpt_array(Ecma119Image *t, char *buf, uint32_t part_start)
|
||||||
|
{
|
||||||
|
static uint8_t basic_data_uuid[16] = {
|
||||||
|
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
|
||||||
|
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
|
||||||
|
};
|
||||||
|
static uint8_t hfs_uuid[16] = {
|
||||||
|
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
|
||||||
|
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
|
||||||
|
};
|
||||||
|
uint8_t *uuid;
|
||||||
|
int i, ilx_opts;
|
||||||
|
off_t start_lba, end_lba;
|
||||||
|
|
||||||
|
/* >>> First entry describes overall image , basic_data_uuid
|
||||||
|
start_lba = ;
|
||||||
|
end_lba = ;
|
||||||
|
write_gpt_entry(t, buf + 512 * part_start, basic_data_uuid,
|
||||||
|
off_t start_lba, off_t end_lba, uint8_t flags[8],
|
||||||
|
uint8_t name[72])
|
||||||
|
*/;
|
||||||
|
|
||||||
|
/* >>> Each marked boot image gets its entry */;
|
||||||
|
for (i= 0; i < t->catalog->num_bootimages; i++) {
|
||||||
|
ilx_opts= (t->catalog->bootimages[i]->isolinux_options >> 2) & 63;
|
||||||
|
if (ilx_opts == 1)
|
||||||
|
uuid = basic_data_uuid;
|
||||||
|
else if (ilx_opts == 1)
|
||||||
|
uuid = hfs_uuid;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* >>> */;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* >>> */;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_gpt_header_block(Ecma119Image *t, char *buf,
|
||||||
|
uint32_t part_start, uint32_t p_arr_crc)
|
||||||
|
{
|
||||||
|
static char *sig = "EFI PART";
|
||||||
|
static char revision[4] = {0x00, 0x00, 0x01, 0x00};
|
||||||
|
char *wpt;
|
||||||
|
uint32_t crc;
|
||||||
|
off_t back_lba;
|
||||||
|
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
wpt = buf;
|
||||||
|
|
||||||
|
memcpy(wpt, sig, 8); /* no trailing 0 */
|
||||||
|
wpt += 8;
|
||||||
|
memcpy(wpt, revision, 4);
|
||||||
|
wpt += 4;
|
||||||
|
lsb_to_buf(&wpt, 92, 32, 0);
|
||||||
|
|
||||||
|
/* CRC will be inserted later */
|
||||||
|
wpt += 4;
|
||||||
|
|
||||||
|
/* reserved */
|
||||||
|
lsb_to_buf(&wpt, 0, 32, 0);
|
||||||
|
/* Own LBA low 32 */
|
||||||
|
lsb_to_buf(&wpt, 1, 32, 0);
|
||||||
|
/* Own LBA high 32 */
|
||||||
|
lsb_to_buf(&wpt, 0, 32, 0);
|
||||||
|
|
||||||
|
/* Backup LBA is 1 hd block before image end */
|
||||||
|
back_lba = t->curblock * 4 - 1;
|
||||||
|
lsb_to_buf(&wpt, (uint32_t) (back_lba & 0xffffffff), 32, 1);
|
||||||
|
lsb_to_buf(&wpt, (uint32_t) (back_lba >> 32), 32, 1);
|
||||||
|
|
||||||
|
/* First usable LBA for partitions (entry array occupies 32 hd blocks) */
|
||||||
|
lsb_to_buf(&wpt, part_start + 32, 32, 0);
|
||||||
|
lsb_to_buf(&wpt, 0, 32, 0);
|
||||||
|
|
||||||
|
/* Last usable LBA for partitions */
|
||||||
|
lsb_to_buf(&wpt, (uint32_t) ((back_lba - 32) & 0xffffffff), 32, 1);
|
||||||
|
lsb_to_buf(&wpt, (uint32_t) ((back_lba - 32) >> 32), 32, 1);
|
||||||
|
|
||||||
|
/* Disk GUID */
|
||||||
|
random_uuid(t, (uint8_t *) wpt);
|
||||||
|
wpt += 16;
|
||||||
|
|
||||||
|
/* Partition entries start */
|
||||||
|
lsb_to_buf(&wpt, part_start, 32, 0);
|
||||||
|
lsb_to_buf(&wpt, 0, 32, 0);
|
||||||
|
|
||||||
|
/* Number of partition entries */
|
||||||
|
lsb_to_buf(&wpt, 128, 32, 0);
|
||||||
|
|
||||||
|
/* Size of a partition entry */
|
||||||
|
lsb_to_buf(&wpt, 128, 32, 0);
|
||||||
|
|
||||||
|
/* CRC-32 of the partition array */
|
||||||
|
lsb_to_buf(&wpt, p_arr_crc, 32, 0);
|
||||||
|
|
||||||
|
|
||||||
|
/* <<< Only for a first test */
|
||||||
|
if (wpt - buf != 92) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"program error : write_gpt_header_block : wpt != 92",
|
||||||
|
0, "FATAL", 0);
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CRC-32 of this header while head_crc is 0 */
|
||||||
|
wpt = buf + 16;
|
||||||
|
crc = crc32_gpt((unsigned char *) buf, wpt - buf, 0);
|
||||||
|
lsb_to_buf(&wpt, crc, 32, 0);
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag bit0= make own random MBR Id from current time
|
* @param flag bit0= make own random MBR Id from current time
|
||||||
*/
|
*/
|
||||||
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||||
uint32_t mbr_id, int head_count, int sector_count,
|
|
||||||
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 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;
|
||||||
|
uint32_t boot_lba, mbr_id, p_arr_crc, part_start;
|
||||||
|
int head_count, sector_count, ret;
|
||||||
|
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||||
|
|
||||||
|
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||||
|
mbr_id = 0;
|
||||||
|
head_count = t->partition_heads_per_cyl;
|
||||||
|
sector_count = t->partition_secs_per_head;
|
||||||
|
|
||||||
|
ret = assess_gpt_apm(t, &gpt_count, gpt_idx, &apm_count);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = insert_apm_head(buf, apm_count);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
/* Padding of image_size to a multiple of sector_count*head_count
|
/* Padding of image_size to a multiple of sector_count*head_count
|
||||||
happens already at compute time and is implemented by
|
happens already at compute time and is implemented by
|
||||||
an appropriate increase of Ecma119Image->tail_blocks.
|
an appropriate increase of Ecma119Image->tail_blocks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (gpt_count) {
|
||||||
|
|
||||||
|
/* >>> ISOHYBRID : need to make sure that backup GPT fits into tail */;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
wpt = (char *) buf + 432;
|
wpt = (char *) buf + 432;
|
||||||
|
|
||||||
/* write qword boot_lba # Offset 432
|
/* write qword boot_lba # Offset 432
|
||||||
@ -422,10 +793,21 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
|
|
||||||
/* # Offset 446
|
/* # Offset 446
|
||||||
*/
|
*/
|
||||||
|
gpt_cursor= 0;
|
||||||
for (part = 1 ; part <= 4; part++) {
|
for (part = 1 ; part <= 4; part++) {
|
||||||
if ((int) part != part_number) {
|
if ((int) part != part_number) {
|
||||||
/* if this_partition != partition_number: write 16 zero bytes */
|
/* if this_partition != partition_number: write 16 zero bytes
|
||||||
|
(this is now overriden by the eventual desire to announce
|
||||||
|
EFI and HFS boot images.)
|
||||||
|
*/
|
||||||
memset(wpt, 0, 16);
|
memset(wpt, 0, 16);
|
||||||
|
|
||||||
|
if (gpt_cursor < gpt_count) {
|
||||||
|
ret = gpt_images_as_mbr_partitions(t, wpt, gpt_idx,
|
||||||
|
&gpt_cursor);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
wpt+= 16;
|
wpt+= 16;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -452,6 +834,24 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
*/
|
*/
|
||||||
lsb_to_buf(&wpt, 0xaa55, 16, 0);
|
lsb_to_buf(&wpt, 0xaa55, 16, 0);
|
||||||
|
|
||||||
|
if (gpt_count) {
|
||||||
|
|
||||||
|
/* >>> ISOHYBRID : write primary GPT and compute p_arr_crc */;
|
||||||
|
part_start = 4 + (apm_count + 1) * 4;
|
||||||
|
|
||||||
|
|
||||||
|
ret = write_gpt_header_block(t, (char *) buf + 512,
|
||||||
|
part_start, p_arr_crc);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apm_count) {
|
||||||
|
|
||||||
|
/* >>> ISOHYBRID : write APM entry blocks (2K) */;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
|||||||
* Be cautious with changing parameters. Only few combinations are tested.
|
* Be cautious with changing parameters. Only few combinations are tested.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int make_isolinux_mbr(uint32_t *img_blocks, uint32_t boot_lba,
|
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
|
||||||
uint32_t mbr_id, int head_count, int sector_count,
|
|
||||||
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);
|
||||||
|
|
||||||
@ -750,9 +749,16 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
*/
|
*/
|
||||||
return ISO_ISOLINUX_CANT_PATCH;
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
}
|
}
|
||||||
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
|
|
||||||
(uint32_t) 0, t->partition_heads_per_cyl,
|
/* >>> ISOHYBRID : need option to set fs_type of MBR partition 1
|
||||||
t->partition_secs_per_head, 0, 1, 0x17, buf, 1);
|
(here it is 0x17) */;
|
||||||
|
|
||||||
|
/* >>> ??? Why is partition_offset 0 here ?
|
||||||
|
It gets adjusted later by iso_offset_partition_start()
|
||||||
|
Would it harm to give the real offset here ?
|
||||||
|
*/;
|
||||||
|
|
||||||
|
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, 0x17, buf, 1);
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
return ret;
|
return ret;
|
||||||
} else if (sa_type == 1) {
|
} else if (sa_type == 1) {
|
||||||
@ -911,6 +917,9 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
|||||||
iso_msgs_submit(0,
|
iso_msgs_submit(0,
|
||||||
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
||||||
0, "WARNING", 0);
|
0, "WARNING", 0);
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"There are said to be BIOSes which will not boot this via MBR.",
|
||||||
|
0, "WARNING", 0);
|
||||||
{ret = ISO_SUCCESS; goto ex;}
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user