rhboot / shim

UEFI shim loader
Other
816 stars 284 forks source link

System always in a reboot loop when selecting hard disk as boot option #570

Open justinvson-pd opened 1 year ago

justinvson-pd commented 1 year ago

Hi,

I'm using a server on which I have installed ubuntu 22.04 server, which uses shim 15.7. It is installed on a micron MTFDDAK1T0TDL SSD.

Now, when I boot the "ubuntu" boot entry, everything is fine and it just works.

However, if I select the disk instead (This is something that I need to be able to do because of multiple boot devices being available), it will always unconditionally reboot.

I have enabled SHIM_VERBOSE and FALLBACK_VERBOSE variables, and the output contains the following lines (I can't give a full log very easily, I had to make a video of the KVM outputting the debug output):

shim.c:(1263):set_second_stage() Invoked from Removable Media Path, ignoring boot optionsshim.c:(866):load_image() attempting to load \EFI\BOOT\fbx64.efi

Now, the disk is certainly not a usb stick, so I'm a bit confused on as to why it would be detected as such. Maybe something to do with the fact that in EFI FW, \EFI\BOOT\BOOTX64.EFI is defined in tianocore/edk2/MdePkg/Include/Uefi/UefiSpec.h as the "Removable media" bootloader path?

fallback finds BOOTX64.CSV correctly, which contains "shimx64.efi,ubuntu,,This is the boot entry for ubuntu"

It also outputs "Found boot entry "Boot0006" with label "ubuntu" for file "\EFI\ubuntu\shimx64.efi"", and also prints the correct boot order. After this, it complains about finding a TPM and thus resets.

It seems to me that everything is going fine, but still for some reason it thinks it has to reset. As a sidenote: in earlier EFI FW versions it did work correctly.

Is this expected behaviour, or is my disk being detected as removable an indicator that something is wrong in the EFI fw? How can I make sure it doesn't reboot when the disk is selected without having to manually set efi variables?

dennis-tseng99 commented 1 year ago

However, if I select the disk instead, it will always unconditionally reboot.

The possible reason why "always reboot" might be that the 1st boot entry for disk is not correctly created which means the first_new_option variable is always NULL. To verify whether FileDevicePath() does get the right path, would you please print out your disk file DP in fallback.c ? Like this:

full_device_path = FileDevicePath(this_image->DeviceHandle, fullpath);
if (!full_device_path) {
    efi_status = EFI_OUT_OF_RESOURCES;
    goto done;
}
dps = DevicePathToStr(full_device_path);
VerbosePrint(L"file DP: %s\n", dps);

Here is the 1st entry file DP of my system:

file DP: PciRoot(0)/Pci(0x02,0x04)/Pci(0x0,0x0)/HD(1,GPT,875E2293-E4E5-482F-AEFD-234073DC3959)/\EFI\opensuse\shim.efi
justinvson-pd commented 1 year ago

The possible reason why "always reboot

Note that after a reboot it selects the "ubuntu" boot entry it created in the fallback so it works at that point. I'm just trying to avoid the reboot in the fallback, as it will recreate that ubuntu entry for every ubuntu disk that's inserted when the respective disk is selected, but all of the information I've encountered seems to suggest that it will always reboot when selecting the hard disk entry, is this correct?

dennis-tseng99 commented 1 year ago

\EFI\BOOT\BOOTX64.EFI is defined in tianocore/edk2/MdePkg/Include/Uefi/UefiSpec.h as the "Removable media" bootloader path?

The bootloader for a removable media like USB is not expected to create a NVRAM entry ahead, and is expected to be in \EFI\BOOT\BOOTX64.efi. The firmware will treat the disk as a removable media and invoke \EFI\BOOT\BOOTX64.efi if your boot variable is missing.

\EFI\BOOT\BOOTX64.EFI is a copy of shimx64.efi internally. It will trigger fallback to try to create "Boot0006" with label "ubuntu".

How can I make sure it doesn't reboot when the disk is selected without having to manually set efi variables?

Remove fbx64.efi, and let bootx64.efi executes your disk boot option directly. This is just a work around.

BTW, If possible, please print out the bootpath like the following example. If it still shows \EFI\BOOT\BOOTX64.EFI after the 1st reboot, which means fallback has been triggered but failed to create your disk boot option, and system will be reboot forever. Normally, after the 1st reboot, bootpath will show \EFI\opensuse\shim.efi, for example, if fallback can successfully create a boot option.

static int
is_removable_media_path(EFI_LOADED_IMAGE *li)
{
          ........

          /* Check the beginning of the string and the end, to avoid
           * caring about which arch this is. */
          /* I really don't know why, but sometimes bootpath gives us
           * L"\\EFI\\BOOT\\/BOOTX64.EFI".  So just handle that here...
           */
          console_print(L"bootpath=%s\n",bootpath);
          msleep(5000000);
          if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) &&
                          StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15) &&
                          StrnCaseCmp(bootpath, L"EFI\\BOOT\\BOOT", 13) &&
                          StrnCaseCmp(bootpath, L"EFI\\BOOT\\/BOOT", 14))
               goto error;