Wednesday, February 28, 2024
Google search engine
HomeUncategorizedInvestigating a vanishing BIOS on the Fujitsu Lifebook AH532

Investigating a vanishing BIOS on the Fujitsu Lifebook AH532

A few months ago, I got given a laptop with a very interesting condition.
The BIOS setup menu was supposedly inaccessible, and nothing apart from the default
boot option works. Time to investigate to see what is actually happening
and what we can do about it.

The status quo

When starting the laptop without doing anything special, the default option
boots just fine, as expected. However, while pressing F2 during boot causes
a beep tone, it ends up falling through to the same behavior as if nothing
was pressed. On the other hand, pressing F12 lands us in a very empty
boot menu:

The broken boot menu
The broken application menu

This, obviously, is not good. The boot menu should (at least) show all bootable
UEFI devices in addition to the boot entries that have been created manually.

Of course, the first thing that one would try is to reset the BIOS settings.
Since the CMOS battery is quite hidden behind plastic shielding, I instead
bridged the CL1_CL2 test point that is located under the RAM slot.

After the BIOS reinitialized, the boot menu looks like the following:

The partially fixed boot menu
The partially fixed application menu

The manually created boot option is now gone, and device-based boot options
show up instead. However, trying to enter the BIOS setup menu still shows the same
fallthrough behavior as it did before.

Luckily, there now is the option to boot from USB storage, so the BIOS
flash utilities provided by Fujitsu
are a possibility going forward. Note that (at least for the AH532)
there are multiple hardware revisions, so I had to go through the
device serial number to arrive at the correct set of downloads.

After flashing the BIOS and rebooting, the boot menu looks normal
and pressing F2 to enter the BIOS setup menu works like a charm:

The complete boot menu
The complete application menu

Isolating a reproducer

Now that I was back in a working setup, the first thing I did was to make
a backup of the current configuration. For that, I made an image of the
Winbond 25Q32BVSIG SPI flash chip that is marked as “U35” on the motherboard,
as it contains the whole UEFI PI firmware volume including executable code
and data storage. Whenever something is broken, I can now just flash back
the image instead of going through a full reset-CMOS-and-update-firmware cycle.

Location of the U35 chip on the motherboard

For easier testing, I also wanted a better reproducer than “reinstall your distribution of choice”.
Therefore, I tried the first thing that came to mind, and it immediately broke the boot menu again:

# efibootmgr -c
BootOrder: 0000
Boot0000* Linux

Warning: Do NOT run this command twice. Doing so made the boot menu completely inaccessible.

Excursion: UEFI boot entry handling

At a high level, UEFI stores data in a large key-value store that is collectively called
“UEFI variables”. Included in those variables are (among other things) boot entries and
related settings. Variable access is done through standardized interfaces
that are documented in the UEFI specification.

Boot entries are stored in entries named BootXXXX, where XXXX is a four digit hexadecimal
number. Boot option order is determined through the BootOrder entry, which lists all
four digit hexadecimal numbers in the order that they should appear in.

On my Framework laptop, the boot entries are set up as follows:

BootOrder: 0002, 0001, 2001, 2002, 2003
Boot0001: "Windows Boot Manager"
Boot0002: "GRUB"
Boot2001: "EFI USB Device"
Boot2002: "EFI DVD/CDROM"
Boot2003: "EFI Network"

Putting the pieces together

Suddenly, the efibootmgr -c output above doesn’t look all that confidence-inspiring.
The command is supposed to create a new entry and insert it at the top of the
boot entry list, but it ended up clearing the entire list instead. Running efibootmgr
on a fresh boot also doesn’t result in quite the expected output:

# efibootmgr -v
Could not read variable 'BootNext': No such file or directory
Could not read variable 'BootCurrent': No such file or directory
Could not read variable 'BootTimeout': No such file or directory
Could not read variable 'BootOrder': No such file or directory
No BootOrder is set; firmware will attempt recovery
Could not read variable 'MirrorCurrent': No such file or directory
Could not read variable 'MirrorRequest': No such file or directory

It appears that Linux is unable to read existing variables from storage, which is
immediately confirmed by inspecting the source of truth:

# ls -al /sys/firmware/efi/efivars/
total 0
drwxr-xr-x 2 root root 0 Jan 15 16:09 .
drwxr-xr-x 5 root root 0 Jan 15 16:09 ..

Note: At this point, I checked that Windows and various other UEFI tools are
able to read the variables just fine, so Linux’ output is confirmed to be incorrect.

Now, this explains why the custom boot entries and the device-based boot entries
end up being gone. efibootmgr can’t find any existing boot entry setup and just
assumes that it can create a new setup without repercussions.

But why does it make the BIOS setup unusable? Using UEFITool,
I inspected the flash image I made earlier, and reconstructed the following entries:

BootOrder: 000E, 000D, 0006, 0007, 0008, 0009, 000A, 000B
Boot0000: "BIOS Setup"
Boot0001: "Boot Menu"
Boot0002: "Diagnostic Screen"
Boot0003: "Recovery 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: "Windows Boot Manager"
Boot000E: "proxmox"

Oh, no…

“BIOS Setup” is an actual boot menu entry.

And it gets overwritten by the new boot entry that gets placed erroneously.

Note: Attentive readers might have noticed the reason for why everything breaks
completely when running efibootmgr -c twice: The second boot entry that
is created would be Boot0001, which successfully replaces “Boot Menu”.

Creating a temporary band-aid

Now that I knew what went wrong, I was able to create a small program that resets
the boot order, as well as the BIOS setup and boot menu entries to their expected
contents.

Note: This program is based on an UEFI dump of a Fujitsu LIFEBOOK AH532 (YLKV).
It is unlikely that it will work on any other hardware (revision) that happens to have
the same symptoms. Furthermore, the written data may also be dependent on the firmware
revision, so take caution when running this on a firmware version that is not v1.08 or
v1.09.

Warning: I assume no liability for broken hardware or software due to correct or incorrect
usage of this tool.

#include 

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,       // Type: Media Device Path
    0x06,       // Sub-Type: PIWG Firmware File
    0x14, 0x00, // Length: 4 + 0x14
    0x66, 0x8B, 0x1C, 0x72, 0x6C, 0x42, 0x86, 0x4E, 0x8E, 0x99, 0x34, 0x57, 0xC4, 0x6A, 0xB0, 0xB9,

    // FilePathList[1]
    0x7F,       // Type: End of Hardware Device Path
    0xFF,       // Sub-Type: End Entire Device Path
    0x04, 0x00, // Length: 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,       // Type: Media Device Path
    0x06,       // Sub-Type: PIWG Firmware File
    0x14, 0x00, // Length: 4 + 0x14
    0x40, 0x84, 0x48, 0x86, 0xBB, 0x41, 0xC7, 0x42, 0x93, 0xAC, 0x45, 0x0F, 0xBF, 0x77, 0x66, 0xBF,

    // FilePathList[1]
    0x7F,       // Type: End of Hardware Device Path
    0xFF,       // Sub-Type: End Entire Device Path
    0x04, 0x00, // Length: 4

    // OptionalData (empty)
};

int main() {
    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 a great solution, since users will continue to brick their installations initially, just like they
did for the last 10 years. However, this is everything
that I managed to research so far, and the band-aid fix makes it reasonable for publication.

I will look into fixing this properly at some point in the future, and if I manage to do so this post will probably get a part
two, so stay tuned. (Apparently Jekyll supports RSS?)

Read More

RELATED ARTICLES

2 COMMENTS

  1. I engaged on this online casino site and won a substantial amount, but eventually, my mother fell ill, and I wanted to cash out some funds from my balance. Unfortunately, I faced issues and could not finalize the cashout. Tragically, my mother passed away due to such casino site. I request for your help in reporting this site. Please assist me to obtain justice, so that others won’t have to face the pain I am going through today, and stop them from shedding tears like mine. 😭😭😭�

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments