New system area type 2 = MIPS Little Endian / DEC Boot Block.

This commit is contained in:
Thomas Schmitt 2010-10-15 12:19:53 +02:00
parent 48316af1d9
commit 0d35100eb0
4 changed files with 170 additions and 23 deletions

View File

@ -1647,6 +1647,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
#endif /* Libisofs_with_libjtE */
target->mipsel_e_entry = 0;
target->mipsel_p_offset = 0;
target->mipsel_p_vaddr = 0;
target->mipsel_p_filesz = 0;
target->tail_blocks = opts->tail_blocks;
/*
@ -1810,12 +1815,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
for (i = 0; i < target->nwriters; ++i) {
IsoImageWriter *writer = target->writers[i];
#define Libisofs_patch_ticket_145 yes
#ifdef Libisofs_patch_ticket_145
/* Delaying boot image patching until new LBA is known */
if (i == el_torito_writer_index)
continue;
#endif
/* Exposing address of data start to IsoWriteOpts */
if (i == file_src_writer_index) {
@ -1827,8 +1829,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup;
}
}
#ifdef Libisofs_patch_ticket_145
/* Now perform delayed image patching */
/* Now perform delayed image patching and System Area preparations */
if (el_torito_writer_index >= 0) {
IsoImageWriter *writer = target->writers[el_torito_writer_index];
ret = writer->compute_data_blocks(writer);
@ -1836,7 +1838,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup;
}
}
#endif /* Libisofs_patch_ticket_145 */
if (((target->system_area_options & 0xfc) >> 2) == 2) {
ret = iso_read_mipsel_elf(target, 0);
if (ret < 0)
goto target_cleanup;
}
/* create the ring buffer */
if (opts->overwrite != NULL &&

View File

@ -588,6 +588,12 @@ struct ecma119_image
struct libjte_env *libjte_handle;
#endif /* Libisofs_with_libjtE */
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
uint32_t tail_blocks;
};

View File

@ -396,34 +396,30 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
}
/* This function was implemented according to doc/boot_sectors.txt section
"MIPS Little Endian" which was derived by Thomas Schmitt from
/* The following two functions were implemented according to
doc/boot_sectors.txt section "MIPS Little Endian" which was derived
by Thomas Schmitt from
cdrkit-1.1.10/genisoimage/boot-mipsel.c by Steve McIntyre which is based
on work of Florian Lohoff and Thiemo Seufer, and from <elf.h> by Free
Software Foundation, Inc.
This function itself is entirely under copyright (C) 2010 Thomas Schmitt.
Both functions are entirely under copyright (C) 2010 Thomas Schmitt.
*/
static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
/**
* Read the necessary ELF information from the first MIPS boot file.
* This is done before image writing starts.
*/
int iso_read_mipsel_elf(Ecma119Image *t, int flag)
{
uint32_t load_adr, exec_adr, seg_size, seg_start, p_offset, p_filesz;
uint32_t phdr_adr;
off_t image_size;
uint32_t phdr_adr, todo, count;
int ret;
uint8_t elf_buf[32];
char *path = NULL;
uint8_t elf_buf[2048];
IsoNode *iso_node;
Ecma119Node *ecma_node;
IsoStream *stream;
FILE *fp = NULL;
/* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512);
/* <<< Unused. No partition table or such ? */
image_size = t->curblock * 2048;
if (t->image->num_mips_boot_files <= 0)
return ISO_SUCCESS; /* There seems to be no partition table */
return ISO_SUCCESS;
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
&iso_node, &ecma_node, "MIPS boot file", 0);
@ -431,6 +427,135 @@ static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
return ret;
stream = iso_file_get_stream((IsoFile *) iso_node);
ret = iso_stream_open(stream);
if (ret < 0) {
iso_msg_submit(t->image->id, ret, 0,
"Cannot open designated MIPS boot file '%s'",
t->image->mips_boot_file_paths[0]);
return ret;
}
ret = iso_stream_read(stream, elf_buf, 32);
if (ret != 32) {
cannot_read:;
iso_stream_close(stream);
iso_msg_submit(t->image->id, ret, 0,
"Cannot read from designated MIPS boot file '%s'",
t->image->mips_boot_file_paths[0]);
return ret;
}
/* 24 - 27 | e_entry | Entry point virtual address */
t->mipsel_e_entry = iso_read_lsb(elf_buf + 24, 4);
/* 28 - 31 | e_phoff | Program header table file offset */
phdr_adr = iso_read_lsb(elf_buf + 28, 4);
/* Skip stream up to byte address phdr_adr */
todo = phdr_adr - 32;
while (todo > 0) {
if (todo > 2048)
count = 2048;
else
count = todo;
todo -= count;
ret = iso_stream_read(stream, elf_buf, count);
if (ret != count)
goto cannot_read;
}
ret = iso_stream_read(stream, elf_buf, 20);
if (ret != 20)
goto cannot_read;
/* 4 - 7 | p_offset | Segment file offset */
t->mipsel_p_offset = iso_read_lsb(elf_buf + 4, 4);
/* 8 - 11 | p_vaddr | Segment virtual address */
t->mipsel_p_vaddr = iso_read_lsb(elf_buf + 8, 4);
/* 16 - 19 | p_filesz | Segment size in file */
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
iso_stream_close(stream);
return ISO_SUCCESS;
}
/**
* Write DEC Bootblock from previously read ELF parameters.
* This is done when image writing has already begun.
*/
static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
{
#ifndef NIX
int ret;
uint32_t seg_size, seg_start;
IsoNode *iso_node;
Ecma119Node *ecma_node;
/* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512);
if (t->image->num_mips_boot_files <= 0)
return ISO_SUCCESS;
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
&iso_node, &ecma_node, "MIPS boot file", 0);
if (ret < 0)
return ret;
/* 8 - 11 | 0x0002757a | Magic number */
iso_lsb(buf + 8, 0x0002757a, 4);
/* 12 - 15 | 1 | Mode 1: Multi extent boot */
iso_lsb(buf + 12, 1, 4);
/* 16 - 19 | load_adr | Load address */
iso_lsb(buf + 16, t->mipsel_p_vaddr, 4);
/* 20 - 23 | exec_adr | Execution address */
iso_lsb(buf + 20, t->mipsel_e_entry, 4);
/* 24 - 27 | seg_size | Segment size in file. */
seg_size = (t->mipsel_p_filesz + 511) / 512;
iso_lsb(buf + 24, seg_size, 4);
/* 28 - 31 | seg_start | Segment file offset */
seg_start = ecma_node->info.file->sections[0].block * 4
+ (t->mipsel_p_offset + 511) / 512;
iso_lsb(buf + 28, seg_start, 4);
return ISO_SUCCESS;
#else
uint32_t load_adr, exec_adr, p_offset, p_filesz, phdr_adr;
uint8_t elf_buf[32];
char *path = NULL;
IsoNode *iso_node;
Ecma119Node *ecma_node;
IsoStream *stream;
FILE *fp = NULL;
off_t image_size;
int ret;
uint32_t seg_size, seg_start;
/* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512);
if (t->image->num_mips_boot_files <= 0)
return ISO_SUCCESS;
/* <<< Unused. No partition table or such ? */
image_size = t->curblock * 2048;
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
&iso_node, &ecma_node, "MIPS boot file", 0);
if (ret < 0)
return ret;
stream = iso_file_get_stream((IsoFile *) iso_node);
/* <<< This does not work for boot file in old session */
/* >>> Replace by iso_stream_open(), iso_stream_read() which has to be
@ -515,6 +640,9 @@ cannot_read:;
iso_lsb(buf + 28, seg_start, 4);
return ISO_SUCCESS;
#endif /* NIX */
}

View File

@ -46,4 +46,11 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
/**
* Read the necessary ELF information from the first MIPS boot file.
* See doc/boot_sectors.txt "DEC Boot Block" for "MIPS Little Endian".
*/
int iso_read_mipsel_elf(Ecma119Image *t, int flag);
#endif /* SYSTEM_AREA_H_ */