Provisory new pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
This commit is contained in:
parent
93f3cb1823
commit
ec35bb21c0
@ -104,6 +104,8 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
free(t->output_charset);
|
free(t->output_charset);
|
||||||
if (t->bootsrc != NULL)
|
if (t->bootsrc != NULL)
|
||||||
free(t->bootsrc);
|
free(t->bootsrc);
|
||||||
|
if (t->boot_appended_idx != NULL)
|
||||||
|
free(t->boot_appended_idx);
|
||||||
if (t->system_area_data != NULL)
|
if (t->system_area_data != NULL)
|
||||||
free(t->system_area_data);
|
free(t->system_area_data);
|
||||||
if (t->checksum_ctx != NULL) { /* dispose checksum context */
|
if (t->checksum_ctx != NULL) { /* dispose checksum context */
|
||||||
@ -567,8 +569,13 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
vol.vol_desc_version[0] = 1;
|
vol.vol_desc_version[0] = 1;
|
||||||
strncpy_pad((char*)vol.system_id, system_id, 32);
|
strncpy_pad((char*)vol.system_id, system_id, 32);
|
||||||
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
||||||
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
|
if (t->pvd_size_is_total_size) {
|
||||||
4);
|
iso_bb(vol.vol_space_size,
|
||||||
|
t->total_size / 2048 - t->eff_partition_offset, 4);
|
||||||
|
} else {
|
||||||
|
iso_bb(vol.vol_space_size,
|
||||||
|
t->vol_space_size - t->eff_partition_offset, 4);
|
||||||
|
}
|
||||||
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
||||||
@ -2376,12 +2383,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||||||
target->num_bootsrc = target->catalog->num_bootimages;
|
target->num_bootsrc = target->catalog->num_bootimages;
|
||||||
target->bootsrc = calloc(target->num_bootsrc + 1,
|
target->bootsrc = calloc(target->num_bootsrc + 1,
|
||||||
sizeof(IsoFileSrc *));
|
sizeof(IsoFileSrc *));
|
||||||
if (target->bootsrc == NULL) {
|
target->boot_appended_idx = calloc(target->num_bootsrc + 1,
|
||||||
|
sizeof(int));
|
||||||
|
if (target->bootsrc == NULL || target->boot_appended_idx == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
for (i= 0; i < target->num_bootsrc; i++)
|
for (i= 0; i < target->num_bootsrc; i++) {
|
||||||
target->bootsrc[i] = NULL;
|
target->bootsrc[i] = NULL;
|
||||||
|
target->boot_appended_idx[i] = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
target->num_bootsrc = 0;
|
target->num_bootsrc = 0;
|
||||||
target->bootsrc = NULL;
|
target->bootsrc = NULL;
|
||||||
@ -2448,6 +2459,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target->total_size = 0;
|
||||||
|
target->vol_space_size = 0;
|
||||||
|
target->pvd_size_is_total_size = 0;
|
||||||
|
|
||||||
target->checksum_idx_counter = 0;
|
target->checksum_idx_counter = 0;
|
||||||
target->checksum_ctx = NULL;
|
target->checksum_ctx = NULL;
|
||||||
target->checksum_counter = 0;
|
target->checksum_counter = 0;
|
||||||
|
@ -554,10 +554,19 @@ struct ecma119_image
|
|||||||
|
|
||||||
time_t now; /**< Time at which writing began. */
|
time_t now; /**< Time at which writing began. */
|
||||||
|
|
||||||
/** Total size of the output. This only includes the current volume. */
|
/* Total size of the output. Counted in bytes.
|
||||||
|
* Includes ISO filesystem and appended data.
|
||||||
|
*/
|
||||||
off_t total_size;
|
off_t total_size;
|
||||||
|
|
||||||
|
/** Size actually governed by the ISO filesystem part of the output */
|
||||||
uint32_t vol_space_size;
|
uint32_t vol_space_size;
|
||||||
|
|
||||||
|
/* 1= write the total size into the PVD of the ISO,
|
||||||
|
* 0= write vol_space_size
|
||||||
|
*/
|
||||||
|
int pvd_size_is_total_size;
|
||||||
|
|
||||||
/* Bytes already written to image output */
|
/* Bytes already written to image output */
|
||||||
off_t bytes_written;
|
off_t bytes_written;
|
||||||
/* just for progress notification */
|
/* just for progress notification */
|
||||||
@ -640,6 +649,8 @@ struct ecma119_image
|
|||||||
int num_bootsrc;
|
int num_bootsrc;
|
||||||
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
|
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
|
||||||
|
|
||||||
|
int *boot_appended_idx; /* Appended partition which serve as boot images */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System Area related information
|
* System Area related information
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2010 - 2014 Thomas Schmitt
|
* Copyright (c) 2010 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -323,36 +324,61 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
struct el_torito_boot_image *boot;
|
struct el_torito_boot_image *boot;
|
||||||
int boot_media_type = 0;
|
int boot_media_type = 0;
|
||||||
int load_sectors = 0; /* number of sector to load */
|
int load_sectors = 0; /* number of sector to load */
|
||||||
|
int part_idx = -1;
|
||||||
unsigned char partition_type = 0;
|
unsigned char partition_type = 0;
|
||||||
off_t size;
|
off_t size;
|
||||||
IsoNode *imgfile;
|
IsoNode *imgfile = NULL;
|
||||||
IsoStream *stream;
|
IsoStream *stream = NULL;
|
||||||
|
|
||||||
*bootnode = NULL;
|
*bootnode = NULL;
|
||||||
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
|
||||||
if (ret < 0) {
|
if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) {
|
||||||
return ret;
|
/* --interval:appended_partition_N... */
|
||||||
}
|
if (type != ELTORITO_NO_EMUL) {
|
||||||
if (ret == 0) {
|
|
||||||
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
/* >>> ??? lift this ban by making a temporary IsoStream from
|
||||||
|
partition source, determine size,
|
||||||
|
and read ELTORITO_HARD_DISC_EMUL MBR ?
|
||||||
|
*/
|
||||||
|
|
||||||
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition cannot serve as El Torito boot image with FD/HD emulation");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
sscanf(image_path + 30, "%d", &part_idx);
|
||||||
|
if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) {
|
||||||
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition index for El Torito boot image is out of range");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
part_idx--;
|
||||||
|
size = 1;
|
||||||
|
} else {
|
||||||
|
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||||
"El Torito boot image file missing in ISO image: '%s'",
|
"El Torito boot image file missing in ISO image: '%s'",
|
||||||
image_path);
|
image_path);
|
||||||
return ISO_NODE_DOESNT_EXIST;
|
return ISO_NODE_DOESNT_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imgfile->type != LIBISO_FILE) {
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
*bootnode = (IsoFile *) imgfile;
|
||||||
|
|
||||||
|
stream = ((IsoFile*)imgfile)->stream;
|
||||||
|
|
||||||
|
/* we need to read the image at least two times */
|
||||||
|
if (!iso_stream_is_repeatable(stream)) {
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = iso_stream_get_size(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgfile->type != LIBISO_FILE) {
|
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
|
||||||
}
|
|
||||||
*bootnode = (IsoFile *) imgfile;
|
|
||||||
|
|
||||||
stream = ((IsoFile*)imgfile)->stream;
|
|
||||||
|
|
||||||
/* we need to read the image at least two times */
|
|
||||||
if (!iso_stream_is_repeatable(stream)) {
|
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = iso_stream_get_size(stream);
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
"Boot image file is empty");
|
"Boot image file is empty");
|
||||||
@ -441,7 +467,9 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
boot->image = (IsoFile*)imgfile;
|
boot->image = (IsoFile*)imgfile;
|
||||||
iso_node_ref(imgfile); /* get our ref */
|
boot->appended_idx = part_idx;
|
||||||
|
if (imgfile != NULL)
|
||||||
|
iso_node_ref(imgfile); /* get our ref */
|
||||||
boot->bootable = 1;
|
boot->bootable = 1;
|
||||||
boot->seems_boot_info_table = 0;
|
boot->seems_boot_info_table = 0;
|
||||||
boot->seems_grub2_boot_info = 0;
|
boot->seems_grub2_boot_info = 0;
|
||||||
@ -538,8 +566,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
catalog->bootimages[i] = NULL;
|
catalog->bootimages[i] = NULL;
|
||||||
catalog->node = cat_node;
|
catalog->node = cat_node;
|
||||||
catalog->sort_weight = 1000000000; /* very high */
|
catalog->sort_weight = 1000000000; /* very high */
|
||||||
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
if (boot_node != NULL)
|
||||||
boot_node->sort_weight = 2;
|
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
iso_node_ref((IsoNode*)cat_node);
|
iso_node_ref((IsoNode*)cat_node);
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
|
||||||
@ -555,7 +584,8 @@ boot_image_cleanup:;
|
|||||||
iso_node_unref((IsoNode*)cat_node);
|
iso_node_unref((IsoNode*)cat_node);
|
||||||
}
|
}
|
||||||
if (boot_image) {
|
if (boot_image) {
|
||||||
iso_node_unref((IsoNode*)boot_image->image);
|
if (boot_image->image != NULL)
|
||||||
|
iso_node_unref((IsoNode*)boot_image->image);
|
||||||
free(boot_image);
|
free(boot_image);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -719,8 +749,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
if (boot_node != NULL)
|
||||||
boot_node->sort_weight = 2;
|
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||||
catalog->num_bootimages++;
|
catalog->num_bootimages++;
|
||||||
if (boot != NULL)
|
if (boot != NULL)
|
||||||
@ -827,12 +858,13 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
|||||||
* Usable for the Default Entry
|
* Usable for the Default Entry
|
||||||
* and for Section Entries with Selection criteria type == 0
|
* and for Section Entries with Selection criteria type == 0
|
||||||
*/
|
*/
|
||||||
static void
|
static
|
||||||
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||||
{
|
{
|
||||||
struct el_torito_boot_image *img;
|
struct el_torito_boot_image *img;
|
||||||
struct el_torito_section_entry *se =
|
struct el_torito_section_entry *se =
|
||||||
(struct el_torito_section_entry*)buf;
|
(struct el_torito_section_entry*)buf;
|
||||||
|
int app_idx;
|
||||||
|
|
||||||
img = t->catalog->bootimages[idx];
|
img = t->catalog->bootimages[idx];
|
||||||
|
|
||||||
@ -840,16 +872,37 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
|||||||
se->boot_media_type[0] = img->type;
|
se->boot_media_type[0] = img->type;
|
||||||
iso_lsb(se->load_seg, img->load_seg, 2);
|
iso_lsb(se->load_seg, img->load_seg, 2);
|
||||||
se->system_type[0] = img->partition_type;
|
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);
|
if (t->boot_appended_idx[idx] >= 0) {
|
||||||
|
app_idx = t->boot_appended_idx[idx];
|
||||||
|
if (t->appended_part_size[app_idx] * 4 > 65535) {
|
||||||
|
if (img->platform_id == 0xef)
|
||||||
|
iso_lsb(se->sec_count, 0, 2);
|
||||||
|
else
|
||||||
|
iso_lsb(se->sec_count, 65535, 2);
|
||||||
|
} else {
|
||||||
|
if (t->appended_part_size[app_idx] == 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition which shall serve as boot image does not exist");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2);
|
||||||
|
}
|
||||||
|
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
|
||||||
|
} else {
|
||||||
|
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];
|
se->selec_criteria[0] = img->selection_crit[0];
|
||||||
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
|
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
|
||||||
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int catalog_open(IsoStream *stream)
|
int catalog_open(IsoStream *stream)
|
||||||
{
|
{
|
||||||
int i, j, k, num_entries;
|
int i, j, k, num_entries, ret;
|
||||||
struct catalog_stream *data;
|
struct catalog_stream *data;
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
struct el_torito_boot_catalog *cat;
|
struct el_torito_boot_catalog *cat;
|
||||||
@ -873,7 +926,9 @@ int catalog_open(IsoStream *stream)
|
|||||||
boots[0]->platform_id, boots[0]->id_string);
|
boots[0]->platform_id, boots[0]->id_string);
|
||||||
|
|
||||||
/* write default entry = first boot image */
|
/* write default entry = first boot image */
|
||||||
write_section_entry(data->buffer + 32, data->target, 0);
|
ret = write_section_entry(data->buffer + 32, data->target, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
|
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
|
||||||
wpt = data->buffer + 64;
|
wpt = data->buffer + 64;
|
||||||
@ -894,7 +949,9 @@ int catalog_open(IsoStream *stream)
|
|||||||
write_section_header(wpt, data->target, i, num_entries);
|
write_section_header(wpt, data->target, i, num_entries);
|
||||||
wpt += 32;
|
wpt += 32;
|
||||||
for (j = 0; j < num_entries; j++) {
|
for (j = 0; j < num_entries; j++) {
|
||||||
write_section_entry(wpt, data->target, i);
|
ret = write_section_entry(wpt, data->target, i);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
wpt += 32;
|
wpt += 32;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -1132,6 +1189,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
|
|||||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
"Isolinux image too small. We won't patch it.");
|
"Isolinux image too small. We won't patch it.");
|
||||||
}
|
}
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply ISOLINUX patching outside of ISO 9660 filesystem.");
|
||||||
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
|
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
|
||||||
t->bootsrc[idx]->sections[0].block,
|
t->bootsrc[idx]->sections[0].block,
|
||||||
(uint32_t) imgsize);
|
(uint32_t) imgsize);
|
||||||
@ -1151,7 +1211,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
|
|||||||
|
|
||||||
if (imgsize < pos + 8)
|
if (imgsize < pos + 8)
|
||||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
"Isolinux image too small for GRUB2. Will not patch it.");
|
"Boot image too small for GRUB2. Will not patch it.");
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply GRUB2 patching outside of ISO 9660 filesystem.");
|
||||||
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
|
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
|
||||||
iso_lsb((buf + pos), blk & 0xffffffff, 4);
|
iso_lsb((buf + pos), blk & 0xffffffff, 4);
|
||||||
iso_lsb((buf + pos + 4), blk >> 32, 4);
|
iso_lsb((buf + pos + 4), blk >> 32, 4);
|
||||||
@ -1174,6 +1237,10 @@ int iso_patch_eltoritos(Ecma119Image *t)
|
|||||||
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
||||||
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
||||||
continue;
|
continue;
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply boot image patching outside of ISO 9660 filesystem");
|
||||||
|
|
||||||
original = t->bootsrc[idx]->stream;
|
original = t->bootsrc[idx]->stream;
|
||||||
size = (size_t) iso_stream_get_size(original);
|
size = (size_t) iso_stream_get_size(original);
|
||||||
if (size > Libisofs_elto_max_patchablE)
|
if (size > Libisofs_elto_max_patchablE)
|
||||||
@ -1281,8 +1348,8 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
{
|
{
|
||||||
int ret, idx, outsource_efi = 0;
|
int ret, idx, outsource_efi = 0;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
IsoFile *bootimg;
|
IsoFile *bootimg = NULL;
|
||||||
IsoFileSrc *src;
|
IsoFileSrc *src = NULL;
|
||||||
|
|
||||||
writer = calloc(1, sizeof(IsoImageWriter));
|
writer = calloc(1, sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
@ -1315,6 +1382,19 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
|
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
|
||||||
outsource_efi = 1;
|
outsource_efi = 1;
|
||||||
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
||||||
|
target->bootsrc[idx] = NULL;
|
||||||
|
if (target->catalog->bootimages[idx]->appended_idx >= 0) {
|
||||||
|
/* Use an appended partition as boot image rather than IsoFile */
|
||||||
|
target->boot_appended_idx[idx] =
|
||||||
|
target->catalog->bootimages[idx]->appended_idx;
|
||||||
|
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
|
||||||
|
(target->system_area_options & 3) == 1) {
|
||||||
|
/* ISO will not be a partition. It can span the whole image. */
|
||||||
|
target->pvd_size_is_total_size = 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bootimg = target->catalog->bootimages[idx]->image;
|
bootimg = target->catalog->bootimages[idx]->image;
|
||||||
ret = iso_file_src_create(target, bootimg, &src);
|
ret = iso_file_src_create(target, bootimg, &src);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -53,6 +53,9 @@ struct el_torito_boot_catalog {
|
|||||||
struct el_torito_boot_image {
|
struct el_torito_boot_image {
|
||||||
IsoFile *image;
|
IsoFile *image;
|
||||||
|
|
||||||
|
/* Overrides .image if >= 0 : array index of appended partition */
|
||||||
|
int appended_idx;
|
||||||
|
|
||||||
unsigned int bootable:1; /**< If the entry is bootable. */
|
unsigned int bootable:1; /**< If the entry is bootable. */
|
||||||
/**
|
/**
|
||||||
* Whether the boot image seems to contain a boot_info_table
|
* Whether the boot image seems to contain a boot_info_table
|
||||||
|
@ -3402,6 +3402,9 @@ int iso_image_get_pvd_times(IsoImage *image,
|
|||||||
* returns an error and the image remains unmodified.
|
* returns an error and the image remains unmodified.
|
||||||
* @param image_path
|
* @param image_path
|
||||||
* The absolute path of a IsoFile to be used as default boot image.
|
* The absolute path of a IsoFile to be used as default boot image.
|
||||||
|
|
||||||
|
>>> or --interval:appended_partition_$number...
|
||||||
|
|
||||||
* @param type
|
* @param type
|
||||||
* The boot media type. This can be one of 3 types:
|
* The boot media type. This can be one of 3 types:
|
||||||
* - Floppy emulation: Boot image file must be exactly
|
* - Floppy emulation: Boot image file must be exactly
|
||||||
@ -3443,7 +3446,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
* The image to which the boot image shall be added.
|
* The image to which the boot image shall be added.
|
||||||
* returns an error and the image remains unmodified.
|
* returns an error and the image remains unmodified.
|
||||||
* @param image_path
|
* @param image_path
|
||||||
* The absolute path of a IsoFile to be used as default boot image.
|
* The absolute path of a IsoFile to be used as boot image.
|
||||||
|
|
||||||
|
>>> or --interval:appended_partition_$number...
|
||||||
|
|
||||||
* @param type
|
* @param type
|
||||||
* The boot media type. See iso_image_set_boot_image
|
* The boot media type. See iso_image_set_boot_image
|
||||||
* @param flag
|
* @param flag
|
||||||
@ -3488,6 +3494,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
* @param imgnode
|
* @param imgnode
|
||||||
* When not NULL, it will be filled with the image tree node. No extra ref
|
* When not NULL, it will be filled with the image tree node. No extra ref
|
||||||
* is added, you can use iso_node_ref() to get one if you need it.
|
* is added, you can use iso_node_ref() to get one if you need it.
|
||||||
|
|
||||||
|
>>> The returned value is NULL if the boot image source is no IsoFile.
|
||||||
|
|
||||||
* @param catnode
|
* @param catnode
|
||||||
* When not NULL, it will be filled with the catnode tree node. No extra
|
* When not NULL, it will be filled with the catnode tree node. No extra
|
||||||
* ref is added, you can use iso_node_ref() to get one if you need it.
|
* ref is added, you can use iso_node_ref() to get one if you need it.
|
||||||
@ -3545,6 +3554,11 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
|
|||||||
* @param bootnodes
|
* @param bootnodes
|
||||||
* Returns NULL or an allocated array of pointers to the IsoFile nodes
|
* Returns NULL or an allocated array of pointers to the IsoFile nodes
|
||||||
* which bear the content of the boot images in boots.
|
* which bear the content of the boot images in boots.
|
||||||
|
|
||||||
|
>>> An array entry is NULL if the boot image source is no IsoFile.
|
||||||
|
|
||||||
|
>>> Need getter for partition index
|
||||||
|
|
||||||
* @param flag
|
* @param flag
|
||||||
* Bitfield for control purposes. Unused yet. Submit 0.
|
* Bitfield for control purposes. Unused yet. Submit 0.
|
||||||
* @return
|
* @return
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "system_area.h"
|
#include "system_area.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "messages.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
|
||||||
@ -60,7 +62,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-2014 Thomas Schmitt
|
and 2008-2015 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.
|
||||||
@ -408,6 +410,7 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
{
|
{
|
||||||
int i, ilx_opts, j, ret, num_img;
|
int i, ilx_opts, j, ret, num_img;
|
||||||
uint32_t block_count;
|
uint32_t block_count;
|
||||||
|
uint64_t start_block;
|
||||||
uint8_t gpt_name[72];
|
uint8_t gpt_name[72];
|
||||||
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
static uint8_t basic_data_uuid[16] = {
|
static uint8_t basic_data_uuid[16] = {
|
||||||
@ -430,11 +433,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
num_img = 0;
|
num_img = 0;
|
||||||
for (i = 0; i < num_img; i++) {
|
for (i = 0; i < num_img; i++) {
|
||||||
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
|
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
|
||||||
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
|
if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) &&
|
||||||
|
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
|
||||||
if (*gpt_count < 128)
|
if (*gpt_count < 128)
|
||||||
gpt_idx[*gpt_count]= i;
|
gpt_idx[*gpt_count]= i;
|
||||||
(*gpt_count)++;
|
(*gpt_count)++;
|
||||||
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
if ((flag & 1) &&
|
||||||
|
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
|
||||||
/* Register GPT entry */
|
/* Register GPT entry */
|
||||||
memset(gpt_name, 0, 72);
|
memset(gpt_name, 0, 72);
|
||||||
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
|
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
|
||||||
@ -443,13 +448,21 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
uuid = hfs_uuid;
|
uuid = hfs_uuid;
|
||||||
else
|
else
|
||||||
uuid = basic_data_uuid;
|
uuid = basic_data_uuid;
|
||||||
block_count = 0;
|
if (t->boot_appended_idx[i] >= 0) {
|
||||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
block_count = t->appended_part_size[
|
||||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
t->boot_appended_idx[i]];
|
||||||
|
start_block = ((uint64_t) t->appended_part_start[
|
||||||
|
t->boot_appended_idx[i]]) * 4;
|
||||||
|
} else {
|
||||||
|
block_count = 0;
|
||||||
|
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||||
|
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||||
|
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
|
||||||
|
* 4;
|
||||||
|
}
|
||||||
ret = iso_quick_gpt_entry(
|
ret = iso_quick_gpt_entry(
|
||||||
t->gpt_req, &(t->gpt_req_count),
|
t->gpt_req, &(t->gpt_req_count),
|
||||||
((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
|
start_block, ((uint64_t) block_count) * 4,
|
||||||
((uint64_t) block_count) * 4,
|
|
||||||
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
|
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -457,13 +470,22 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
}
|
}
|
||||||
if ((ilx_opts & 256) && !(flag & 2)) {
|
if ((ilx_opts & 256) && !(flag & 2)) {
|
||||||
(*apm_count)++;
|
(*apm_count)++;
|
||||||
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
if ((flag & 1) &&
|
||||||
|
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
|
||||||
/* Register APM entry */
|
/* Register APM entry */
|
||||||
block_count = 0;
|
if (t->boot_appended_idx[i] >= 0) {
|
||||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
block_count = t->appended_part_size[
|
||||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
t->boot_appended_idx[i]];
|
||||||
|
start_block = t->appended_part_start[
|
||||||
|
t->boot_appended_idx[i]];
|
||||||
|
} else {
|
||||||
|
block_count = 0;
|
||||||
|
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||||
|
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||||
|
start_block = t->bootsrc[i]->sections[0].block;
|
||||||
|
}
|
||||||
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
|
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
|
||||||
t->bootsrc[i]->sections[0].block,
|
(uint32_t) start_block,
|
||||||
block_count, "EFI", "Apple_HFS");
|
block_count, "EFI", "Apple_HFS");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -546,13 +568,18 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
|||||||
0xfe, 0xff, 0xff,
|
0xfe, 0xff, 0xff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL) {
|
||||||
|
(*gpt_cursor)++;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
wpt[0] = 0;
|
wpt[0] = 0;
|
||||||
memcpy(wpt + 1, dummy_chs, 3);
|
memcpy(wpt + 1, dummy_chs, 3);
|
||||||
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
|
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
|
||||||
if (((ilx_opts >> 2) & 63) == 2)
|
if (((ilx_opts >> 2) & 63) == 2)
|
||||||
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
|
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
|
||||||
else
|
else
|
||||||
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
|
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */
|
||||||
|
|
||||||
memcpy(wpt + 5, dummy_chs, 3);
|
memcpy(wpt + 5, dummy_chs, 3);
|
||||||
|
|
||||||
@ -589,6 +616,10 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
|
if (t->bootsrc[0] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
|
||||||
|
|
||||||
if (flag & 2) {
|
if (flag & 2) {
|
||||||
part_number = 1;
|
part_number = 1;
|
||||||
part_offset = 1;
|
part_offset = 1;
|
||||||
|
@ -1820,6 +1820,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
/* Check for isolinux image with magic number of 3.72 and produce
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
*/
|
*/
|
||||||
|
if (t->bootsrc[0] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
|
||||||
if (img_blocks < 0x80000000) {
|
if (img_blocks < 0x80000000) {
|
||||||
int_img_blocks= img_blocks;
|
int_img_blocks= img_blocks;
|
||||||
} else {
|
} else {
|
||||||
@ -2062,6 +2065,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
|
|
||||||
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
|
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
|
||||||
/* Patch MBR for GRUB2 */
|
/* Patch MBR for GRUB2 */
|
||||||
|
if (t->bootsrc[0] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Cannot refer by GRUB2 MBR to data outside of ISO 9660 filesystem.");
|
||||||
blk = t->bootsrc[0]->sections[0].block * 4 +
|
blk = t->bootsrc[0]->sections[0].block * 4 +
|
||||||
Libisofs_grub2_mbr_patch_offsT;
|
Libisofs_grub2_mbr_patch_offsT;
|
||||||
wpt = buf + Libisofs_grub2_mbr_patch_poS;
|
wpt = buf + Libisofs_grub2_mbr_patch_poS;
|
||||||
|
Loading…
Reference in New Issue
Block a user