Red Hat 7.4: How to inject kickstart file into USB media for UEFI-only system?
The decisive advantage of original over genisoimage remake is probably in the line
-boot_image isolinux partition_entry=gpt_basdat
genisoimage cannot make partition tables for EFI. (Inspect both ISOs by "/sbin/fdisk -l" to see the difference.) You actually need the MBR partition of type 0xef. But tradition is to also add an invalid and thus useless GPT.
One way to get the partition tables would be to run after genisoimage
isohybrid --uefi $THISDIR/$VOLLABEL.iso
The program stems from SYSLINUX source. One should use the version from the same source release or git clone from which "isolinux.bin" stems.
Other distros use xorriso's mkisofs emulation with the boot options which this xorriso command tells:
xorriso -indev rhel-server-7.4-x86_64-dvd.iso -report_el_torito as_mkisofs
There will be a lengthy addess to option -isohybrid-mbr:
--interval:imported_iso:0s-15s:zero_mbrpt,zero_gpt:'rhel-server-7.4-x86_64-boot.iso
It tells xorriso to use the first 32 KiB of the original ISO as MBR template and further System Area. Normally it is SYSLINUX file "isohdpfx.bin", which has only 432 bytes. You may replace it by "mbr.bin" after copying the first 432 bytes yourself:
dd if=rhel-server-7.4-x86_64-dvd.iso bs=432 count=1 of=mbr.bin
I now have completed the process, thanks to @Thomas Schmitt's invaluable tip.
Here is the complete process.
Overview
You must modify three files on the original Red Hat DVD:
isolinux/isolinux.cfg
EFI/BOOT/grub.cfg
images/efiboot.img
Decide on a volume label that you want to use. The volume label should be shorter than 14 characters.
Then use genisoimage
to build the new ISO with that volume label, use isohybrid --uefi
to make it UEFI compatible, and use implantisomd5
to update the correct checksum
Step-by-Step
I have scripted this, but the script is very specific to our situation, so no point in posting it.
- Mount the original Red Hat DVD using
fuseiso
. - Set an environment variable
VOLUMELABEL
to your chosen volume label. - Copy the three files you need to modify to another location.
Edit the isolinux.cfg
file. This file will be used for BIOS booting.
- Edit the
isolinux.cfg
file, adding the argument to the first two lines that start withappend
:ks=hd:LABEL=$VOLUMELABEL:/ks.cfg
. - Update the
inst.stage2
argument everywhere you find it (probably four places) to read:inst.stage2=hd:LABEL=$VOLUMELABEL
. - You may also want to remove the
menu default
entry so your image defaults toInstall
instead ofTest & Install
.
Edit the grub.cfg
file. This file will be used for EFI booting. Note that this file (and everything in EFI/BOOT
) will exist twice: once on the regular DVD image, and also inside the efiboot.img
file.
- Add the same argument to the first two lines that start with
linuxefi
. - Update the
inst.stage2
argument everywhere you find it (probably four places) to read:inst.stage2=hd:LABEL=$VOLUMELABEL
. - IMPORTANT AND EASY TO OVERLOOK: Also edit the line that starts with
search
ingrub.cfg
.
Edit the efiboot.img
file. This will actually be booted by EFI.
- Mount your copy of the
efiboot.img
file. Unfortunately, I have not found a way to do this withfusermount
, so you have to be root to do this. - Copy the modified
grub.cfg
into theefiboot.img
file underEFI/BOOT
- Umount your copy of the
efiboot.img
file.
Now you can generate the ISO image.
The arguments to genisoimage
are position-sensitive. Key points: I base the image on the original mounted ISO file (mounted as $TMPDIR
), then use -m
to exclude the three modified files, and use graft points to insert the modifications, as well as the kickstart file, into the image. In my image, I also removed the directory addons.
genisoimage \
-untranslated-filenames \
-graft-points \
-rational-rock \
-v \
-translation-table \
-input-charset "default" \
-J \
-joliet-long \
-V $VOLLABEL -A $VOLLABEL -volset $VOLLABEL \
-b isolinux/isolinux.bin \
-c isolinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-eltorito-alt-boot \
-efi-boot images/efiboot.img \
-no-emul-boot \
-quiet \
-o $THISDIR/$VOLLABEL.iso \
-m $TMPDIR/EFI/BOOT/grub.cfg \
-m $TMPDIR/isolinux/isolinux.cfg \
-m $TMPDIR/images/efiboot.img \
-m addons \
$TMPDIR \
EFI/BOOT/grub.cfg=$TMPGRAFT/grub.cfg \
isolinux/isolinux.cfg=$TMPGRAFT/isolinux.cfg \
images/efiboot.img=$TMPGRAFT/efiboot.img \
$KICKSTARTFILE=$KICKSTARTDIR/$KICKSTARTFILE
Then use isohybrid --uefi
and implantisomd5
:
isohybrid --uefi $THISDIR/$VOLUMELABEL.iso
implantisomd5 $THISDIR/$VOLUMELABEL.iso
Based on answers from Thomas and Kevin I managed to get a working procedure based on xorriso
, which is available from EPEL. My goals were similar to Kevin's:
- Use a stock RHEL 7 installation media
- Implant a kickstart and configuration scripts into the resulting image
- Select the kickstart automatically for installation
- Produce an image compatible with UEFI boot
- Make the procedure scripted
Tested successfully with RHEL 7.5 and 7.6.
Step by step procedure
- Have
xorriso
installed from EPEL. - Have RHEL 7 installation DVD downloaded in
$ISO_SRC
. - Have your kickstart (
ks.cfg
) and scripts ready in$SCRIPTS
. Extract files, which need to be customized, from ISO into
$FILES
:isolinux/isolinux.cfg
EFI/BOOT/grub.cfg
images/efiboot.img
Modify the
*.cfg
boot configuration files in$FILES
:Note: I do not modify the disc label (or volume ID) intentionally. It is space sensitive (potentially any special characters) and I found it easier to reuse it instead of replacing.
add kickstart parameter to boot command
'(.*)(hd:LABEL=\S+)(.*)'
→'\1\2 inst.ks=\2:/$SCRIPTS/ks.cfg\3'
set default boot menu for legacy boot in
isolinux.cfg
'^\s*menu default\s*\n'
→''
set default boot menu for UEFI boot in
grub.cfg
'set default=.*'
→'set default="0"'
Modify the UEFI boot image
images/efiboot.img
in$FILES
:- mount it in a temporary directory
- copy the UEFI boot menu
$FILES/EFI/BOOT/grub.cfg
into it - unmount
Build your customized image:
xorriso \ -indev "$ISO_SRC" \ -map "$SCRIPTS" /"$SCRIPTS" \ -map "$FILES" / \ -boot_image any replay \ -outdev "$ISO_DST"
The command copies contents of the source ISO image
$ISO_SRC
, merges local directories' contents and replays all boot settings from the source into the destination image$ISO_DST
. No further steps are required.
Note on geniso
method
I had hard time with following the geniso
method as described by Kevin. I managed to produce the output ISO image, however, geniso
was complaining about not being able to modify the isolinux.bin
image, hence I had to extract it too. This is not mentioned in the procedure.
I faced the wall on enabling the UEFI boot with isohybrid
. It returned an error I did not find a workaround for:
$ isohybrid --uefi rhel-custom.iso
isohybrid: rhel-custom.iso: boot loader does not have an isolinux.bin hybrid
signature. Note that isolinux-debug .bin does not support hybrid booting
Ansible role
I did create an Ansible role, which performs the task: build_boot_iso.