New API calls el_torito_set_id_string(), el_torito_get_id_string(),

el_torito_set_selection_crit(), el_torito_get_selection_crit().
This commit is contained in:
Thomas Schmitt 2010-04-23 18:01:27 +02:00
parent ace0d1ab2e
commit 02d7a690eb
4 changed files with 157 additions and 20 deletions

View File

@ -123,6 +123,36 @@ int el_torito_get_bootable(ElToritoBootImage *bootimg)
return !!bootimg->bootable;
}
/* API */
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
{
memcpy(bootimg->id_string, id_string, 28);
return 1;
}
/* API */
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
{
memcpy(id_string, bootimg->id_string, 28);
return 1;
}
/* API */
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
{
memcpy(bootimg->selection_crit, crit, 20);
return 1;
}
/* API */
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
{
memcpy(crit, bootimg->selection_crit, 20);
return 1;
}
/**
* Specifies that this image needs to be patched. This involves the writting
* of a 56 bytes boot information table at offset 8 of the boot image file.
@ -376,7 +406,8 @@ int create_image(IsoImage *image, const char *image_path,
boot->load_seg = 0;
boot->load_size = load_sectors;
boot->platform_id = 0; /* 80x86 */
memset(boot->id_string, 0, sizeof(boot->id_string));
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
if (bootimg) {
*bootimg = boot;
}
@ -656,7 +687,8 @@ struct catalog_stream
};
static void
write_validation_entry(uint8_t *buf, uint8_t platform_id)
write_validation_entry(uint8_t *buf, uint8_t platform_id,
uint8_t id_string[24])
{
size_t i;
int checksum;
@ -665,9 +697,9 @@ write_validation_entry(uint8_t *buf, uint8_t platform_id)
(struct el_torito_validation_entry*)buf;
ve->header_id[0] = 1;
ve->platform_id[0] = platform_id;
memcpy(ve->id_string, id_string, sizeof(ve->id_string));
ve->key_byte1[0] = 0x55;
ve->key_byte2[0] = 0xAA;
/* calculate the checksum, to ensure sum of all words is 0 */
checksum = 0;
for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) {
@ -677,7 +709,8 @@ write_validation_entry(uint8_t *buf, uint8_t platform_id)
}
static void
write_section_header(uint8_t *buf, Ecma119Image *t, int idx) {
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
{
int pi;
char *id_string;
@ -687,17 +720,11 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx) {
/* 0x90 = more section headers follow , 0x91 = final section */
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
pi= e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->num_entries[0] = 1;
e->num_entries[1] = 0;
e->num_entries[0] = num_entries & 0xff;
e->num_entries[1] = (num_entries >> 8) & 0xff;;
id_string = (char *) e->id_string;
memset(id_string, 0, sizeof(e->id_string));
/* >>> ???
El-Torito 1.0 , chapter 2.3 :
"If the BIOS understands the ID, string it may choose to boot
the system using one of these entries ..."
*/
memcpy(id_string, t->catalog->bootimages[idx]->id_string,
sizeof(e->id_string));
}
/**
@ -720,18 +747,25 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
se->system_type[0] = img->partition_type;
iso_lsb(se->sec_count, img->load_size, 2);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
se->selec_criteria[0] = img->selection_crit[0];
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
}
static
int catalog_open(IsoStream *stream)
{
int i;
int i, j, k, num_entries;
struct catalog_stream *data;
uint8_t *wpt;
struct el_torito_boot_catalog *cat;
struct el_torito_boot_image **boots;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
cat = data->target->catalog;
boots = cat->bootimages;
if (data->offset != -1) {
return ISO_FILE_ALREADY_OPENED;
@ -741,16 +775,35 @@ int catalog_open(IsoStream *stream)
/* fill the buffer with the catalog contents */
write_validation_entry(data->buffer,
data->target->catalog->bootimages[0]->platform_id);
boots[0]->platform_id, boots[0]->id_string);
/* write default entry = first boot image */
write_section_entry(data->buffer + 32, data->target, 0);
/* ts B00420 */
/* (The maximum number of boot images must fit into BLOCK_SIZE) */
for (i = 1; i < data->target->catalog->num_bootimages; i++) {
write_section_header(data->buffer + i * 64, data->target, i);
write_section_entry(data->buffer + i * 64 + 32, data->target, i);
wpt = data->buffer + 64;
for (i = 1; i < cat->num_bootimages; ) {
/* Look ahead and put images of same platform_id and id_string
into the same section */
for (j = i + 1; j < cat->num_bootimages; j++) {
if (boots[i]->platform_id != boots[j]->platform_id)
break;
for (k = 0; k < sizeof(boots[i]->selection_crit); k++)
if (boots[i]->selection_crit[k] != boots[j]->selection_crit[k])
break;
if (k < sizeof(boots[i]->selection_crit))
break;
}
num_entries = j - i;
write_section_header(wpt, data->target, i, num_entries);
wpt += 32;
for (j = 0; j < num_entries; j++) {
write_section_entry(wpt, data->target, i);
wpt += 32;
i++;
}
}
data->offset = 0;
return ISO_SUCCESS;

View File

@ -64,6 +64,8 @@ struct el_torito_boot_image {
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
uint8_t platform_id;
uint8_t id_string[28];
uint8_t selection_crit[20];
};
/** El-Torito, 2.1 */

View File

@ -282,6 +282,8 @@ typedef struct
/* ts B00419 */
int num_bootimgs;
unsigned char platform_ids[Libisofs_max_boot_imageS];
unsigned char id_strings[Libisofs_max_boot_imageS][28];
unsigned char selection_crits[Libisofs_max_boot_imageS][20];
unsigned char boot_flags[Libisofs_max_boot_imageS]; /* bit0= bootable */
unsigned char media_types[Libisofs_max_boot_imageS];
unsigned char partition_types[Libisofs_max_boot_imageS];
@ -2238,12 +2240,16 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
/* The Default Entry is declared mandatory */
data->num_bootimgs = 1;
data->platform_ids[0] = ve->platform_id[0];
memcpy(data->id_strings[0], ve->id_string, 24);
memset(data->id_strings[0] + 24, 0, 4);
data->boot_flags[0] = entry->boot_indicator[0] ? 1 : 0;
data->media_types[0] = entry->boot_media_type[0];
data->partition_types[0] = entry->system_type[0];
data->load_segs[0] = iso_read_lsb(entry->load_seg, 2);
data->load_sizes[0] = iso_read_lsb(entry->sec_count, 2);
data->bootblocks[0] = iso_read_lsb(entry->block, 4);
/* The Default Entry has no selection criterion */
memset(data->selection_crits[0], 0, 20);
/* ts B00420 : Read eventual more entries from the boot catalog */
last_done = 0;
@ -2262,12 +2268,15 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
entry = (struct el_torito_section_entry *)(buffer + rx);
idx = data->num_bootimgs;
data->platform_ids[idx] = sh->platform_id[0];
memcpy(data->id_strings[idx], sh->id_string, 28);
data->boot_flags[idx] = entry->boot_indicator[0] ? 1 : 0;
data->media_types[idx] = entry->boot_media_type[0];
data->partition_types[idx] = entry->system_type[0];
data->load_segs[idx] = iso_read_lsb(entry->load_seg, 2);
data->load_sizes[idx] = iso_read_lsb(entry->sec_count, 2);
data->bootblocks[idx] = iso_read_lsb(entry->block, 4);
data->selection_crits[idx][0] = entry->selec_criteria[0];
memcpy(data->selection_crits[idx] + 1, entry->vendor_sc, 19);
data->num_bootimgs++;
}
}
@ -3137,6 +3146,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
boot_image->load_seg = data->load_segs[idx];
boot_image->load_size = data->load_sizes[idx];
boot_image->platform_id = data->platform_ids[idx];
memcpy(boot_image->id_string, data->id_strings[idx], 28);
memcpy(boot_image->selection_crit, data->selection_crits, 20);
catalog->bootimages[catalog->num_bootimages] = boot_image;
catalog->num_bootimages++;

View File

@ -2543,6 +2543,77 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
*/
int el_torito_get_bootable(ElToritoBootImage *bootimg);
/**
* Set the id_string of the Validation Entry resp. Sector Header Entry which
* will govern the boot image Section Entry in the El Torito Catalog.
*
* @param bootimg
* The image to manipulate.
* @param id_string
* The first boot image puts 24 bytes of ID string into the Validation
* Entry, where they shall "identify the manufacturer/developer of
* the CD-ROM".
* Further boot images put 28 bytes into their Section Header.
* El Torito 1.0 states that "If the BIOS understands the ID string, it
* may choose to boot the * system using one of these entries in place
* of the INITIAL/DEFAULT entry." (The INITIAL/DEFAULT entry points to the
* first boot image.)
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Get the id_string as of el_torito_set_id_string().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 28 bytes of id string
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Set the Selection Criteria of a boot image.
*
* @param bootimg
* The image to manipulate.
* @param crit
* The first boot image has no selection criteria. They will be ignored.
* Further boot images put 1 byte of Selection Criteria Type and 19
* bytes of data into their Section Entry.
* El Torito 1.0 states that "The format of the selection criteria is
* a function of the BIOS vendor. In the case of a foreign language
* BIOS three bytes would be used to identify the language".
* Type byte == 0 means "no criteria",
* type byte == 1 means "Language and Version Information (IBM)".
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Get the Selection Criteria bytes as of el_torito_set_selection_crit().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 20 bytes of type and data
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Specifies that this image needs to be patched. This involves the writing
* of a 56 bytes boot information table at offset 8 of the boot image file.