diff --git a/doc/boot_sectors.txt b/doc/boot_sectors.txt index 29395a4..9f86cb1 100644 --- a/doc/boot_sectors.txt +++ b/doc/boot_sectors.txt @@ -33,6 +33,8 @@ PowerPC Reference Platform (PReP), for IBM PowerPC Common Hardware Reference Platform (CHRP), for IBM PowerPC +HP-PA via PALO + Combinations of boot mechanisms: - SYSLINUX isohybrid MBR - SYSLINUX isohybrid for MBR, UEFI and x86-Mac @@ -947,7 +949,52 @@ in the ISO image [without causing overlapping between partitions]. ------------------------------------------------------------------------------ ->>> ??? HP-PA + HP-PA via PALO + for HP PA-RISC + +Sources: + cdrkit-1.1.10/genisoimage/boot-hppa.c + by Steve McIntyre + who states "Heavily inspired by palo" + +There are five parameters which get encoded into the first 248 bytes of the +System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk. +They are all mandatory. +While cmdline is simply a string of at most 127 characters, the other four +point to data files inside the ISO image. + +All numbers are recorded big endian. + +Boot sector components: + +Byte Range | Value | Meaning +---------- | ---------- | ---------------------------------------------------- + 0 - 1 | 0x8000 | Magic + 2 - 5 | "PALO" | + 6 - 7 | 0x0004 | Version + | | + 8 - 11 | kern32_adr | Byte address of the "HPPA 32-bit kernel" file + | | genisoimage option -hppa-kernel-32 + 12 - 15 | kern32_len | Byte count of the "HPPA 32-bit kernel" file + | | + 16 - 19 | ramdsk_adr | Byte address of the "HPPA ramdisk" file + | | genisoimage option -hppa-ramdisk + 20 - 23 | ramdsk_len | Byte count of the "HPPA ramdisk" file + | | + 24 - 141 | cmdline | "Command line" + | | genisoimage option -hppa-cmdline + | | + 232 - 235 | kern64_adr | Byte address of the "HPPA 64-bit kernel" file + | | genisoimage option -hppa-kernel-64 + 236 - 239 | kern64_len | Byte count of the "HPPA 64-bit kernel" file + | | + 240 - 243 | bootld_adr | Byte address of the "HPPA bootloader" file + | | genisoimage option -hppa-bootloader + 244 - 247 | bootld_len | Byte count of the "HPPA bootloader" file + | | +---------- | ---------- | ---------------------------------------------------- + + ------------------------------------------------------------------------------ diff --git a/libisofs/image.c b/libisofs/image.c index 34c3ef6..281d53e 100644 --- a/libisofs/image.c +++ b/libisofs/image.c @@ -85,6 +85,11 @@ int iso_image_new(const char *name, IsoImage **image) for (i = 0; i < 15; i++) img->mips_boot_file_paths[i] = NULL; img->sparc_core_node = NULL; + img->hppa_cmdline= NULL; + img->hppa_bootloader= NULL; + img->hppa_kernel_32= NULL; + img->hppa_kernel_64= NULL; + img->hppa_ramdisk= NULL; img->builder_ignore_acl = 1; img->builder_ignore_ea = 1; img->inode_counter = 0; @@ -141,6 +146,7 @@ void iso_image_unref(IsoImage *image) iso_image_give_up_mips_boot(image, 0); 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); free(image->volset_id); free(image->volume_id); free(image->publisher_id); @@ -859,3 +865,85 @@ int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag) } +/* @param flag + bit0= Let NULL parameters free the corresponding image properties. + 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) +{ + int ret; + IsoNode *node; + IsoFile *file; + + if (path == NULL && !(flag & 1)) + return ISO_SUCCESS; + if (iso_clone_mgtd_mem(path, target, 0) < 0) + return ISO_OUT_OF_MEM; + if (path == NULL) + return ISO_SUCCESS; + ret = iso_tree_path_to_node(img, path, &node); + if (ret < 0) + 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); + 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; + } + file = (IsoFile *) node; + if (!file->explicit_weight) + file->sort_weight = 2; + return ISO_SUCCESS; +} + + +/* API */ +/* @param flag + Bitfield for control purposes + bit0= Let NULL parameters free the corresponding image properties. + Else only the non-NULL parameters of this call have an effect. +*/ +int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader, + char *kernel_32, char *kernel_64, char *ramdisk, + int flag) +{ + int ret; + + 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), + flag & 1); + if (ret < 0) + return ret; + ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), flag & 1); + if (ret < 0) + return ret; + ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), flag & 1); + if (ret < 0) + return ret; + ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), flag & 1); + if (ret < 0) + return ret; + return ISO_SUCCESS; +} + + +/* API */ +int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader, + char **kernel_32, char **kernel_64, char **ramdisk) +{ + *cmdline = img->hppa_cmdline; + *bootloader = img->hppa_bootloader; + *kernel_32 = img->hppa_kernel_32; + *kernel_64 = img->hppa_kernel_64; + *ramdisk = img->hppa_ramdisk; + return ISO_SUCCESS; +} + + diff --git a/libisofs/image.h b/libisofs/image.h index eb92db4..8d55fe8 100644 --- a/libisofs/image.h +++ b/libisofs/image.h @@ -78,6 +78,16 @@ struct Iso_Image */ IsoFile *sparc_core_node; + /* + * Parameters for HP-PA PALO boot sector. cmdline is a string. The other + * four are absolute paths to data files in the ISO image. + */ + char *hppa_cmdline; + char *hppa_bootloader; + char *hppa_kernel_32; + char *hppa_kernel_64; + char *hppa_ramdisk; + /* image identifier, for message origin identifier */ int id; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index abbde54..3e7fb47 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -2185,6 +2185,10 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size); * to 8. * This will overwrite the first 512 bytes of the submitted * data. + * 4= HP-PA PALO boot sector for HP PA-RISC + * @since 1.3.6 + * Submit all five parameters of iso_image_set_hppa_palo(): + * cmdline, bootloader, kernel_32, kernel_64, ramdisk * bit8-9= Only with System area type 0 = MBR * @since 1.0.4 * Cylinder alignment mode eventually pads the image to make it @@ -3733,6 +3737,63 @@ int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag); */ int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag); + +/** + * Define a command line and submit the paths of four mandatory files for + * production of a HP-PA PALO boot sector for PA-RISC machines. + * The paths must lead to already existing data files in the ISO image + * which stay with these paths until image production. + * + * @param img + * The image to be manipulated. + * @param cmdline + * Up to 127 characters of command line. + * @param bootloader + * Absolute path of a data file in the ISO image. + * @param kernel_32 + * Absolute path of a data file in the ISO image which serves as + * 32 bit kernel. + * @param kernel_64 + * Absolute path of a data file in the ISO image which serves as + * 64 bit kernel. + * @param ramdisk + * Absolute path of a data file in the ISO image. + * @param flag + * Bitfield for control purposes + * bit0= Let NULL parameters free the corresponding image properties. + * Else only the non-NULL parameters of this call have an effect + * @return + * 1 is success , <0 means error + * @since 1.3.6 + */ +int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader, + char *kernel_32, char *kernel_64, char *ramdisk, + int flag); + +/** + * Inquire the current settings of iso_image_set_hppa_palo(). + * Do not free() the returned pointers. + * + * @param img + * The image to be inquired. + * @param cmdline + * Will return the command line. + * @param bootloader + * Will return the absolute path of the bootloader file. + * @param kernel_32 + * Will return the absolute path of the 32 bit kernel file. + * @param kernel_64 + * Will return the absolute path of the 64 bit kernel file. + * @param ramdisk + * Will return the absolute path of the RAM disk file. + * @return + * 1 is success , <0 means error + * @since 1.3.6 + */ +int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader, + char **kernel_32, char **kernel_64, char **ramdisk); + + /** * Increments the reference counting of the given node. * @@ -4116,7 +4177,7 @@ int iso_node_get_hidden(IsoNode *node); * @param n2 * The second node to compare. * @return - * -1 if s1 is smaller s2 , 0 if s1 matches s2 , 1 if s1 is larger s2 + * -1 if n1 is smaller n2 , 0 if n1 matches n2 , 1 if n1 is larger n2 * @param flag * Bitfield for control purposes, unused yet, submit 0 * @since 0.6.20 @@ -7608,6 +7669,18 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len, /** File name collision during ISO image import (WARNING, HIGH, -398) */ #define ISO_IMPORT_COLLISION 0xD030FE72 +/** Incomplete HP-PA PALO boot parameters (FAILURE, HIGH, -399) */ +#define ISO_HPPA_PALO_INCOMPL 0xE830FE71 + +/** HP-PA PALO boot address exceeds 32 bit (FAILURE, HIGH, -400) */ +#define ISO_HPPA_PALO_OFLOW 0xE830FE70 + +/** HP-PA PALO file is not a data file (FAILURE, HIGH, -401) */ +#define ISO_HPPA_PALO_NOTREG 0xE830FE6F + +/** HP-PA PALO command line too long (FAILURE, HIGH, -402) */ +#define ISO_HPPA_PALO_CMDLEN 0xE830FE6E + /* Internal developer note: Place new error codes directly above this comment. diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index b4f605f..92f83c8 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -124,6 +124,8 @@ iso_image_set_boot_catalog_weight; iso_image_set_boot_image; iso_image_set_copyright_file_id; iso_image_set_data_preparer_id; +iso_image_set_hppa_palo; +iso_image_get_hppa_palo; iso_image_set_ignore_aclea; iso_image_set_publisher_id; iso_image_set_sparc_core; diff --git a/libisofs/messages.c b/libisofs/messages.c index 06ceeed..65f4af1 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -504,9 +504,17 @@ const char *iso_error_to_msg(int errcode) case ISO_BAD_ISO_FILETYPE: return "Unrecognized file type in ISO image"; case ISO_NAME_NOT_UCS2: - return "Filename not suitable for character set UCS-2"; + return "Filename not suitable for character set UCS-2"; case ISO_IMPORT_COLLISION: - return "File name collision during ISO image import"; + return "File name collision during ISO image import"; + case ISO_HPPA_PALO_INCOMPL: + return "Incomplete HP-PA PALO boot parameters"; + case ISO_HPPA_PALO_OFLOW: + return "HP-PA PALO boot address exceeds 32 bit"; + case ISO_HPPA_PALO_NOTREG: + return "HP-PA PALO file is not a data file"; + case ISO_HPPA_PALO_CMDLEN: + return "HP-PA PALO command line too long"; default: return "Unknown error"; } diff --git a/libisofs/system_area.c b/libisofs/system_area.c index b0eab9f..d2e29bc 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2008 Vreixo Formoso - * Copyright (c) 2010 - 2013 Thomas Schmitt + * Copyright (c) 2010 - 2014 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 @@ -765,6 +765,115 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag) } +static int hppa_palo_get_filepar(Ecma119Image *t, char *path, + uint32_t *adr, uint32_t *len, int flag) +{ + int ret; + IsoNode *iso_node; + Ecma119Node *ecma_node; + off_t adr64; + + ret = boot_nodes_from_iso_path(t, path, + &iso_node, &ecma_node, "HP-PA PALO boot file", 0); + if (ret < 0) + return ret; + if (iso_node_get_type(iso_node) != LIBISO_FILE) { + iso_msg_submit(t->image->id, ISO_HPPA_PALO_NOTREG, 0, + "HP-PA PALO file is not a data file"); + return ISO_HPPA_PALO_NOTREG; + } + adr64 = ((off_t) 2048) * (off_t) ecma_node->info.file->sections[0].block; + if (adr64 > 0xffffffff) { + iso_msg_submit(t->image->id, ISO_HPPA_PALO_OFLOW, 0, + "HP-PA PALO boot address exceeds 32 bit"); + return ISO_HPPA_PALO_OFLOW; + } + *adr = adr64; + *len = ecma_node->info.file->sections[0].size; + return ISO_SUCCESS; +} + + +/** + * Write HP-PA PALO boot sector. See doc/boot_sectors.txt + * + * learned from cdrkit-1.1.10/genisoimage/boot-hppa.c + * by Steve McIntyre + * who states "Heavily inspired by palo" + */ +static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int flag) +{ + int ret; + IsoImage *img; + uint32_t adr, len; + + /* Bytes 256 to 32767 may come from image or external file */ + memset(buf, 0, 256); + + img = t->image; + if (img->hppa_cmdline == NULL && img->hppa_bootloader == NULL && + img->hppa_kernel_32 == NULL && img->hppa_kernel_64 && + img->hppa_ramdisk == NULL) + return ISO_SUCCESS; + if (img->hppa_cmdline == NULL || img->hppa_bootloader == NULL || + img->hppa_kernel_32 == NULL || img->hppa_kernel_64 == NULL || + img->hppa_ramdisk == NULL) { + iso_msg_submit(img->id, ISO_HPPA_PALO_INCOMPL, 0, + "Incomplete HP-PA PALO boot parameters"); + return ISO_HPPA_PALO_INCOMPL; + } + + /* Magic */ + iso_msb(buf + 0, 0x8000, 2); + /* Name of boot loader */ + memcpy(buf + 2, "PALO", 4); + /* Version */ + iso_msb(buf + 6, 0x0004, 2); + + /* Byte address and byte count of the "HPPA 32-bit kernel" file + */ + ret = hppa_palo_get_filepar(t, img->hppa_kernel_32, &adr, &len, 0); + if (ret < 0) + return ret; + iso_msb(buf + 8, adr, 4); + iso_msb(buf + 12, len, 4); + + /* Byte address and byte count of the "HPPA ramdisk" file + */ + ret = hppa_palo_get_filepar(t, img->hppa_ramdisk, &adr, &len, 0); + if (ret < 0) + return ret; + iso_msb(buf + 16, adr, 4); + iso_msb(buf + 20, len, 4); + + /* "Command line" */ + if (strlen(img->hppa_cmdline) > 127) { + iso_msg_submit(img->id, ISO_HPPA_PALO_CMDLEN, 0, + "HP-PA PALO command line too long"); + return ISO_HPPA_PALO_CMDLEN; + } + memcpy(buf + 24, img->hppa_cmdline, strlen(img->hppa_cmdline) + 1); + + /* Byte address and byte count of the "HPPA 64-bit kernel" file + */ + ret = hppa_palo_get_filepar(t, img->hppa_kernel_64, &adr, &len, 0); + if (ret < 0) + return ret; + iso_msb(buf + 232, adr, 4); + iso_msb(buf + 236, len, 4); + + /* Byte address and byte count of the "HPPA bootloader" file + */ + ret = hppa_palo_get_filepar(t, img->hppa_bootloader, &adr, &len, 0); + if (ret < 0) + return ret; + iso_msb(buf + 240, adr, 4); + iso_msb(buf + 244, len, 4); + + return ISO_SUCCESS; +} + + /* Convenience frontend for iso_register_apm_entry(). name and type are 0-terminated strings. */ @@ -1589,6 +1698,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) ret = make_sun_disk_label(t, buf, 0); if (ret != ISO_SUCCESS) return ret; + } else if (sa_type == 4) { + ret = make_hppa_palo_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. */ diff --git a/libisofs/util.c b/libisofs/util.c index 640840b..ee91864 100644 --- a/libisofs/util.c +++ b/libisofs/util.c @@ -2255,3 +2255,10 @@ int iso_clone_mem(char *in, char **out, size_t size) } +int iso_clone_mgtd_mem(char *in, char **out, size_t size) +{ + if (*out != NULL) + free(*out); + return iso_clone_mem(in, out, size); +} + diff --git a/libisofs/util.h b/libisofs/util.h index bb48611..d1eae35 100644 --- a/libisofs/util.h +++ b/libisofs/util.h @@ -614,6 +614,10 @@ void *iso_alloc_mem(size_t size, size_t count, int flag); */ int iso_clone_mem(char *in, char **out, size_t size); +/* Like iso_clone_mem but first freeing *out if not NULL +*/ +int iso_clone_mgtd_mem(char *in, char **out, size_t size); + /* ------------------------------------------------------------------------- */