New API calls iso_image_add_mips_boot_file(), iso_image_get_mips_boot_files(),

iso_image_give_up_mips_boot().
The preliminary ban has been lifted to combine El Torito and MIPS Big Endian
boot facilities.
The current state of boot record documentation has been added to bzr.
This commit is contained in:
2010-10-12 20:24:17 +02:00
parent 2a087f6f39
commit f33df0ef29
10 changed files with 478 additions and 11 deletions

View File

@ -1109,3 +1109,35 @@ int ecma119_tree_create(Ecma119Image *img)
return ISO_SUCCESS;
}
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
static
Ecma119Node *search_iso_node(Ecma119Node *root, IsoNode *node)
{
size_t i;
Ecma119Node *res = NULL;
if (root->node == node)
return root;
for (i = 0; i < root->info.dir->nchildren && res == NULL; i++) {
if (root->info.dir->children[i]->type == ECMA119_DIR)
res = search_iso_node(root->info.dir->children[i], node);
else if (root->info.dir->children[i]->node == node)
res = root->info.dir->children[i];
}
return res;
}
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node)
{
Ecma119Node *res = NULL;
if (img->root != NULL)
res = search_iso_node(img->root, node);
return res;
}

View File

@ -90,4 +90,11 @@ int ecma119_tree_create(Ecma119Image *img);
*/
void ecma119_node_free(Ecma119Node *node);
/**
* Search the tree for a certain IsoNode and return its owning Ecma119Node
* or NULL.
*/
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
#endif /*LIBISO_ECMA119_TREE_H_*/

View File

@ -1091,10 +1091,14 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
#ifndef Libisofs_mips_boot_file_pathS
/* >>> Preliminary: No El Torito with system area type other than MBR */
if (t->system_area_options & 0xfc)
return ISO_SUCCESS;
#endif
/* Patch the boot image info tables if indicated */
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
@ -1155,10 +1159,14 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
t = writer->target;
cat = t->catalog;
#ifndef Libisofs_mips_boot_file_pathS
/* >>> Preliminary: No El Torito with system area type other than MBR */
if (t->system_area_options & 0xfc)
return ISO_SUCCESS;
#endif
iso_msg_debug(t->image->id, "Write El-Torito boot record");
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
@ -1233,10 +1241,14 @@ int eltorito_writer_create(Ecma119Image *target)
}
}
#ifndef Libisofs_mips_boot_file_pathS
/* >>> Preliminary: No El Torito with system area type other than MBR */
if (target->system_area_options & 0xfc)
return ISO_SUCCESS;
#endif
/* we need the bootable volume descriptor */
target->curblock++;
return ISO_SUCCESS;

View File

@ -36,7 +36,7 @@
*/
int iso_image_new(const char *name, IsoImage **image)
{
int res;
int res, i;
IsoImage *img;
if (image == NULL) {
@ -80,6 +80,9 @@ int iso_image_new(const char *name, IsoImage **image)
}
img->system_area_data = NULL;
img->system_area_options = 0;
img->num_mips_boot_files = 0;
for (i = 0; i < 15; i++)
img->mips_boot_file_paths[i] = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -103,7 +106,7 @@ void iso_image_ref(IsoImage *image)
}
/**
* Decrements the reference couting of the given image.
* Decrements the reference counting of the given image.
* If it reaches 0, the image is free, together with its tree nodes (whether
* their refcount reach 0 too, of course).
*/
@ -127,6 +130,7 @@ void iso_image_unref(IsoImage *image)
iso_node_builder_unref(image->builder);
iso_filesystem_unref(image->fs);
el_torito_boot_catalog_free(image->bootcat);
iso_image_give_up_mips_boot(image, 0);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -613,3 +617,41 @@ int iso_image_generator_is_running(IsoImage *image)
return image->generator_is_running;
}
/* API */
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag)
{
if (image->num_mips_boot_files >= 15)
return ISO_BOOT_TOO_MANY_MIPS;
image->mips_boot_file_paths[image->num_mips_boot_files] = strdup(path);
if (image->mips_boot_file_paths[image->num_mips_boot_files] == NULL)
return ISO_OUT_OF_MEM;
image->num_mips_boot_files++;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
paths[i] = image->mips_boot_file_paths[image->num_mips_boot_files];
for (; i < 15; i++)
paths[i] = NULL;
return image->num_mips_boot_files;
}
/* API */
int iso_image_give_up_mips_boot(IsoImage *image, int flag)
{
int i;
for (i = 0; i < image->num_mips_boot_files; i++)
if (image->mips_boot_file_paths[i] != NULL) {
free(image->mips_boot_file_paths[i]);
image->mips_boot_file_paths[i] = NULL;
}
image->num_mips_boot_files = 0;
return ISO_SUCCESS;
}

View File

@ -58,6 +58,14 @@ struct Iso_Image
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
int system_area_options;
/*
* Up to 15 boot files can be referred by a MIPS Big Endian Volume Header.
The mips_boot_file_paths are ISO 9660 Rock Ridge paths.
*/
int num_mips_boot_files;
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
/* image identifier, for message origin identifier */
int id;

View File

@ -1771,10 +1771,8 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* else: unspecified type
* @since 0.6.38
* 1= MIPS Big Endian Volume Header
>>> EXPERIMENTAL:
Submit MIPS boot image files as El Torito Boot image to
iso_image_set_boot_image() , iso_image_add_boot_image().
No El Torito info will be produced with system area type 1.
* Submit up to 15 MIPS Big Endian boot files by
* iso_image_add_mips_boot_file().
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2969,6 +2967,52 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
int iso_image_get_system_area(IsoImage *img, char data[32768],
int *options, int flag);
/**
* Add a MIPS Big Endian boot file to the image. Up to 15 such files can be
* written into a MIPS Big Endian Volume Header if this is enabled by
* value 1 in iso_write_opts_set_system_area() option bits 2 to 7.
* @param img
* The image to be manipulated.
* @param path
* Absolute path of the boot file in the ISO 9660 Rock Ridge tree
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 on success, < 0 error
* @since 0.6.38
*/
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag);
/**
* Obtain the number of added MIPS Big Endian boot files and pointers to
* their paths in the ISO 9660 Rock Ridge tree.
* @param img
* The image to be inquired.
* @param paths
* An array of pointers to be set to the registered boot file paths.
* This are just pointers to data inside IsoImage. Do not free() them.
* Eventually make own copies of the data before manipulating the image.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* >= 0 is the number of valid path pointers , <0 means error
* @since 0.6.38
*/
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
/**
* Clear the list of MIPS Big Endian boot file paths.
* @param img
* The image to be manipulated.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
* @return
* 1 is success , <0 means error
* @since 0.6.38
*/
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
/**
* Increments the reference counting of the given node.
*
@ -6262,7 +6306,14 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Failed to process file for Jigdo Template Extraction
(MISHAP, HIGH, -366) */
#define ISO_LIBJTE_FILE_FAILED 0xE430FE92
#define ISO_LIBJTE_FILE_FAILED 0xE430FE92
/** Too many MIPS Big Endian boot files given (max. 15) (FAILURE, HIGH, -365)*/
#define ISO_BOOT_TOO_MANY_MIPS 0xE830FE91
/** MIPS Big Endian boot file missing in image (MISHAP, HIGH, -364) */
#define ISO_BOOT_MIPS_MISSING 0xE430FE90
/* Internal developer note:
@ -6492,4 +6543,8 @@ struct burn_source {
*/
/* Try to address MIPS Big Endian boot files via their ISO/RR paths
*/
#define Libisofs_mips_boot_file_pathS yes
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -68,6 +68,7 @@ iso_get_local_charset;
iso_get_messenger;
iso_gzip_get_refcounts;
iso_image_add_boot_image;
iso_image_add_mips_boot_file;
iso_image_attach_data;
iso_image_create_burn_source;
iso_image_filesystem_new;
@ -89,6 +90,7 @@ iso_image_get_biblio_file_id;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
iso_image_get_mips_boot_files;
iso_image_get_msg_id;
iso_image_get_publisher_id;
iso_image_get_root;
@ -97,6 +99,7 @@ iso_image_get_system_area;
iso_image_get_system_id;
iso_image_get_volset_id;
iso_image_get_volume_id;
iso_image_give_up_mips_boot;
iso_image_import;
iso_image_new;
iso_image_ref;

View File

@ -350,6 +350,10 @@ const char *iso_error_to_msg(int errcode)
return "Failed to finish Jigdo Template Extraction";
case ISO_LIBJTE_FILE_FAILED:
return "Failed to process file for Jigdo Template Extraction";
case ISO_BOOT_TOO_MANY_MIPS:
return "Too many MIPS Big Endian boot files given (max. 15)";
case ISO_BOOT_MIPS_MISSING:
return "MIPS Big Endian boot file missing in image";
default:
return "Unknown error";
}

View File

@ -16,6 +16,9 @@
#include "system_area.h"
#include "eltorito.h"
#include "filesrc.h"
#include "ecma119_tree.h"
#include "image.h"
#include "messages.h"
#include <string.h>
#include <stdio.h>
@ -209,8 +212,8 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
}
/* This function was implemented according to a byte map which was derived
by Thomas Schmitt from
/* This function was implemented according to doc/boot_sectors.txt section
"MIPS Volume Header" which was derived by Thomas Schmitt from
cdrkit-1.1.10/genisoimage/boot-mips.c by Steve McIntyre which is based
on work of Florian Lohoff and Thiemo Seufer who possibly learned from
documents of MIPS Computer Systems, Inc. and Silicon Graphics Computer
@ -224,6 +227,15 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
off_t image_size;
static uint32_t bps = 512, spt = 32;
#ifdef Libisofs_mips_boot_file_pathS
Ecma119Node *ecma_node;
IsoNode *node;
IsoStream *stream;
off_t file_size;
uint32_t file_lba;
int ret;
#endif
memset(buf, 0, 16 * BLOCK_SIZE);
image_size = t->curblock * 2048;
@ -256,6 +268,58 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
/* 80 - 83 | boot_block | ISO 9660 LBA of boot file * 4 */
/* 84 - 87 | boot_bytes | File length in bytes */
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
#ifdef Libisofs_mips_boot_file_pathS
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
ret = iso_tree_path_to_node(t->image,
t->image->mips_boot_file_paths[idx], &node);
if (ret < 0) {
iso_msg_submit(t->image->id, ISO_BOOT_MIPS_MISSING, 0,
"Cannot find MIPS boot file '%s'",
t->image->mips_boot_file_paths[idx]);
return ISO_BOOT_MIPS_MISSING;
}
if (node->type != LIBISO_FILE) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Designated MIPS boot file is not a data file: '%s'",
t->image->mips_boot_file_paths[idx]);
return ISO_BOOT_IMAGE_NOT_VALID;
}
namept = (char *) iso_node_get_name(node);
name_field = (char *) (buf + (72 + 16 * idx));
strncpy(name_field, namept, 8);
ecma_node= ecma119_search_iso_node(t, node);
if (ecma_node != NULL) {
if (ecma_node->type != ECMA119_FILE) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Program error: Ecma119Node of IsoFile is no ECMA119_FILE: '%s'",
t->image->mips_boot_file_paths[idx]);
return ISO_ASSERT_FAILURE;
}
} else {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Program error: IsoFile has no Ecma119Node: '%s'",
t->image->mips_boot_file_paths[idx]);
return ISO_ASSERT_FAILURE;
}
file_lba = ecma_node->info.file->sections[0].block;
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
stream = iso_file_get_stream((IsoFile *) node);
file_size = iso_stream_get_size(stream);
/* >>> shall i really round up to 2048 ? */
iso_msb(buf + (72 + 16 * idx) + 12,
((file_size + 2047) / 2048 ) * 2048, 4);
}
#else /* Libisofs_mips_boot_file_pathS */
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
/* >>> skip non-MIPS boot images */;
@ -273,6 +337,8 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
4);
}
#endif /* ! Libisofs_mips_boot_file_pathS */
/* 408 - 411 | part_blks | Number of 512 byte blocks in partition */
blocks = (image_size + bps - 1) / bps;
iso_msb(buf + 408, blocks, 4);
@ -357,8 +423,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ret;
} else if(sa_type == 1) {
ret = make_mips_volume_header(t, buf, 0);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
if (ret != ISO_SUCCESS)
return ret;
} else if(t->partition_offset > 0) {
/* Write a simple partition table. */
ret = make_grub_msdos_label(img_blocks, buf, 2);