New API call iso_write_opts_set_partition_img().
This commit is contained in:
parent
ebb5937568
commit
b58d1e28ef
@ -266,9 +266,8 @@ Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
|
|||||||
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
||||||
|
|
||||||
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
||||||
heads, and remaining sectors. The nomenclature seems to stem from antique
|
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
|
||||||
drum storage.
|
drum storage.
|
||||||
C/H/S counting starts with 0/0/1, not 0/0/0.
|
|
||||||
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
||||||
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
||||||
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
||||||
@ -306,6 +305,7 @@ Byte Range | Value | Meaning
|
|||||||
451 - 453 | ========== | C/H/S address of last absolute sector in partition
|
451 - 453 | ========== | C/H/S address of last absolute sector in partition
|
||||||
451 - 451 | end_head | Heads part of end address.
|
451 - 451 | end_head | Heads part of end address.
|
||||||
452 - 452 | end_c_s | Bits 0 to 5 : Sectors part of end address.
|
452 - 452 | end_c_s | Bits 0 to 5 : Sectors part of end address.
|
||||||
|
| Values: 1 to 63, not 0.
|
||||||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||||
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
||||||
| |
|
| |
|
||||||
|
@ -107,7 +107,10 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
free(t->writers);
|
free(t->writers);
|
||||||
if (t->partition_root != NULL)
|
if (t->partition_root != NULL)
|
||||||
ecma119_node_free(t->partition_root);
|
ecma119_node_free(t->partition_root);
|
||||||
t->partition_root = NULL;
|
for (i = 0; i < 4; i++)
|
||||||
|
if (t->appended_partitions[i] != NULL)
|
||||||
|
free(t->appended_partitions[i]);
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1295,6 +1298,39 @@ static int finish_libjte(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||||
|
uint32_t blocks, int flag)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t buf[BLOCK_SIZE];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fp = fopen(path, "rb");
|
||||||
|
if (fp == NULL)
|
||||||
|
return ISO_BAD_PARTITION_FILE;
|
||||||
|
|
||||||
|
for (i = 0; i < blocks; i++) {
|
||||||
|
memset(buf, 0, BLOCK_SIZE);
|
||||||
|
if (fp != NULL) {
|
||||||
|
ret = fread(buf, 1, BLOCK_SIZE, fp);
|
||||||
|
if (ret != BLOCK_SIZE) {
|
||||||
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void *write_function(void *arg)
|
void *write_function(void *arg)
|
||||||
{
|
{
|
||||||
@ -1321,6 +1357,17 @@ void *write_function(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Append partition data */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (target->appended_partitions[i] == NULL)
|
||||||
|
continue;
|
||||||
|
res = write_mbr_partition_file(target, target->appended_partitions[i],
|
||||||
|
target->appended_part_size[i], 0);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Transplant checksum buffer from Ecma119Image to IsoImage */
|
/* Transplant checksum buffer from Ecma119Image to IsoImage */
|
||||||
transplant_checksum_buffer(target, 0);
|
transplant_checksum_buffer(target, 0);
|
||||||
|
|
||||||
@ -1469,7 +1516,6 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||||
{
|
{
|
||||||
@ -1589,6 +1635,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->partition_offset = opts->partition_offset;
|
target->partition_offset = opts->partition_offset;
|
||||||
target->partition_secs_per_head = opts->partition_secs_per_head;
|
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||||
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||||
|
if (target->partition_secs_per_head == 0)
|
||||||
|
target->partition_secs_per_head = 63;
|
||||||
|
if (target->partition_heads_per_cyl == 0)
|
||||||
|
target->partition_heads_per_cyl = 255;
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
target->partition_root = NULL;
|
target->partition_root = NULL;
|
||||||
target->partition_l_table_pos = 0;
|
target->partition_l_table_pos = 0;
|
||||||
@ -1646,12 +1696,24 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
target->tail_blocks = opts->tail_blocks;
|
||||||
|
|
||||||
target->mipsel_e_entry = 0;
|
target->mipsel_e_entry = 0;
|
||||||
target->mipsel_p_offset = 0;
|
target->mipsel_p_offset = 0;
|
||||||
target->mipsel_p_vaddr = 0;
|
target->mipsel_p_vaddr = 0;
|
||||||
target->mipsel_p_filesz = 0;
|
target->mipsel_p_filesz = 0;
|
||||||
|
|
||||||
target->tail_blocks = opts->tail_blocks;
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (opts->appended_partitions[i] != NULL) {
|
||||||
|
target->appended_partitions[i] =
|
||||||
|
strdup(opts->appended_partitions[i]);
|
||||||
|
if (target->appended_partitions[i] == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
target->appended_part_types[i] = opts->appended_part_types[i];
|
||||||
|
}
|
||||||
|
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Based on those options, create needed writers: iso, joliet...
|
* 2. Based on those options, create needed writers: iso, joliet...
|
||||||
@ -1843,6 +1905,18 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The volume space size is just the size of the last session, in
|
||||||
|
* case of ms images.
|
||||||
|
*/
|
||||||
|
target->vol_space_size = target->curblock - target->ms_block;
|
||||||
|
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||||
|
|
||||||
|
/* Add sizes of eventually appended partitions */
|
||||||
|
ret = iso_compute_append_partitions(target, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
/* create the ring buffer */
|
/* create the ring buffer */
|
||||||
if (opts->overwrite != NULL &&
|
if (opts->overwrite != NULL &&
|
||||||
opts->fifo_size / 2048 < 32 + target->partition_offset) {
|
opts->fifo_size / 2048 < 32 + target->partition_offset) {
|
||||||
@ -1936,13 +2010,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The volume space size is just the size of the last session, in
|
|
||||||
* case of ms images.
|
|
||||||
*/
|
|
||||||
target->vol_space_size = target->curblock - target->ms_block;
|
|
||||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
|
||||||
|
|
||||||
|
|
||||||
/* 4. Create and start writing thread */
|
/* 4. Create and start writing thread */
|
||||||
if (target->md5_session_checksum) {
|
if (target->md5_session_checksum) {
|
||||||
@ -2172,6 +2239,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
|||||||
|
|
||||||
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
IsoWriteOpts *wopts;
|
IsoWriteOpts *wopts;
|
||||||
|
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
@ -2231,6 +2299,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
wopts->tail_blocks = 0;
|
wopts->tail_blocks = 0;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
wopts->appended_partitions[i] = NULL;
|
||||||
|
|
||||||
*opts = wopts;
|
*opts = wopts;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -2238,13 +2308,17 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
|
|
||||||
void iso_write_opts_free(IsoWriteOpts *opts)
|
void iso_write_opts_free(IsoWriteOpts *opts)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(opts->output_charset);
|
free(opts->output_charset);
|
||||||
if (opts->system_area_data != NULL)
|
if (opts->system_area_data != NULL)
|
||||||
free(opts->system_area_data);
|
free(opts->system_area_data);
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
if (opts->appended_partitions[i] != NULL)
|
||||||
|
free(opts->appended_partitions[i]);
|
||||||
|
|
||||||
free(opts);
|
free(opts);
|
||||||
}
|
}
|
||||||
@ -2718,7 +2792,23 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle)
|
|||||||
|
|
||||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
|
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
|
||||||
{
|
{
|
||||||
opts->tail_blocks = num_blocks;
|
opts->tail_blocks = num_blocks;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||||
|
uint8_t partition_type, char *image_path, int flag)
|
||||||
|
{
|
||||||
|
if (partition_number < 1 || partition_number > 4)
|
||||||
|
return ISO_BAD_PARTITION_NO;
|
||||||
|
|
||||||
|
if (opts->appended_partitions[partition_number - 1] != NULL)
|
||||||
|
free(opts->appended_partitions[partition_number - 1]);
|
||||||
|
opts->appended_partitions[partition_number - 1] = strdup(image_path);
|
||||||
|
if (opts->appended_partitions[partition_number - 1] == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
opts->appended_part_types[partition_number - 1] = partition_type;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +334,11 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
uint32_t tail_blocks;
|
uint32_t tail_blocks;
|
||||||
|
|
||||||
|
/* Eventual disk file paths of prepared images which shall be appended
|
||||||
|
after the ISO image and described by partiton table entries in a MBR
|
||||||
|
*/
|
||||||
|
char *appended_partitions[4];
|
||||||
|
uint8_t appended_part_types[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -588,13 +593,20 @@ struct ecma119_image
|
|||||||
struct libjte_env *libjte_handle;
|
struct libjte_env *libjte_handle;
|
||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
uint32_t tail_blocks;
|
||||||
|
|
||||||
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
||||||
uint32_t mipsel_e_entry;
|
uint32_t mipsel_e_entry;
|
||||||
uint32_t mipsel_p_offset;
|
uint32_t mipsel_p_offset;
|
||||||
uint32_t mipsel_p_vaddr;
|
uint32_t mipsel_p_vaddr;
|
||||||
uint32_t mipsel_p_filesz;
|
uint32_t mipsel_p_filesz;
|
||||||
|
|
||||||
uint32_t tail_blocks;
|
char *appended_partitions[4];
|
||||||
|
uint8_t appended_part_types[4];
|
||||||
|
/* Counted in blocks of 2048 */
|
||||||
|
uint32_t appended_part_start[4];
|
||||||
|
uint32_t appended_part_size[4];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BP(a,b) [(b) - (a) + 1]
|
#define BP(a,b) [(b) - (a) + 1]
|
||||||
|
@ -1936,6 +1936,32 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cause an arbitrary data file to be appended to the ISO image and to be
|
||||||
|
* described by a partition table entry in an MBR at the start of the
|
||||||
|
* ISO image.
|
||||||
|
* The partition entry will bear the size of the image file rounded up to
|
||||||
|
* the next multiple of 2048 bytes.
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param partition_number
|
||||||
|
* Depicts the partition table entry which shall describe the
|
||||||
|
* appended image. Range 1 to 4.
|
||||||
|
* 1 will cause the whole ISO image to be unclaimable space before
|
||||||
|
* partition 1.
|
||||||
|
* @param image_path
|
||||||
|
* File address in the local file system.
|
||||||
|
* @param image_type
|
||||||
|
* The partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
||||||
|
* Linux Native Partition = 0x83. See fdisk command L.
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
*
|
||||||
|
* @since 0.6.38
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||||
|
uint8_t partition_type, char *image_path, int flag);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire the start address of the file data blocks after having used
|
* Inquire the start address of the file data blocks after having used
|
||||||
@ -6321,12 +6347,17 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
(MISHAP, HIGH, -366) */
|
(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)*/
|
/** Too many MIPS Big Endian boot files given (max. 15) (FAILURE, HIGH, -367)*/
|
||||||
#define ISO_BOOT_TOO_MANY_MIPS 0xE830FE91
|
#define ISO_BOOT_TOO_MANY_MIPS 0xE830FE91
|
||||||
|
|
||||||
/** Boot file missing in image (MISHAP, HIGH, -364) */
|
/** Boot file missing in image (MISHAP, HIGH, -368) */
|
||||||
#define ISO_BOOT_FILE_MISSING 0xE430FE90
|
#define ISO_BOOT_FILE_MISSING 0xE430FE90
|
||||||
|
|
||||||
|
/** Partition number out of range (FAILURE, HIGH, -369) */
|
||||||
|
#define ISO_BAD_PARTITION_NO 0xE830FE8F
|
||||||
|
|
||||||
|
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
|
||||||
|
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
|
@ -279,6 +279,7 @@ iso_write_opts_set_omit_version_numbers;
|
|||||||
iso_write_opts_set_output_charset;
|
iso_write_opts_set_output_charset;
|
||||||
iso_write_opts_set_overwrite_buf;
|
iso_write_opts_set_overwrite_buf;
|
||||||
iso_write_opts_set_part_offset;
|
iso_write_opts_set_part_offset;
|
||||||
|
iso_write_opts_set_partition_img;
|
||||||
iso_write_opts_set_pvd_times;
|
iso_write_opts_set_pvd_times;
|
||||||
iso_write_opts_set_record_md5;
|
iso_write_opts_set_record_md5;
|
||||||
iso_write_opts_set_relaxed_vol_atts;
|
iso_write_opts_set_relaxed_vol_atts;
|
||||||
|
@ -353,6 +353,10 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Too many MIPS Big Endian boot files given (max. 15)";
|
return "Too many MIPS Big Endian boot files given (max. 15)";
|
||||||
case ISO_BOOT_FILE_MISSING:
|
case ISO_BOOT_FILE_MISSING:
|
||||||
return "Boot file missing in image";
|
return "Boot file missing in image";
|
||||||
|
case ISO_BAD_PARTITION_NO:
|
||||||
|
return "Partition number out of range";
|
||||||
|
case ISO_BAD_PARTITION_FILE:
|
||||||
|
return "Cannot open data file for appended partition";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,6 +75,85 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute size and position of appended partitions.
|
||||||
|
*/
|
||||||
|
int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
uint32_t pos, size;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
pos = (t->vol_space_size + t->ms_block);
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (t->appended_partitions[i] == NULL)
|
||||||
|
continue;
|
||||||
|
ret = stat(t->appended_partitions[i], &stbuf);
|
||||||
|
if (ret == -1)
|
||||||
|
return ISO_BAD_PARTITION_FILE;
|
||||||
|
if (! S_ISREG(stbuf.st_mode))
|
||||||
|
return ISO_BAD_PARTITION_FILE;
|
||||||
|
size = ((stbuf.st_size + 2047) / 2048);
|
||||||
|
t->appended_part_start[i] = pos;
|
||||||
|
t->appended_part_size[i] = size;
|
||||||
|
pos += size;
|
||||||
|
t->total_size += size * 2048;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Note: partition_offset and partition_size are counted in 2048 blocks
|
||||||
|
*/
|
||||||
|
static int write_mbr_partition_entry(int partition_number, int partition_type,
|
||||||
|
uint32_t partition_offset, uint32_t partition_size,
|
||||||
|
int sph, int hpc, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
|
uint32_t after_end;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
after_end = partition_offset + partition_size;
|
||||||
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||||
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||||
|
iso_compute_cyl_head_sec(&after_end, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
wpt = buf + 446 + (partition_number - 1) * 16;
|
||||||
|
|
||||||
|
/* Not bootable */
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
|
||||||
|
/* C/H/S of the start */
|
||||||
|
*(wpt++) = start_head;
|
||||||
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = start_cyl & 0xff;
|
||||||
|
|
||||||
|
/* (partition type) */
|
||||||
|
*(wpt++) = partition_type;
|
||||||
|
|
||||||
|
/* 3 bytes of C/H/S end */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
/* LBA start in little endian */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Number of sectors in partition, little endian */
|
||||||
|
end_lba = end_lba - start_lba + 1;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Afaik, partition tables are recognize donly with MBR signature */
|
||||||
|
buf[510] = 0x55;
|
||||||
|
buf[511] = 0xAA;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||||
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||||
"Currently we use first and not last entry. You need to:
|
"Currently we use first and not last entry. You need to:
|
||||||
@ -92,11 +174,12 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
|||||||
bit1= do not mark partition as bootable
|
bit1= do not mark partition as bootable
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
||||||
|
uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
int sph = 63, hpc = 255, i;
|
int i;
|
||||||
|
|
||||||
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
@ -155,17 +238,13 @@ int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
|||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||||
int sph_in, int hpc_in, uint8_t *buf, int flag)
|
int sph, int hpc, uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
uint32_t start_lba, start_sec, start_head, start_cyl;
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
int sph = 63, hpc = 255, i;
|
int i;
|
||||||
|
|
||||||
if (sph_in > 0)
|
|
||||||
sph = sph_in;
|
|
||||||
if (hpc_in > 0)
|
|
||||||
hpc = hpc_in;
|
|
||||||
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||||
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||||
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
@ -180,7 +259,7 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
|||||||
/* C/H/S of the start */
|
/* C/H/S of the start */
|
||||||
*(wpt++) = start_head;
|
*(wpt++) = start_head;
|
||||||
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||||
*(wpt++) = end_cyl & 0xff;
|
*(wpt++) = start_cyl & 0xff;
|
||||||
|
|
||||||
/* (partition type) */
|
/* (partition type) */
|
||||||
wpt++;
|
wpt++;
|
||||||
@ -302,9 +381,6 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
|||||||
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
||||||
|
|
||||||
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
||||||
|
|
||||||
#ifndef NIX
|
|
||||||
|
|
||||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
||||||
&node, &ecma_node, "MIPS boot file", 0);
|
&node, &ecma_node, "MIPS boot file", 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -314,45 +390,6 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
|||||||
name_field = (char *) (buf + (72 + 16 * idx));
|
name_field = (char *) (buf + (72 + 16 * idx));
|
||||||
strncpy(name_field, namept, 8);
|
strncpy(name_field, namept, 8);
|
||||||
|
|
||||||
#else /* ! NIX */
|
|
||||||
|
|
||||||
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_FILE_MISSING, 0,
|
|
||||||
"Cannot find MIPS boot file '%s'",
|
|
||||||
t->image->mips_boot_file_paths[idx]);
|
|
||||||
return ISO_BOOT_FILE_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NIX */
|
|
||||||
|
|
||||||
|
|
||||||
file_lba = ecma_node->info.file->sections[0].block;
|
file_lba = ecma_node->info.file->sections[0].block;
|
||||||
|
|
||||||
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
|
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
|
||||||
@ -529,7 +566,7 @@ static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
|
|||||||
|
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int ret, int_img_blocks, sa_type;
|
int ret, int_img_blocks, sa_type, i;
|
||||||
uint32_t img_blocks;
|
uint32_t img_blocks;
|
||||||
|
|
||||||
if ((t == NULL) || (buf == NULL)) {
|
if ((t == NULL) || (buf == NULL)) {
|
||||||
@ -565,7 +602,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
}
|
}
|
||||||
if (sa_type == 0 && (t->system_area_options & 1)) {
|
if (sa_type == 0 && (t->system_area_options & 1)) {
|
||||||
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
||||||
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 0);
|
||||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
} else if(sa_type == 0 && (t->system_area_options & 2)) {
|
} else if(sa_type == 0 && (t->system_area_options & 2)) {
|
||||||
@ -577,7 +615,8 @@ 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,
|
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
|
||||||
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
|
(uint32_t) 0, t->partition_heads_per_cyl,
|
||||||
|
t->partition_secs_per_head, 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) {
|
||||||
@ -590,7 +629,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
return ret;
|
return ret;
|
||||||
} else if(t->partition_offset > 0 && sa_type == 0) {
|
} else if(t->partition_offset > 0 && sa_type == 0) {
|
||||||
/* Write a simple partition table. */
|
/* Write a simple partition table. */
|
||||||
ret = make_grub_msdos_label(img_blocks, buf, 2);
|
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 2);
|
||||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -605,5 +645,17 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This eventually overwrites the partition table entries made so far */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (t->appended_partitions[i] == NULL)
|
||||||
|
continue;
|
||||||
|
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||||
|
t->appended_part_start[i], t->appended_part_size[i],
|
||||||
|
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||||
|
buf, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -53,4 +53,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
|||||||
*/
|
*/
|
||||||
int iso_read_mipsel_elf(Ecma119Image *t, int flag);
|
int iso_read_mipsel_elf(Ecma119Image *t, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute size and position of appended partitions.
|
||||||
|
*/
|
||||||
|
int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
||||||
|
|
||||||
#endif /* SYSTEM_AREA_H_ */
|
#endif /* SYSTEM_AREA_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user