Investigating a vanishing BIOS on the Fujitsu LIFEBOOK AH532
Just a few months in the past, I obtained given a laptop computer with a really fascinating situation.
The BIOS setup menu was supposedly inaccessible, and nothing other than the default
boot choice works. Time to research to see what is definitely taking place
and what we will do about it.
The established order
When beginning the laptop computer with out doing something particular, the default choice
boots simply superb, as anticipated. Nonetheless, whereas urgent F2 throughout boot causes
a beep tone, it finally ends up falling by means of to the identical habits as if nothing
was pressed. Then again, urgent F12 lands us in a really empty
boot menu:
This, clearly, will not be good. The boot menu ought to (no less than) present all bootable
UEFI units along with the boot entries which were created manually.
After all, the very first thing that one would strive is to reset the BIOS settings.
For the reason that CMOS battery is sort of hidden behind plastic shielding, I as an alternative
bridged the CL1_CL2
take a look at level that’s positioned underneath the RAM slot.
After the BIOS reinitialized, the boot menu appears to be like like the next:
The manually created boot choice is now gone, and device-based boot choices
present up as an alternative. Nonetheless, attempting to enter the BIOS setup menu nonetheless exhibits the identical
fallthrough habits because it did earlier than.
Fortunately, there now could be the choice besides from USB storage, so the BIOS
flash utilities provided by Fujitsu
are a risk going ahead. Observe that (no less than for the AH532)
there are a number of {hardware} revisions, so I needed to undergo the
machine serial quantity to reach on the right set of downloads.
After flashing the BIOS and rebooting, the boot menu appears to be like regular
and urgent F2 to enter the BIOS setup menu works like a appeal:
Isolating a reproducer
Now that I used to be again in a working setup, the very first thing I did was to make
a backup of the present configuration. For that, I made a picture of the
Winbond 25Q32BVSIG SPI flash chip that’s marked as “U35” on the motherboard,
because it incorporates the entire UEFI PI firmware quantity together with executable code
and knowledge storage. At any time when one thing is damaged, I can now simply flash again
the picture as an alternative of going by means of a full reset-CMOS-and-update-firmware cycle.
For simpler testing, I additionally needed a greater reproducer than “reinstall your distribution of selection”.
Subsequently, I attempted the very first thing that got here to thoughts, and it instantly broke the boot menu once more:
# efibootmgr -c
BootOrder: 0000
Boot0000* Linux
Warning: Do NOT run this command twice. Doing so made the boot menu fully inaccessible.
Tour: UEFI boot entry dealing with
At a excessive degree, UEFI shops knowledge in a big key-value retailer that’s collectively known as
“UEFI variables”. Included in these variables are (amongst different issues) boot entries and
associated settings. Variable entry is finished by means of standardized interfaces
which can be documented in the UEFI specification.
Boot entries are saved in entries named BootXXXX
, the place XXXX
is a 4 digit hexadecimal
quantity. Boot choice order is decided by means of the BootOrder
entry, which lists all
4 digit hexadecimal numbers within the order that they need to seem in.
On my Framework laptop computer, the boot entries are arrange as follows:
BootOrder: 0002, 0001, 2001, 2002, 2003
Boot0001: "Home windows Boot Supervisor"
Boot0002: "GRUB"
Boot2001: "EFI USB System"
Boot2002: "EFI DVD/CDROM"
Boot2003: "EFI Community"
Placing the items collectively
All of the sudden, the efibootmgr -c
output above doesn’t look all that confidence-inspiring.
The command is meant to create a brand new entry and insert it on the high of the
boot entry listing, however it ended up clearing your entire listing as an alternative. Working efibootmgr
on a contemporary boot additionally doesn’t end in fairly the anticipated output:
# efibootmgr -v
Couldn't learn variable 'BootNext': No such file or listing
Couldn't learn variable 'BootCurrent': No such file or listing
Couldn't learn variable 'BootTimeout': No such file or listing
Couldn't learn variable 'BootOrder': No such file or listing
No BootOrder is ready; firmware will try restoration
Couldn't learn variable 'MirrorCurrent': No such file or listing
Couldn't learn variable 'MirrorRequest': No such file or listing
It seems that Linux is unable to learn current variables from storage, which is
instantly confirmed by inspecting the supply of fact:
# ls -al /sys/firmware/efi/efivars/
whole 0
drwxr-xr-x 2 root root 0 Jan 15 16:09 .
drwxr-xr-x 5 root root 0 Jan 15 16:09 ..
Observe: At this level, I checked that Home windows and varied different UEFI instruments are
in a position to learn the variables simply superb, so Linux’ output is confirmed to be incorrect.
Now, this explains why the customized boot entries and the device-based boot entries
find yourself being gone. efibootmgr
can’t discover any current boot entry setup and simply
assumes that it will probably create a brand new setup with out repercussions.
However why does it make the BIOS setup unusable? Utilizing UEFITool,
I inspected the flash picture I made earlier, and reconstructed the next entries:
BootOrder: 000E, 000D, 0006, 0007, 0008, 0009, 000A, 000B
Boot0000: "BIOS Setup"
Boot0001: "Boot Menu"
Boot0002: "Diagnostic Display screen"
Boot0003: "Restoration and Utility"
Boot0004: "Diagnostic Program"
Boot0005: "Diagnostic Progrogram ROM"
Boot0006: "Floppy Disk Drive"
Boot0007: "Drive0 HDD"
Boot0008: "CD/DVD Drive"
Boot0009: "NETWORK"
Boot000A: "USB HDD"
Boot000B: "USB CD/DVD"
Boot000C: "Erase Disk"
Boot000D: "Home windows Boot Supervisor"
Boot000E: "proxmox"
Oh, no…
“BIOS Setup” is an precise boot menu entry.
And it will get overwritten by the brand new boot entry that will get positioned erroneously.
Observe: Attentive readers may need observed the rationale for why every thing breaks
fully when operating efibootmgr -c
twice: The second boot entry that
is created can be Boot0001
, which efficiently replaces “Boot Menu”.
Creating a short lived band-aid
Now that I knew what went improper, I used to be in a position to create a small program that resets
the boot order, in addition to the BIOS setup and boot menu entries to their anticipated
contents.
Observe: This program relies on an UEFI dump of a Fujitsu LIFEBOOK AH532 (YLKV).
It’s unlikely that it’s going to work on every other {hardware} (revision) that occurs to have
the identical signs. Moreover, the written knowledge can also be depending on the firmware
revision, so take warning when operating this on a firmware model that isn’t v1.08 or
v1.09.
Warning: I assume no legal responsibility for damaged {hardware} or software program because of right or incorrect
utilization of this instrument.
#embrace <efivar/efivar.h>
uint32_t boot_attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
unsigned char bootorder_data[] = {
0x06, 0x00, // Boot0006
0x07, 0x00, // Boot0007
0x08, 0x00, // Boot0008
0x09, 0x00, // Boot0009
0x0A, 0x00, // Boot000A
0x0B, 0x00, // Boot000B
};
unsigned char boot0000_data[] = {
0x00, 0x01, 0x00, 0x00, // Attributes
0x18, 0x00, // FilePathListLength
// Description: "BIOS Setup "
0x42, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x53, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x74, 0x00, 0x75, 0x00, 0x70, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00,
// FilePathList[0]
0x04, // Sort: Media System Path
0x06, // Sub-Sort: PIWG Firmware File
0x14, 0x00, // Size: 4 + 0x14
0x66, 0x8B, 0x1C, 0x72, 0x6C, 0x42, 0x86, 0x4E, 0x8E, 0x99, 0x34, 0x57, 0xC4, 0x6A, 0xB0, 0xB9,
// FilePathList[1]
0x7F, // Sort: Finish of {Hardware} System Path
0xFF, // Sub-Sort: Finish Total System Path
0x04, 0x00, // Size: 4
// OptionalData (empty)
};
unsigned char boot0001_data[] = {
0x00, 0x01, 0x00, 0x00, // Attributes
0x18, 0x00, // FilePathListLength
// Description: "Boot Menu"
0x42, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x75, 0x00, 0x00, 0x00,
// FilePathList[0]
0x04, // Sort: Media System Path
0x06, // Sub-Sort: PIWG Firmware File
0x14, 0x00, // Size: 4 + 0x14
0x40, 0x84, 0x48, 0x86, 0xBB, 0x41, 0xC7, 0x42, 0x93, 0xAC, 0x45, 0x0F, 0xBF, 0x77, 0x66, 0xBF,
// FilePathList[1]
0x7F, // Sort: Finish of {Hardware} System Path
0xFF, // Sub-Sort: Finish Total System Path
0x04, 0x00, // Size: 4
// OptionalData (empty)
};
int foremost() {
int rc = efi_set_variable(EFI_GLOBAL_GUID, "BootOrder", bootorder_data, sizeof(bootorder_data), boot_attributes, 0644);
if (rc < 0) {
efi_error("Resetting BootOrder failed");
return 1;
}
rc = efi_set_variable(EFI_GLOBAL_GUID, "Boot0000", boot0000_data, sizeof(boot0000_data), boot_attributes, 0644);
if (rc < 0) {
efi_error("Resetting Boot0000 failed");
return 1;
}
rc = efi_set_variable(EFI_GLOBAL_GUID, "Boot0001", boot0001_data, sizeof(boot0001_data), boot_attributes, 0644);
if (rc < 0) {
efi_error("Resetting Boot0001 failed");
return 1;
}
}
Naturally, this isn’t an awesome answer, since customers will proceed to brick their installations initially, identical to they
did for the last 10 years. Nonetheless, that is every thing
that I managed to analysis to this point, and the band-aid repair makes it affordable for publication.
I’ll look into fixing this correctly sooner or later sooner or later, and if I handle to take action this put up will most likely get a component
two, so keep tuned. (Apparently Jekyll helps RSS?)