From c0d74503797af6c534d9a50dea96e833be8ce3ca Mon Sep 17 00:00:00 2001 From: Itxaka Date: Wed, 11 Dec 2024 15:04:58 +0100 Subject: [PATCH] Fix different behaviour between usb and cd in efi (#135) * Use the efi image directly and set efi_boot_part this supposedly increases compatibility when booting from usb Mark the current El Torito boot image (see options -b and -e) in an actually invalid GPT as partition of type Basic Data. This works only with -isohybrid-mbr and has the same impact on the system area as -efi-boot-part. It cannot be combined with -efi-boot-part or -hfsplus. The first three boot images which are marked by GPT will also show up as partition entries in MBR. The MBR partition of type 0xEF is what actually is used by EFI firmware for booting from USB stick. The MBR partition for PC-BIOS gets type 0x00 rather than 0x17 in this case. Often the further MBR entries are the ones which actually get used by EFI. Signed-off-by: Itxaka * Make it work for livecd and usb Signed-off-by: Itxaka * Review comments Signed-off-by: Itxaka * Apply suggestions from code review Co-authored-by: Mauro Morales * Move dir creation to function Signed-off-by: Itxaka --------- Signed-off-by: Itxaka Co-authored-by: Mauro Morales --- pkg/constants/constants.go | 5 ++--- pkg/ops/iso.go | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 09d42e2..364160d 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -4,7 +4,6 @@ import ( _ "embed" "fmt" "os" - "path/filepath" ) // Eltorito image is basically a grub cdboot.img + grub core image @@ -107,11 +106,11 @@ func GetXorrisoBooloaderArgs(root string) []string { "-boot_image", "any", "platform_id=0x00", "-boot_image", "any", "emul_type=no_emulation", "-boot_image", "any", "load_size=2048", - "-append_partition", "2", "0xef", filepath.Join(root, IsoEFIPath), "-boot_image", "any", "next", - "-boot_image", "any", "efi_path=--interval:appended_partition_2:all::", "-boot_image", "any", "platform_id=0xef", "-boot_image", "any", "emul_type=no_emulation", + "-boot_image", "any", "efi_path=" + IsoEFIPath, // Tell where the efi path is + "-boot_image", "any", "efi_boot_part=--efi-boot-image", // Tell where the efi path is for booting } return args } diff --git a/pkg/ops/iso.go b/pkg/ops/iso.go index ba0eba5..5ee6b6c 100644 --- a/pkg/ops/iso.go +++ b/pkg/ops/iso.go @@ -368,6 +368,7 @@ func (b BuildISOAction) createEFI(rootdir string, isoDir string) error { // rootfs /efi dir img := filepath.Join(isoDir, constants.IsoEFIPath) + // Temp dir is where we will build the EFI image from temp, _ := utils.TempDir(b.cfg.Fs, "", "auroraboot-iso") err = utils.MkdirAll(b.cfg.Fs, filepath.Join(temp, constants.EfiBootPath), constants.DirPerm) if err != nil { @@ -394,8 +395,16 @@ func (b BuildISOAction) createEFI(rootdir string, isoDir string) error { // Its read from the root of the livecd, so we need to copy it into /EFI/BOOT/grub.cfg // This is due to the hybrid bios/efi boot mode of the livecd // the uefi.img is loaded into memory and run, but grub only sees the livecd root - err = b.cfg.Fs.WriteFile(filepath.Join(isoDir, constants.EfiBootPath, constants.GrubCfg), []byte(constants.GrubEfiCfg), constants.FilePerm) - if err != nil { + // WARNING: If we load the image into an usb stick, grub will not use the livecd root as the grub root, so it cannot find the grub.cfg + // So we copy in 2 places, into the livecd and into the img + + // This is used when booting from usb + if err = b.writeDefaultGrubEfiCfg(temp); err != nil { + b.cfg.Logger.Errorf("Failed writing grub.cfg: %v", err) + return err + } + // This is used when booting from cdrom + if err = b.writeDefaultGrubEfiCfg(isoDir); err != nil { b.cfg.Logger.Errorf("Failed writing grub.cfg: %v", err) return err } @@ -415,13 +424,12 @@ func (b BuildISOAction) createEFI(rootdir string, isoDir string) error { b.cfg.Logger.Infof("Detected Flavor: %s", flavor) if strings.Contains(strings.ToLower(flavor), "ubuntu") { b.cfg.Logger.Infof("Ubuntu based ISO detected, copying grub.cfg to /EFI/ubuntu/grub.cfg") - err = utils.MkdirAll(b.cfg.Fs, filepath.Join(isoDir, "EFI/ubuntu/"), constants.DirPerm) - if err != nil { + + if err = b.writeUbuntuGrubEfiCfg(temp); err != nil { b.cfg.Logger.Errorf("Failed writing grub.cfg: %v", err) return err } - err = b.cfg.Fs.WriteFile(filepath.Join(isoDir, "EFI/ubuntu/", constants.GrubCfg), []byte(constants.GrubEfiCfg), constants.FilePerm) - if err != nil { + if err = b.writeUbuntuGrubEfiCfg(isoDir); err != nil { b.cfg.Logger.Errorf("Failed writing grub.cfg: %v", err) return err } @@ -465,6 +473,22 @@ func (b BuildISOAction) createEFI(rootdir string, isoDir string) error { return nil } +// writeDefaultGrubEfiCfg writes the default grub.cfg for the EFI image in teh given path +func (b *BuildISOAction) writeDefaultGrubEfiCfg(path string) error { + calculatedPath := filepath.Join(path, constants.EfiBootPath, constants.GrubCfg) + return b.cfg.Fs.WriteFile(calculatedPath, []byte(constants.GrubEfiCfg), constants.FilePerm) +} + +func (b *BuildISOAction) writeUbuntuGrubEfiCfg(path string) error { + calculatedPath := filepath.Join(path, "EFI/ubuntu/", constants.GrubCfg) + err := utils.MkdirAll(b.cfg.Fs, calculatedPath, constants.DirPerm) + if err != nil { + b.cfg.Logger.Errorf("Failed writing grub.cfg: %v", err) + return err + } + return b.cfg.Fs.WriteFile(calculatedPath, []byte(constants.GrubEfiCfg), constants.FilePerm) +} + // copyShim copies the shim files into the EFI partition // tempdir is the temp dir where the EFI image is generated from // rootdir is the rootfs where the shim files are searched for