diff --git a/doc/boot_sectors.txt b/doc/boot_sectors.txt index 9f86cb1..fee688b 100644 --- a/doc/boot_sectors.txt +++ b/doc/boot_sectors.txt @@ -33,7 +33,8 @@ PowerPC Reference Platform (PReP), for IBM PowerPC Common Hardware Reference Platform (CHRP), for IBM PowerPC -HP-PA via PALO +HP-PA via PALO header version 4 +HP-PA via PALO header version 5 Combinations of boot mechanisms: - SYSLINUX isohybrid MBR @@ -949,7 +950,7 @@ in the ISO image [without causing overlapping between partitions]. ------------------------------------------------------------------------------ - HP-PA via PALO + HP-PA via PALO header version 4 for HP PA-RISC Sources: @@ -970,8 +971,10 @@ Boot sector components: Byte Range | Value | Meaning ---------- | ---------- | ---------------------------------------------------- 0 - 1 | 0x8000 | Magic - 2 - 5 | "PALO" | - 6 - 7 | 0x0004 | Version + | | + 2 - 6 | "PALO" | Zero terminated string + | | + 7 - 7 | 4 | Version | | 8 - 11 | kern32_adr | Byte address of the "HPPA 32-bit kernel" file | | genisoimage option -hppa-kernel-32 @@ -995,6 +998,116 @@ Byte Range | Value | Meaning ---------- | ---------- | ---------------------------------------------------- +------------------------------------------------------------------------------ + + HP-PA via PALO header version 5 + for HP PA-RISC + +Sources: + Public mail conversations with Helge Deller, beginning with + https://lists.debian.org/debian-hppa/2014/01/msg00016.html + http://git.kernel.org/cgit/linux/kernel/git/deller/palo.git/tree/lib/ + (especially struct firstblock in common.h and struct partition in part.h) + +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 1023 characters, the other four +point to data files inside the ISO image. + +Several fields of the firstblock shall be hardcoded to 0, on advise of +Helge Deller. Their description is shown in round brackets. + +The partition table format is the same as with MBR. +>>> ??? what block range gets marked in which partition ? +>>> If this is only for CD/DVD/BD images, then no partitioning is needed. + +All numbers are recorded big endian. +Except flags, all 4-byte integers are signed. + +Boot sector components: + +Byte Range | Value | Meaning +---------- | ---------- | ---------------------------------------------------- + 0 - 1 | 0x8000 | Magic + | | + 2 - 6 | "PALO" | Zero terminated string + | | + 7 - 7 | 5 | Version + | | + 8 - 11 | kern32_adr | Byte address of the 32-bit kernel file + | | + 12 - 15 | kern32_len | Byte count of the 32-bit kernel file + | | + 16 - 19 | ramdsk_adr | Byte address of the ramdisk file + | | + 20 - 23 | ramdsk_len | Byte count of the ramdisk file + | | + 24 - 141 | 0 | All 0s. Old command line of version 4. + | | + | | + 220 - 223 | 0 | (Length of uncompressed 32-bit kernel) + | | + 224 - 227 | 0 | (Length of uncompressed 64-bit kernel) + | | + 228 - 231 | 0 | (flags) + | | + 232 - 235 | kern64_adr | Byte address of the 64-bit kernel file + | | + 236 - 239 | kern64_len | Byte count of the 64-bit kernel file + | | + 240 - 243 | ipl_adr | Byte address of the bootloader file + | | + 244 - 247 | ipl_len | Byte count of the bootloader file + | | + 248 - 251 | ipl_entry | >>> Meaning unclear + | | + | | + 446 - 461 | ========== | MBR/DOS Partition Table Entry for partition 1 + | | + 446 - 446 | status | Governs bootability: + | | 0x80 = bootable/active , 0x00 non-bootable/inactive + | | + 447 - 449 | ========== | C/H/S address of partition start + 447 - 447 | start_head | Heads part of start address. + 448 - 448 | start_c_s | Bits 0 to 5 : Sectors part of start address. + | | Bits 6 to 7 : Bits 8 to 9 of cylinders part. + 449 - 449 | start_cyl | Lower 8 bits of cylinders part of start address + | | + 450 - 450 | part_type | Partition type indicates the purpose or kind of + | | filesystem in the partition. + | | + 451 - 453 | ========== | C/H/S address of last absolute sector in partition + 451 - 451 | end_head | Heads 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. + 453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address + | | + 454 - 457 | start_lba | LBA of first absolute sector in partiton. + | | Block size is 512. Counting starts at 0. + | | + 458 - 461 | num_blocks | Number of sectors in partition. + | | + 462 - 477 | ========== | Partition Table Entry for partition 2 + | part_entr2 | 16 bytes. Format as with partition 1. + | | All 0 means that partition is unused/undefined. + | | + 478 - 493 | ========== | Partition Table Entry for partition 3 + | part_entr3 | 16 bytes. See above. + | | + 494 - 509 | ========== | Partition Table Entry for partition 4 + | part_entr4 | 16 bytes. See above. + | | + 510 - 510 | 0x55 | MBR signature + 511 - 511 | 0xaa | MBR signature + | | + | | +1024 -2047 | cmdline | Zero terminated command line of up to + | | 1023 characters + | | +---------- | ---------- | ---------------------------------------------------- + ------------------------------------------------------------------------------ diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 3e7fb47..ec313dc 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -2185,8 +2185,14 @@ 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 + * 4= HP-PA PALO boot sector version 4 for HP PA-RISC * @since 1.3.6 + * Suitable for older PALO of e.g. Debian 4 and 5. + * Submit all five parameters of iso_image_set_hppa_palo(): + * cmdline, bootloader, kernel_32, kernel_64, ramdisk + * 5= HP-PA PALO boot sector version 5 for HP PA-RISC + * Suitable for newer PALO, where PALOHDRVERSION in + * lib/common.h is defined as 5. * 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 @@ -7672,7 +7678,7 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len, /** 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) */ +/** HP-PA PALO boot address exceeds 2 GB (FAILURE, HIGH, -400) */ #define ISO_HPPA_PALO_OFLOW 0xE830FE70 /** HP-PA PALO file is not a data file (FAILURE, HIGH, -401) */ diff --git a/libisofs/messages.c b/libisofs/messages.c index 65f4af1..d513042 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -510,7 +510,7 @@ const char *iso_error_to_msg(int errcode) 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"; + return "HP-PA PALO boot address exceeds 2 GB"; case ISO_HPPA_PALO_NOTREG: return "HP-PA PALO file is not a data file"; case ISO_HPPA_PALO_CMDLEN: diff --git a/libisofs/system_area.c b/libisofs/system_area.c index d2e29bc..aa0ddab 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -783,9 +783,9 @@ static int hppa_palo_get_filepar(Ecma119Image *t, char *path, return ISO_HPPA_PALO_NOTREG; } adr64 = ((off_t) 2048) * (off_t) ecma_node->info.file->sections[0].block; - if (adr64 > 0xffffffff) { + if (adr64 > 0x7fffffff) { iso_msg_submit(t->image->id, ISO_HPPA_PALO_OFLOW, 0, - "HP-PA PALO boot address exceeds 32 bit"); + "HP-PA PALO boot address exceeds 2 GB"); return ISO_HPPA_PALO_OFLOW; } *adr = adr64; @@ -800,15 +800,18 @@ static int hppa_palo_get_filepar(Ecma119Image *t, char *path, * learned from cdrkit-1.1.10/genisoimage/boot-hppa.c * by Steve McIntyre * who states "Heavily inspired by palo" + * Public mail conversations with Helge Deller, beginning with + * https://lists.debian.org/debian-hppa/2014/01/msg00016.html + * http://git.kernel.org/cgit/linux/kernel/git/deller/palo.git/tree/lib/ + * (especially struct firstblock in common.h and struct partition in part.h) + * */ -static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int flag) +static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int hdrversion, + 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 && @@ -822,13 +825,25 @@ static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int flag) "Incomplete HP-PA PALO boot parameters"); return ISO_HPPA_PALO_INCOMPL; } + if (hdrversion == 4) { + /* Bytes 256 to 32767 may come from loaded ISO image or external file */ + memset(buf, 0, 256); + } else if(hdrversion == 5) { + memset(buf, 0, 512); + memset(buf + 1024, 0, 1024); + } else { + iso_msg_submit(img->id, ISO_WRONG_ARG_VALUE, 0, + "Unsupported HP-PA PALO header version %d (can do 4 or 5)", + hdrversion); + return ISO_WRONG_ARG_VALUE; + } /* Magic */ iso_msb(buf + 0, 0x8000, 2); /* Name of boot loader */ - memcpy(buf + 2, "PALO", 4); + memcpy(buf + 2, "PALO", 5); /* Version */ - iso_msb(buf + 6, 0x0004, 2); + buf[7] = hdrversion; /* Byte address and byte count of the "HPPA 32-bit kernel" file */ @@ -846,13 +861,15 @@ static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int flag) 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; + if (hdrversion == 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); } - memcpy(buf + 24, img->hppa_cmdline, strlen(img->hppa_cmdline) + 1); /* Byte address and byte count of the "HPPA 64-bit kernel" file */ @@ -870,6 +887,16 @@ static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int flag) iso_msb(buf + 240, adr, 4); iso_msb(buf + 244, len, 4); + /* >>> ??? iso_msb(buf + 248, ipl_entry, 4); */ + + if (hdrversion == 5) { + if (strlen(img->hppa_cmdline) > 1023) { + iso_msg_submit(img->id, ISO_HPPA_PALO_CMDLEN, 0, + "HP-PA PALO command line too long"); + return ISO_HPPA_PALO_CMDLEN; + } + memcpy(buf + 1024, img->hppa_cmdline, strlen(img->hppa_cmdline) + 1); + } return ISO_SUCCESS; } @@ -1698,8 +1725,9 @@ 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); + } else if (sa_type == 4 || sa_type == 5) { + /* (By coincidence, sa_type and PALO header versions match) */ + ret = make_hppa_palo_sector(t, buf, sa_type, 0); if (ret != ISO_SUCCESS) return ret; } else if ((t->opts->partition_offset > 0 || will_append) &&