How to flash bios chips with Raspberry Pi

This post is an addition to my previous post: “How to flash bios chips with Arduino“.

While doing some research online I found several articles/posts from people using a Raspberry Pi to flash SPI flash chips. Apparently the Raspberry Pi  is very suitable for this kind of thing as it has a SPI interface and is able to run linux. I was eager to try this out for myself so I got out my Pi 3 model B and got to work. For this project I used a Winbond 25X80 salvaged from a motherboard I had lying around.

Preparing the RaspberryPi

As others have pointed out, the latest version of Raspbian (Stretch) will also work by adding the spispeed param to the Flashrom command.

Enable the SPI interfaces by typing sudo raspi-config and selecting P4 SPI under the Interfacing options.

Select option 5: Interfacing options
Select SPI to enable the SPI interfaces

The SPI interfaces will become available under /dev/spidev0.0 and /dev/spidev0.1.

Next we install the packages are needed by Flashrom by using the following command.

sudo apt install git libpci-dev libusb-1.0 libusb-dev

Make and install Flashrom.

git clone https://github.com/flashrom/flashrom.git
cd flashrom
make && sudo make install

Connecting the Raspberry to the SPI flash chip

The table below show the connections between the RaspberryPi and the chip.

RPi pin SPI flash
25 GND
24 CS
23 SCK
21 DO
19 DI
17 VCC 3.3V and /HOLD and /WP

Flashing the chip

In order to verify Flashrom correctly identifies the chip we run Flashrom without any operations.

pi@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512
flashrom p1.0-76-g291764a on Linux 4.14.34-v7+ (armv7l)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X80" (1024 kB, SPI) on linux_spi.
No operations were specified.

Now that Flashrom correctly identifies the Winbond W25X80 we can continue to backup the current BIOS.

pi@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -r flash.dat
flashrom p1.0-76-g291764a on Linux 4.14.34-v7+ (armv7l)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X80" (1024 kB, SPI) on linux_spi.
Reading flash... done.

After backing up the old BIOS we can safely write the new BIOS back to the chip.

pi@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512 -w flash.dat 
flashrom p1.0-76-g291764a on Linux 4.14.34-v7+ (armv7l)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X80" (1024 kB, SPI) on linux_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... 
Warning: Chip content is identical to the requested image.
Erase/write done.

References:

How to flash bios chips with Arduino

In this post I will explain how to flash bios chips with an Arduino. We will be using a Arduino Duemilnove (uno, mega or clones do also work) and a ASUS P5B motherboard that no longer boots after a failed bios update.

Here is an outline of the steps (some of these steps are not strictly necessary but I figured they might help the uninitiated):

  1. Identify board
  2. Find documentation for the board
  3. Locate and identify bios chip
  4. Find documentation for the chip
  5. Find pinout and operating voltages (important)
  6. Prepare the Arduino and installing flashrom
  7. Connecting the Arduino to the chip
  8. Testing
  9. Flashing and verify
  10. Troubleshooting

Identify board and finding documentation

As mentioned in the introduction we are using an ASUS P5B motherboard. The manual of this board can be found on the ASUS website (a direct link can be found in the list of references).

Locate and identifying the bios chip

In the manual we find a board layout that shows the location of the chip, to the right of pci slot 3.

In case the location is not documented we have to find it ourselves. The following page provides instructions on how to locate the bios chip: http://www.bios-chip24.com/Information/Bios-Chip-localization

The next step is to identify what brand and type of chip we are dealing with in order to find the datasheet. Usually the writing on the chip is everything we need as it states the manufacturer and model number. The motherboard manual mentions a “MXIC 25L8005” and if we look at the board we see that the model is indeed a 25L8005 made by Macronix.

MX25L8005

Typing the model number into google returns the datasheet as one of the first results. The information we are looking for is the pinout and operating voltage. The following image shows the pinout of the 25L8005:

The pin names do not make much sense if you are seeing them for the first time so the datasheet also include a description of the pin names:

For more information on what exactly the pins do please refer to the datasheet.

Preparing the Arduino

For the Arduino to be able to act as a serial programmer we need to first prepare it using frser-duino. The following command(s) will download and install the required packages, install flashrom, clone frser-duino and flash the Arduino.

sudo apt install git flashrom gcc-avr binutils-avr avr-libc avrdude && git clone --recursive https://github.com/tomvanveen/frser-duino.git && cd frser-duino && make ftdi && sudo make flash-ftdi

Connecting the Arduino to the SPI chip

The following image is an example schematic taken from the flashrom GitHub and shows the pins on the Arduino and the pins on the chip they should connect to (please note that PB0 does not have to be connected):

Emergency edit here: I know understand why people use resistors between the Arduino pins and the chip. The Arduino operates on 5V meaning its logic levels are also at 5V. This need to be brought down to 3.3v using a level shifter.

Flashing the SPI chip

To verify that everything is working correctly we first run flashrom without any operations:

sudo flashrom -p serprog:dev=/dev/ttyUSB0:2000000

The output should look like this:

flashrom v0.9.9-91-g0bfa819 on Linux 4.10.0-28-generic (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
serprog: Programmer name is "frser-duino"
Found Macronix flash chip "MX25L8005" (1024 kB, SPI) on serprog.
No operations were specified.

If the previous command worked as expected we are now ready for our final step. To write the new BIOS to the chip we use the following command:

sudo flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -w [NEWBIOS]

The output should look like this:

flashrom v0.9.9-91-g0bfa819 on Linux 4.10.0-28-generic (x86_64) flashrom is free software, get the source code at https://flashrom.org Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns). serprog: Programmer name is "frser-duino" Found Macronix flash chip "MX25L8005" (1024 kB, SPI) on serprog. Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED. 

And that is it. We have successfully flashed a chip using the SPI interface. If you have any questions or feedback about this post please leave a comment below!

References