From ca3aaadb382226e182fc9a8724765dfbab711b8e Mon Sep 17 00:00:00 2001 From: jmatthew Date: Tue, 21 Nov 2023 08:46:06 +0000 Subject: [PATCH] Add '-e' (or -eltorito-boot-efi) option for writing an EFI eltorito boot image, in addition to or instead of the x86 boot image, to the output file. Per the UEFI standard, the EFI boot image should be an image of an EFI System Partition to be loaded in no-emulation mode, so we always record it that way rather than checking if it looks like a floppy image. with, tested by and ok yasuoka@ strong encouragement from deraadt@ --- gnu/usr.sbin/mkhybrid/src/defaults.h | 3 +- gnu/usr.sbin/mkhybrid/src/eltorito.c | 50 ++++++++++++++++++++++++---- gnu/usr.sbin/mkhybrid/src/iso9660.h | 13 +++++++- gnu/usr.sbin/mkhybrid/src/mkhybrid.8 | 18 +++++++++- gnu/usr.sbin/mkhybrid/src/mkisofs.c | 11 ++++++ gnu/usr.sbin/mkhybrid/src/mkisofs.h | 3 +- 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/gnu/usr.sbin/mkhybrid/src/defaults.h b/gnu/usr.sbin/mkhybrid/src/defaults.h index 2003f9ad8fb..766546446a6 100644 --- a/gnu/usr.sbin/mkhybrid/src/defaults.h +++ b/gnu/usr.sbin/mkhybrid/src/defaults.h @@ -2,7 +2,7 @@ * Header file defaults.h - assorted default values for character strings in * the volume descriptor. * - * $Id: defaults.h,v 1.1 2000/10/10 20:40:13 beck Exp $ + * $Id: defaults.h,v 1.2 2023/11/21 08:46:06 jmatthew Exp $ */ #define PREPARER_DEFAULT NULL @@ -17,6 +17,7 @@ #define VOLUME_ID_DEFAULT "CDROM" #define BOOT_CATALOG_DEFAULT "boot.catalog" #define BOOT_IMAGE_DEFAULT NULL +#define EFI_BOOT_IMAGE_DEFAULT NULL #ifdef APPLE_HYB #define DEFTYPE "TEXT" /* default Apple TYPE */ #define DEFCREATOR "unix" /* default Apple CREATOR */ diff --git a/gnu/usr.sbin/mkhybrid/src/eltorito.c b/gnu/usr.sbin/mkhybrid/src/eltorito.c index ccb44542118..4526d98c440 100644 --- a/gnu/usr.sbin/mkhybrid/src/eltorito.c +++ b/gnu/usr.sbin/mkhybrid/src/eltorito.c @@ -44,6 +44,8 @@ static struct eltorito_validation_entry valid_desc; static struct eltorito_defaultboot_entry default_desc; static struct eltorito_boot_descriptor gboot_desc; +static struct eltorito_sectionheader_entry shdr_desc; +static struct eltorito_defaultboot_entry efi_desc; static int tvd_write __PR((FILE * outfile)); @@ -120,8 +122,9 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) int bootcat; int checksum; unsigned char * checksum_ptr; - struct directory_entry * de; + struct directory_entry * de = NULL; struct directory_entry * de2; + struct directory_entry * efi_de = NULL; int i; int nsectors; @@ -149,8 +152,12 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) * now adjust boot catalog * lets find boot image first */ - de=search_tree_file(root, boot_image); - if (!de) + if (boot_image != NULL) + de=search_tree_file(root, boot_image); + if (efi_boot_image != NULL) + efi_de=search_tree_file(root, efi_boot_image); + + if (de == NULL && efi_boot_image == NULL) { fprintf(stderr,"Uh oh, I cant find the boot image!\n"); exit(1); @@ -162,7 +169,8 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) */ memset(&valid_desc, 0, sizeof(valid_desc)); valid_desc.headerid[0] = 1; - valid_desc.arch[0] = EL_TORITO_ARCH_x86; + valid_desc.arch[0] = + (boot_image != NULL)? EL_TORITO_ARCH_x86 : EL_TORITO_ARCH_EFI; /* * we'll shove start of publisher id into id field, may get truncated @@ -198,6 +206,8 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) checksum = -checksum; set_721(valid_desc.cksum, (unsigned int) checksum); + if (de == NULL) + goto skip_x86; /* * now make the initial/default entry for boot catalog */ @@ -279,7 +289,28 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) #endif set_731(default_desc.bootoff, (unsigned int) get_733(de->isorec.extent)); - + skip_x86: + /* + * add the EFI boot image, if specified + */ + if (efi_de != NULL) { + if (de != NULL) { + memset(&shdr_desc, 0, sizeof(shdr_desc)); + shdr_desc.header_id[0] = EL_TORITO_SHDR_ID_LAST_SHDR; + shdr_desc.platform_id[0] = EL_TORITO_ARCH_EFI; + set_721(shdr_desc.entry_count, 1); + } + + memset(&efi_desc, 0, sizeof(efi_desc)); + efi_desc.boot_id[0] = EL_TORITO_BOOTABLE; + set_721(efi_desc.loadseg, 0); + efi_desc.arch[0] = EL_TORITO_ARCH_EFI; + + nsectors = ((efi_de->size + 511) & ~(511))/512; + set_721(efi_desc.nsect, nsectors); + set_731(efi_desc.bootoff, (unsigned int)get_733(efi_de->isorec.extent)); + } + /* * now write it to disk */ @@ -295,7 +326,14 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) * write out */ write(bootcat, &valid_desc, 32); - write(bootcat, &default_desc, 32); + if (de != NULL) + { + write(bootcat, &default_desc, 32); + if (efi_de != NULL) + write(bootcat, &shdr_desc, sizeof(shdr_desc)); + } + if (efi_de != NULL) + write(bootcat, &efi_desc, sizeof(efi_desc)); close(bootcat); } /* get_torito_desc(... */ diff --git a/gnu/usr.sbin/mkhybrid/src/iso9660.h b/gnu/usr.sbin/mkhybrid/src/iso9660.h index 622727037bf..e8561101a5f 100644 --- a/gnu/usr.sbin/mkhybrid/src/iso9660.h +++ b/gnu/usr.sbin/mkhybrid/src/iso9660.h @@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: iso9660.h,v 1.1 2000/10/10 20:40:16 beck Exp $ + * $Id: iso9660.h,v 1.2 2023/11/21 08:46:06 jmatthew Exp $ */ #ifndef _ISOFS_FS_H @@ -52,6 +52,7 @@ struct iso_volume_descriptor { #define EL_TORITO_ARCH_x86 0 #define EL_TORITO_ARCH_PPC 1 #define EL_TORITO_ARCH_MAC 2 +#define EL_TORITO_ARCH_EFI 0xEF #define EL_TORITO_BOOTABLE 0x88 #define EL_TORITO_MEDIA_NOEMUL 0 #define EL_TORITO_MEDIA_12FLOP 1 @@ -129,6 +130,16 @@ struct eltorito_defaultboot_entry { char pad2 [ISODCL ( 13, 32)]; }; +/* El Torito section header entry in boot catalog */ +struct eltorito_sectionheader_entry { +#define EL_TORITO_SHDR_ID_SHDR 0x90 +#define EL_TORITO_SHDR_ID_LAST_SHDR 0x91 + char header_id [ISODCL ( 1, 1)]; /* 711 */ + char platform_id [ISODCL ( 2, 2)]; + char entry_count [ISODCL ( 3, 4)]; /* 721 */ + char id [ISODCL ( 5, 32)]; +}; + /* We use this to help us look up the parent inode numbers. */ diff --git a/gnu/usr.sbin/mkhybrid/src/mkhybrid.8 b/gnu/usr.sbin/mkhybrid/src/mkhybrid.8 index 884b3127fec..33b0a82b552 100644 --- a/gnu/usr.sbin/mkhybrid/src/mkhybrid.8 +++ b/gnu/usr.sbin/mkhybrid/src/mkhybrid.8 @@ -2,7 +2,7 @@ .\" To print, first run through tbl .\" -*- nroff -*- .\" -.\" $Id: mkhybrid.8,v 1.4 2022/07/11 03:11:49 daniel Exp $ +.\" $Id: mkhybrid.8,v 1.5 2023/11/21 08:46:06 jmatthew Exp $ .\" .TH MKHYBRID 8 "7 April 1999" "Version 1.12b5.1" .SH NAME @@ -46,6 +46,10 @@ mkhybrid \- create an hybrid ISO9660/JOLIET/HFS filesystem with optional Rock Ri .B \-D ] [ +.B \-e +.I efi_boot_image +] +[ .B \-hide .I glob ] @@ -474,6 +478,18 @@ Do not use deep directory relocation, and instead just pack them in the way we see them. This violates the ISO9660 standard, but it works on many systems. Use with caution. .TP +.BI \-e " efi_boot_image +Specifies the path and filename of the EFI boot image to be used when making +an "El Torito" bootable CD. +The pathname must be relative to the source path specified to +.B mkhybrid. +The file should contain an EFI system partition image. +The +.B \-e +option can be used with or without the +.B \-b +option. +.TP .B \-f Follow symbolic links when generating the filesystem. When this option is not in use, symbolic links will be entered using Rock Ridge if enabled, otherwise diff --git a/gnu/usr.sbin/mkhybrid/src/mkisofs.c b/gnu/usr.sbin/mkhybrid/src/mkisofs.c index 6ff61065835..f59c5a7ac57 100644 --- a/gnu/usr.sbin/mkhybrid/src/mkisofs.c +++ b/gnu/usr.sbin/mkhybrid/src/mkisofs.c @@ -110,6 +110,7 @@ char * volume_id = VOLUME_ID_DEFAULT; char * system_id = SYSTEM_ID_DEFAULT; char * boot_catalog = BOOT_CATALOG_DEFAULT; char * boot_image = BOOT_IMAGE_DEFAULT; +char * efi_boot_image = EFI_BOOT_IMAGE_DEFAULT; int volume_set_size = 1; int volume_sequence_number = 1; @@ -274,6 +275,8 @@ static const struct ld_option ld_options[] = 'd', NULL, "Omit trailing periods from filenames", ONE_DASH }, { {"disable-deep-relocation", no_argument, NULL, 'D'}, 'D', NULL, "Disable deep directory relocation", ONE_DASH }, + { {"eltorito-boot-efi", required_argument, NULL, 'e' }, + 'e', "FILE", "Set El Torito EFI boot image name" , ONE_DASH }, { {"follow-links", no_argument, NULL, 'f'}, 'f', NULL, "Follow symbolic links", ONE_DASH }, { {"help", no_argument, NULL, OPTION_HELP}, @@ -865,6 +868,14 @@ int FDECL2(main, int, argc, char **, argv){ exit(1); } break; + case 'e': + use_eltorito++; + efi_boot_image = optarg; + if (efi_boot_image == NULL) { + fprintf(stderr,"Required EFI boot image pathname missing\n"); + exit(1); + } + break; case 'c': use_eltorito++; boot_catalog = optarg; /* pathname of the boot image on cd */ diff --git a/gnu/usr.sbin/mkhybrid/src/mkisofs.h b/gnu/usr.sbin/mkhybrid/src/mkisofs.h index e7af9e66b3d..5f1065e9893 100644 --- a/gnu/usr.sbin/mkhybrid/src/mkisofs.h +++ b/gnu/usr.sbin/mkhybrid/src/mkisofs.h @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: mkisofs.h,v 1.4 2015/09/09 20:02:31 miod Exp $ + * $Id: mkisofs.h,v 1.5 2023/11/21 08:46:06 jmatthew Exp $ */ /* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 12/3/99 */ @@ -462,6 +462,7 @@ extern char * system_id; extern char * volume_id; extern char * boot_catalog; extern char * boot_image; +extern char * efi_boot_image; extern int volume_set_size; extern int volume_sequence_number; -- 2.20.1