New system area type 6 = DEC Alpha SRM boot sector.

New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
Thanks to Helge Deller.
This commit is contained in:
Thomas Schmitt 2015-02-28 15:13:38 +01:00
parent 9c33eb5f10
commit 782bb7854e
9 changed files with 269 additions and 21 deletions

View File

@ -1104,7 +1104,44 @@ Byte Range | Value | Meaning
------------------------------------------------------------------------------
>>> ??? DEC Alpha
DEC Alpha SRM boot sector
for Alpha architecture
Sources:
http://www.tldp.org/HOWTO/text/SRM-HOWTO
SRM Firmware Howto - Rich Payne, and David Huggins-Daines
cdrkit-1.1.10/genisoimage/boot-alpha.c
by Steve McIntyre
who states "Heavily inspired by isomarkboot by David Mosberger in 1996"
mail conversations with Helge Deller
The SRM firmware expects a Secondary Bootstrap Loader program, which usually
is a data file of the ISO filesystem. This loader is announced by size and
block address in the first 512 bytes of the System Area.
SRM accepts the boot sector and executes the loader if the checksum matches.
All numbers are recorded as unsigned 64 bit little endian.
Boot sector components:
Byte Range | Value | Meaning
---------- | ---------- | ----------------------------------------------------
0 - ? | boot_string| genisoimage writes
| | "Linux/Alpha aboot for ISO filesystem."
| | with terminating zero byte.
| |
? - 479 | 0 | Unused / undefined.
| |
480 - 487 | length | Size of boot loader file in units of 512 bytes.
| |
488 - 495 | address | LBA of the boot loader file in units of 512 bytes.
| |
496 - 503 | flag | "Always 0"
| |
504 - 511 | checksum | Sum of 64 bit words 0 to 63 (bytes 0 to 503).
| |
---------- | ---------- | ----------------------------------------------------
------------------------------------------------------------------------------

View File

@ -637,6 +637,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
/* initialize the ce_block, it might be needed */
info.ce_block = dir->info.dir->block + DIV_UP(dir->info.dir->len,
BLOCK_SIZE);
info.ce_susp_fields = NULL;
}
/* write the "." and ".." entries first */

View File

@ -4631,9 +4631,58 @@ int iso_analyze_hppa(IsoImage *image, IsoDataSource *src, int flag)
/* HP-PA PALO boot sector version 4 or 5 for HP PA-RISC */
sai->system_area_options = (sai->hppa_hdrversion << 2);
return ret;
return 1;
}
static
int iso_analyze_alpha_boot(IsoImage *image, IsoDataSource *src, int flag)
{
int ret = 0, i, section_count;
char *sad;
uint8_t *usad;
struct iso_imported_sys_area *sai;
IsoNode *node;
IsoFile *file;
uint64_t checksum_found, checksum_should = 0, size;
struct iso_file_section *sections = NULL;
sai = image->imported_sa_info;
sad = image->system_area_data;
usad = (uint8_t *) sad;
checksum_found = iso_read_lsb64(usad + 504);
for (i = 0; i < 63; i++)
checksum_should += iso_read_lsb64(usad + 8 * i);
if (checksum_found != checksum_should)
return 0;
sai->alpha_boot_image = NULL;
sai->alpha_boot_image_size = (uint64_t) iso_read_lsb64(usad + 480);
sai->alpha_boot_image_adr = (uint64_t) iso_read_lsb64(usad + 488);
ret = iso_tree_get_node_of_block(image, NULL,
(uint32_t) (sai->alpha_boot_image_adr / 4),
&node, NULL, 0);
if (ret > 0) {
if (iso_node_get_type(node) != LIBISO_FILE)
return 0;
file = (IsoFile *) node;
ret = iso_file_get_old_image_sections(file, &section_count,
&sections, 0);
if (ret > 0) {
size = sections[0].size / 512 + !!(sections[0].size % 512);
free(sections);
if (size != sai->alpha_boot_image_size)
return 0;
}
sai->alpha_boot_image = iso_tree_get_node_path(node);
} else if (strncmp(sad, "Linux/Alpha aboot for ISO filesystem.", 37) != 0
|| sad[37] != 0) {
return 0; /* Want to see either boot file or genisoimage string */
}
sai->system_area_options = (6 << 2);
return 1;
}
struct iso_impsysa_result {
char *buf;
int byte_count;
@ -4867,6 +4916,8 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target,
strcat(msg, " SUN-SPARC-Disk-Label");
} else if (sa_type == 4 || sa_type == 5) {
sprintf(msg + strlen(msg), " HP-PA-PALO");
} else if (sa_type == 6) {
sprintf(msg + strlen(msg), " DEC-Alpha");
} else {
sprintf(msg + strlen(msg), " unkown-system-area-type-%d", sa_type);
}
@ -4911,6 +4962,17 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target,
iso_impsysa_report_text(target, msg,
sai->hppa_bootloader != NULL ?
sai->hppa_bootloader : "(not found in ISO)", 0);
} else if (sa_type == 6) {
sprintf(msg, "DEC Alpha ldr size : %.f",
(double) sai->alpha_boot_image_size);
iso_impsysa_line(target, msg);
sprintf(msg, "DEC Alpha ldr adr : %.f",
(double) sai->alpha_boot_image_adr);
iso_impsysa_line(target, msg);
if (sai->alpha_boot_image != NULL) {
sprintf(msg, "DEC Alpha ldr path : %s", sai->alpha_boot_image);
iso_impsysa_line(target, msg);
}
}
if (sai->mbr_req_count > 0) {
sprintf(msg, "MBR heads per cyl : %d", sai->partition_heads_per_cyl);
@ -5310,6 +5372,7 @@ int iso_image_report_boot_eqp(IsoImage *image, int what,
ISO_SYSAREA_REPORT_DOC_MIPS ,
ISO_SYSAREA_REPORT_DOC_SUN ,
ISO_SYSAREA_REPORT_DOC_HPPA ,
ISO_SYSAREA_REPORT_DOC_ALPHA ,
"@END_OF_DOC@" };
static char *eltorito_doc[] = { ISO_ELTORITO_REPORT_DOC ,
"@END_OF_DOC@" };
@ -5491,6 +5554,12 @@ int iso_analyze_system_area(IsoImage *image, IsoDataSource *src,
ret = iso_analyze_hppa(image, src, 0);
if (ret < 0)
goto ex;
/* DEC Alpha has checksum bytes where MBR has its magic number */
if (ret == 0) {
ret = iso_analyze_alpha_boot(image, src, 0);
if (ret < 0)
goto ex;
}
}
ret = iso_record_meta_struct_blocks(image, src, 0);
if (ret < 0)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* 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
@ -51,6 +51,8 @@ int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
b->hppa_kernel_64 = NULL;
b->hppa_ramdisk = NULL;
b->alpha_boot_image = NULL;
*boots = b;
return 1;
}
@ -107,6 +109,7 @@ int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
LIBISO_FREE_MEM(b->hppa_kernel_32);
LIBISO_FREE_MEM(b->hppa_kernel_64);
LIBISO_FREE_MEM(b->hppa_ramdisk);
LIBISO_FREE_MEM(b->alpha_boot_image);
LIBISO_FREE_MEM(b);
*boots = NULL;
return 1;
@ -181,6 +184,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->hppa_kernel_32 = NULL;
img->hppa_kernel_64 = NULL;
img->hppa_ramdisk = NULL;
img->alpha_boot_image = NULL;
img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->inode_counter = 0;
@ -239,6 +243,8 @@ void iso_image_unref(IsoImage *image)
if (image->sparc_core_node != NULL)
iso_node_unref((IsoNode *) image->sparc_core_node);
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
if (image->alpha_boot_image != NULL)
free(image->alpha_boot_image);
free(image->volset_id);
free(image->volume_id);
free(image->publisher_id);
@ -969,9 +975,9 @@ int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
Else only the non-NULL parameters of this call have an effect.
*/
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
int flag)
char *what, int flag)
{
int ret;
int ret, err;
IsoNode *node;
IsoFile *file;
@ -986,13 +992,16 @@ static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
return ret;
if (ret == 0) {
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
"Cannot find in ISO image: HP-PA file '%s'", path);
"Cannot find in ISO image: %s file '%s'", what, path);
return ISO_BOOT_FILE_MISSING;
}
if (iso_node_get_type(node) != LIBISO_FILE) {
iso_msg_submit(img->id, ISO_HPPA_PALO_NOTREG, 0,
"HP-PA PALO file is not a data file: '%s'", path);
return ISO_HPPA_PALO_NOTREG;
err = ISO_HPPA_PALO_NOTREG;
if (strncmp(what, "DEC Alpha", 9) == 0)
err = ISO_ALPHA_BOOT_NOTREG;
iso_msg_submit(img->id, err, 0,
"%s file is not a data file: '%s'", what, path);
return err;
}
file = (IsoFile *) node;
if (!(file->explicit_weight || file->from_old_session))
@ -1012,21 +1021,25 @@ int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
int flag)
{
int ret;
static char *what = "HP-PA PALO";
if (cmdline != NULL || (flag & 1))
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
return ISO_OUT_OF_MEM;
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader),
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), flag & 1);
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), flag & 1);
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), what,
flag & 1);
if (ret < 0)
return ret;
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), flag & 1);
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), what,
flag & 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
@ -1046,3 +1059,24 @@ int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
}
/* API */
int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag)
{
int ret;
ret = hppa_palo_set_path(img, boot_loader_path, &(img->alpha_boot_image),
"DEC Alpha Bootloader", 1);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/* API */
int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path)
{
*boot_loader_path = img->alpha_boot_image;
return ISO_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2015 Thomas Schmitt
*
* 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
@ -88,6 +88,9 @@ struct Iso_Image
char *hppa_kernel_64;
char *hppa_ramdisk;
/* Absolute DEC Alpha boot image path in the ISO image */
char *alpha_boot_image;
/* image identifier, for message origin identifier */
int id;
@ -96,7 +99,7 @@ struct Iso_Image
*/
IsoFilesystem *fs;
/*
/**
* Default builder to use when adding files to the image tree.
*/
IsoNodeBuilder *builder;
@ -385,6 +388,10 @@ struct iso_imported_sys_area {
char *hppa_ramdisk;
char *hppa_bootloader;
uint64_t alpha_boot_image_size;
uint64_t alpha_boot_image_adr;
char *alpha_boot_image;
/* Some block addresses of active and first session:
PVD, L Pathtable, Opt L, M Pathtable, Opt M, root directory
*/

View File

@ -2203,6 +2203,9 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* lib/common.h is defined as 5.
* Submit all five parameters of iso_image_set_hppa_palo():
* cmdline, bootloader, kernel_32, kernel_64, ramdisk
* 6= DEC Alpha SRM boot sector
* @since 1.4.0
* Submit bootloader path in ISO by iso_image_set_alpha_boot().
* bit8-9= Only with System area type 0 = MBR
* @since 1.0.4
* Cylinder alignment mode eventually pads the image to make it
@ -2493,7 +2496,8 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
* Linux Native Partition = 0x83. See fdisk command L.
* This parameter is ignored with SUN Disk Label.
* @param flag
* Reserved for future usage, set to 0.
* bit0= The path may contain instructions for the interval reader
* All other bits are reserved for future usage. Set them to 0.
* @return
* ISO_SUCCESS or error
*
@ -3729,7 +3733,7 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
" human readable interpretation of system area options and other info", \
" The words are from the set:", \
" { MBR, CHRP, PReP, GPT, APM, MIPS-Big-Endian, MIPS-Little-Endian,", \
" SUN-SPARC-Disk-Label, HP-PA-PALO,", \
" SUN-SPARC-Disk-Label, HP-PA-PALO, DEC-Alpha, ", \
" protective-msdos-label, isohybrid, grub2-mbr,", \
" cyl-align-{auto,on,off,all}, not-recognized, }", \
" The acronyms indicate boot data for particular hardware/firmware.", \
@ -3916,6 +3920,16 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
" HP-PA bootloader : decimal decimal path", \
" tells the same for the bootloader file.", \
""
#define ISO_SYSAREA_REPORT_DOC_ALPHA \
"If a DEC Alpha SRM boot sector is present:", \
" DEC Alpha ldr size : decimal", \
" tells the number of 512-byte blocks in DEC Alpha Secondary Bootstrap" \
" Loader file.", \
" DEC Alpha ldr adr : decimal", \
" tells the start of the loader file in units of 512-byte blocks.", \
" DEC Alpha ldr path : path", \
" tells the path of a file in the ISO image which starts at the loader", \
" start address."
/**
* Obtain an array of texts describing the detected properties of the
@ -4214,6 +4228,42 @@ int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
char **kernel_32, char **kernel_64, char **ramdisk);
/**
* Submit the path of the DEC Alpha Secondary Bootstrap Loader file.
* The path must lead to an already existing data file in the ISO image
* which stays with this path until image production.
* This setting has an effect only if system area type is set to 6
* with iso_write_opts_set_system_area().
*
* @param img
* The image to be manipulated.
* @param boot_loader_path
* Absolute path of a data file in the ISO image.
* Submit NULL to free this image property.
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
* 1 is success , <0 means error
* @since 1.4.0
*/
int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag);
/**
* Inquire the path submitted by iso_image_set_alpha_boot()
* Do not free() the returned pointer.
*
* @param img
* The image to be inquired.
* @param cmdline
* Will return the path. NULL if none is currently submitted.
* @return
* 1 is success , <0 means error
* @since 1.4.0
*/
int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path);
/**
* Increments the reference counting of the given node.
*
@ -8110,6 +8160,9 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** Unrecognized inquiry for system area property (FAILURE, HIGH, -404) */
#define ISO_INQ_SYSAREA_PROP 0xE830FE6C
/** DEC Alpha Boot Loader file is not a data file (FAILURE, HIGH, -405) */
#define ISO_ALPHA_BOOT_NOTREG 0xE830FE6A
/* Internal developer note:
Place new error codes directly above this comment.

View File

@ -90,6 +90,7 @@ iso_image_fs_get_volume_id;
iso_image_generator_is_running;
iso_image_get_abstract_file_id;
iso_image_get_all_boot_imgs;
iso_image_get_alpha_boot;
iso_image_get_app_use;
iso_image_get_application_id;
iso_image_get_attached_data;
@ -120,6 +121,7 @@ iso_image_remove_boot_image;
iso_image_report_el_torito;
iso_image_report_system_area;
iso_image_set_abstract_file_id;
iso_image_set_alpha_boot;
iso_image_set_app_use;
iso_image_set_application_id;
iso_image_set_biblio_file_id;

View File

@ -519,6 +519,8 @@ const char *iso_error_to_msg(int errcode)
return "Problems encountered during inspection of System Area";
case ISO_INQ_SYSAREA_PROP:
return "Unrecognized inquiry for system area property";
case ISO_ALPHA_BOOT_NOTREG:
return "DEC Alpha Boot Loader file is not a data file";
default:
return "Unknown error";
}

View File

@ -913,6 +913,45 @@ static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int hdrversion,
}
/**
* Write DEC Alpha boot sector. See doc/boot_sectors.txt
*
* learned from cdrkit-1.1.10/genisoimage/boot-alpha.c
* by Steve McIntyre <steve@einval.com>
* who states "Heavily inspired by isomarkboot by David Mosberger in 1996"
*
*/
static int make_dec_alpha_sector(Ecma119Image *t, uint8_t *buf, int flag)
{
int ret, i;
IsoImage *img;
IsoNode *iso_node;
Ecma119Node *ecma_node;
uint64_t size, lba, checksum = 0;
img = t->image;
if (img->alpha_boot_image == NULL)
return ISO_SUCCESS;
ret = boot_nodes_from_iso_path(t, img->alpha_boot_image,
&iso_node, &ecma_node, "DEC Alpha boot file", 0);
if (ret < 0)
return ret;
memset(buf, 0, 512);
strcpy((char *) buf, "Linux/Alpha aboot for ISO filesystem.");
lba = ecma_node->info.file->sections[0].block * 4;
size = ecma_node->info.file->sections[0].size / 512 +
!!(ecma_node->info.file->sections[0].size % 512);
iso_lsb(buf + 480, size & 0xffffffff, 4);
iso_lsb(buf + 484, (size >> 32) & 0xffffffff, 4);
iso_lsb(buf + 488, lba & 0xffffffff, 4);
iso_lsb(buf + 492, (lba >> 32) & 0xffffffff, 4);
for (i = 0; i < 63; i++)
checksum += iso_read_lsb64(buf + 8 * i);
iso_lsb(buf + 504, checksum & 0xffffffff, 4);
iso_lsb(buf + 508, (checksum >> 32) & 0xffffffff, 4);
return ISO_SUCCESS;
}
/* Convenience frontend for iso_register_apm_entry().
name and type are 0-terminated strings.
*/
@ -1778,6 +1817,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
ret = make_hppa_palo_sector(t, buf, sa_type, 0);
if (ret != ISO_SUCCESS)
return ret;
} else if (sa_type == 6) {
ret = make_dec_alpha_sector(t, buf, 0);
if (ret != ISO_SUCCESS)
return ret;
} else if ((t->opts->partition_offset > 0 || will_append) &&
sa_type == 0 && t->mbr_req_count == 0) {
/* Write a simple partition table. */