Bit more detail here:
In my picture above, I have an external big adjustable DC power supply (the type youâd see on an electronics lab bench) set at 1.9V. Youâll want to make sure your battery is disconnected before attempting any of this. When powering on the DC supply, I noticed it was drawing 0.2A, which is much more than the Winbond flash part should be consuming, even while actively being read/written. This implies that (maybe?) I was powering other parts of the 1.8V logic on the mainboard, but it didnât cause a problem for me, and I left it powered for several hours non-stop. I also had the /RESET
and /WP
pins of the SPI flash tied high (to the 1.9V of my power supply). I did not bother connecting these to the Raspberry PI for it to control.
The level-shifter I used was this one from Amazon, which I just happened to have on-hand. I expect anything capable of adapting from 3.3V to 1.8V at a reasonable frequency would work fine. I ran my SPI reads/writes at 256kHz - on the low side, which was important considering I was using some fairly long jumper wires.
I used this article as a great reference on how to hook things up to the Raspberry Pi and configure it to use the SPI-0 peripheral. I was using a Raspberry Pi 5, but I know that at least the Raspberry Pi 4 has the same pinout and should work identically.
After I had the SPI bus configured on the RPI (per the guide above) and had everything hooked up with the level shifter, I ran the following to confirm I was detecting the expected flash chip:
$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=256 --wp-status
flashrom v1.6.0-devel (git:v1.5.0-33-gc3b89597) on Linux 6.6.74+rpt-rpi-2712 (aarch64)
flashrom is free software, get the source code at https://flashrom.org
Found Winbond flash chip "W25Q256JW" (32768 kB, SPI) on linux_spi.
Protection range: start=0x00000000 length=0x00000000 (none)
Protection mode: disabled
The chip isnât technically a W25Q256JW
- it is W25R256JWEQ
. But that didnât matter - I didnât dig in much but I expect the difference is due to the logic level and the package.
I then did a couple different reads to separate files, and made sure they matched. An example read:
$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=256 -r fw-bios-orig-1.bin --progress
flashrom v1.6.0-devel (git:v1.5.0-33-gc3b89597) on Linux 6.6.74+rpt-rpi-2712 (aarch64)
flashrom is free software, get the source code at https://flashrom.org
Found Winbond flash chip "W25Q256JW" (32768 kB, SPI) on linux_spi.
Reading flash...
[READ: 100%]...done.
Next step was to extract the portion of the UBI capsule file (e.g. Framework_Laptop_13_Ryzen7040_capsule_signed_allsku_3.07.cap
) that contained the actual SPI flash contents. This was my first time dealing with these UEFI capsules, but by using UEFITool, binwalk, and some basic hex comparisons (both on my dumped SPI flash contents and the capsule file from the Framework upgrade zip), I came to the following conclusions:
- My SPI flash seemed to have been mostly (if not fully) updated to 3.07. All of the firmware regions matched perfectly with the UEFI capsule file. The differences were only in some non-zeroed padding regions, along with the expected differences in the nvram VSS store region (where BIOS settings and other non-volatile status is saved). I still have no idea which of these two differences was causing it to fail to boot.
- The UEFI capsule file had some header stuff, then a couple Microsoft PE-formatted executables, then the actual SPI flash payload, then finally some trailing random data. I didnât bother digging it into any more than necessary to figure out which region of this file I needed to flash. I primarily used UEFITool to figure out the relative offsets of the regions between my SPI flash dump and the UEFI capsule file.
Once I had my offset and length figured out, I extracted the SPI flash portion of the UEFI capsule as follows:
$ md5sum Framework_Laptop_13_Ryzen7040_capsule_signed_allsku_3.07.cap
ae4043c17d95f36f14f342e6deca3c5e Framework_Laptop_13_Ryzen7040_capsule_signed_allsku_3.07.cap
$ tail -c +1993293 Framework_Laptop_13_Ryzen7040_capsule_signed_allsku_3.07.cap | head -c 33554432 > framework-3.07-rom.bin
$ md5sum framework-3.07-rom.bin
e8241cda9edf65627d84303f9e6f91af framework-3.07-rom.bin
IMPORTANT NOTE: The offset and md5sums will be different if youâre trying to flash a different version of the BIOS.
Next, I went ahead and flashed away:
$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=256 -w framework-3.07-rom.bin --progress
flashrom v1.6.0-devel (git:v1.5.0-33-gc3b89597) on Linux 6.6.74+rpt-rpi-2712 (aarch64)
flashrom is free software, get the source code at https://flashrom.org
Found Winbond flash chip "W25Q256JW" (32768 kB, SPI) on linux_spi.
Reading old flash chip contents...
[READ: 100%]...done.
Updating flash chip contents...
[WRITE: 100%]...Erase/write done from 0 to 1ffffff
Verifying flash...
[READ: 100%]...VERIFIED.
I then disconnected all my wires, cleaned off the solder flux, booted up my laptop, and breathed a huge sigh of relief when I got my LUKS password prompt. Everything has been working flawlessly for the ~6 hours since doing this.
Also note this will wipe all BIOS settings to default (which I absolutely wanted to do).
After doing all this, I am noticing that fwupdmgr
is reporting that it wants to update my UEFI dbx
âŚ
$ fwupdmgr get-updates
Devices with no available firmware updates:
⢠WD BLACK SN850X 2000GB
Devices with the latest available firmware version:
⢠Fingerprint Sensor
⢠System Firmware
Framework Laptop 13 (AMD Ryzen 7040Series)
â
ââUEFI dbx:
â Device ID: 362301da643102b9f38477387e2193e57abaa590
â Summary: UEFI revocation database
â Current version: 20230501
â Minimum Version: 20230501
â Vendor: UEFI:Microsoft
â Install Duration: 1 second
â GUIDs: f8ba2887-9411-5c36-9cee-88995bb39731 â UEFI\CRT_A1117F516A32CEFCBA3F2D1ACE10A87972FD6BBE8FE0D0B996E09E65D802A503&ARCH_X64
â 115f7cac-f705-5d34-9a47-37177c3e8514 â UEFI\CRT_B38FAD316F525F27B27A21B486456C3E4279748BF16893827BF16FE659C0F75E&ARCH_X64
â Device Flags: ⢠Internal device
â ⢠Updatable
â ⢠Supported on remote server
â ⢠Needs a reboot after installation
â ⢠Device is usable for the duration of the update
â ⢠Only version upgrades are allowed
â ⢠Signed Payload
â
ââSecure Boot dbx Configuration Update:
New version: 20241101
Remote ID: lvfs
Release ID: 105821
Summary: UEFI Secure Boot Forbidden Signature Database
Variant: x64
License: Proprietary
Size: 15.1 kB
Created: 2025-01-17
Urgency: High
Tested by Linux Foundation:
Tested: 2025-01-20
Distribution: fedora 41 (workstation)
Old version: 20240301
Version[fwupd]: 2.0.4
Vendor: Linux Foundation
Duration: 1 second
Release Flags: ⢠Trusted metadata
⢠Is upgrade
⢠Tested by trusted vendor
Description:
This updates the list of forbidden signatures (the "dbx") to the latest release from Microsoft.
An insecure version of Howyar's SysReturn software was added, due to a security vulnerability that allowed an attacker to bypass UEFI Secure Boot.
Issues: 529659
CVE-2024-7344
Checksum: d661d4a0aaca09dfa9e56967ca2467b0575fc07cb704d182fa8c68225452957f
From my very limited experience on UEFI (from going through this recovery process), I learned that is a section in flash with a list of signatures of firmware that should be âblacklistedâ for secure-boot purposes. I donât use secure-boot (shame on me), and considering my shotty experience with the Framework BIOS update process, Iâm not touching this with a 10-foot pole. Iâll wait to do anything that writes to this SPI flash until absolutely necessary.
Happy hacking!