Flashing a BIOS chip with a Raspberry Pi

I made this post as a addition or supplement to my “Flashing a BIOS chip with an Arduino” post.

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

I’ve tried different versions of Raspbian but Jessie lite seems to works best for me. It is available for download here: https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-07-05/

Install the packages needed by flashrom by using the following command:

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

Build and install flashrom using the commands below:

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

Before continuing we need to enable the SPI interfaces on the Raspberry Pi. This can be done either by editing the config file found at /boot/config.txt and uncommenting the line that says #dtparam=spi=on or by using raspi-config. Run raspi-config, and under interfaces enable SPI.

After rebooting the SPI interfaces are available under /dev/spidev0.0 and /dev/spidev0.1.

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

In order to verify flashrom is working correctly and the chip is detected properly we run flashrom without any operation. Example output can be found below:

pi@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.1
flashrom v0.9.9-91-g0bfa819 on Linux 4.9.35-v7+ (arm7l)
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 we have verified everything is in order we can start writing the BIOS to the chip:

pi@raspberrypi:~ $ flashrom -p linux_spi:dev=/dev/spidev0.1 -w YOURBIOS
flashrom v0.9.9-91-g0bfa819 on Linux 4.9.35-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... Erase/write done.
Verifying flash... VERIFIED.

And that is that.

Resources:

50 thoughts on “Flashing a BIOS chip with a Raspberry Pi”

  1. Thank you for this post. I was able to fix my Asrock x79 Extreme4-m with this technique.

  2. Hello. I am getting this error when installing flashrom on raspberry pi 3,

    internal.c:148:32: error: ‘par_master_internal’ defined but not used [-Werror=unused-const-variable=]
    static const struct par_master par_master_internal = {
    ^~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    Makefile:1043: recipe for target ‘internal.o’ failed
    make: *** [internal.o] Error 1

    occurs after (sudo make)

    Your help is much appreciated

      1. Hi,

        I am using jessie lite too. same error on latest version 2 previous versions.

        But I managed to install it with apt-get install flashrom, and its working now,

        Thank you very much

        Amr

          1. Trying to revive a bricked GPU CARD..( MSI RX580 GAMING X) The bios chip is ( winbong w25x40cling)
            still no luck reading it with permona soic 8 test clip..
            will keep you updated

            Many thanks

    1. edit the Makefile before you run make

      and change the CFLAGS line

      CFLAGS ?= -Os -Wshadow -Wno-unused-parameter

        1. You are welcome! I’m glad people are helping each other out in the comments.

          It seems there are some issues when using the Flashrom version from github.

          Would be interesting to see if these problems are solved when installing Flashrom using apt-get.

          I will test this and update the post when I have the result.

        2. Hi Kjetil,

          I’ve tried both versions of Flashrom (from github and the standard debian repo) but neither seemed to work for me when using Raspbian Stretch. Flashrom was not able to recognize the SPI flash chip. Next I reverted to Raspbian Jessie lite and compiled Flashrom from github. Now Flashrom did identify the SPI flash chip and I could read en write to it. Did Flashrom work for you on Stretch?

          Kind regards,

          Tom

          1. Hey Tom,
            So that explains my issues with recognizing the flash, didn’t have much time when I compiled it, and after a few attempts I put it aside.
            I can confirm that reverting to Stretch and compiling from git it not detects the flash on first try.. Shows me right for trying to squeeze in some fun before leaving for work.
            Thanks again for the follow up, you saved me hours of cursing and debugging I’m sure!

          2. Hi Kjetil,

            Thank you for confirming my suspicion about Stretch. I’ve updated my post and included a link to the specific Raspbian Jessie image I used. Let me know if this image works for you.

  3. Hi Tom, first off, thanks for the awesome tut, it’s brought me closer to rescuing my motherboard than anything else so far.

    I am having a similar issue to Kjetil though in that Flashrom (both apt-get version and the freshly compiled repo source) fail to identify the chip:

    “pi@raspberrypi:~/bios $ sudo flashrom -p linux_spi:dev=/dev/spidev0.0 -w E7760IMS.C80
    flashrom v0.9.9-91-g0bfa819-dirty on Linux 4.9.59-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 Generic flash chip “unknown SPI chip (RDID)” (0 kB, SPI) on linux_spi.
    ===
    This flash part has status NOT WORKING for operations: PROBE READ ERASE WRITE
    The test status of this chip may have been updated in the latest development
    version of flashrom. If you are running the latest development version,
    please email a report to flashrom@flashrom.org if any of the above operations
    work correctly for you with this flash chip. Please include the flashrom log
    file for all operations you tested (see the man page for details), and mention
    which mainboard or programmer you tested in the subject line.
    Thanks for your help!
    Error: Image size (8388608 B) doesn’t match the flash chip’s size (0 B)!”

    I’ve double checked that the chip is supported (it’s the MSI motherboard MS-7760), I’ve double and triple checked the wiring to the JSPI1 header (9-pin variant) and I’ve tried pulling the hold pin high, low and even leaving it disconnected…
    So far, no dice though.

    Have you encountered this kind of issue before or do you have any ideas as to how I might be able to either solve or refine the problem further?

    1. Hi Minothor!

      Did you use the jessie image I linked to in the post?

      Flashrom is refusing the see the SPI chip when using Raspbian Strech.

      Using Raspbian Jessie fixed the issue.

      Kind regards,

      Tom

          1. Am doing so! Thank you so much! Seeing it load the Bios after 3 weeks was just pure joy!
            I’m going to reflash the B chip now so I have an on-board backup!

  4. Hello,
    Thanks for your work.
    I’ll try to revive an old laptop bricked ages ago.
    I was wondering if I can solder small wire on the chip to avoid to desoldering the winbond 25q128fv..

    Regards

      1. Thanks for the hint !!

        Aliexpress or ebay is fine.. 1.5€ is OK, and it might save lots of work.
        Neverthless I’ll have to tear down the laptop as there’s very little space near the chip.

        I’ll keep you informed.

          1. Just ordered the clip+ribbon+breakboard adapter plate…
            Now patience begin…

            Another thing… I extract the exe from the bios upgrade file.. and theris x2 .bin file.. 8mB each.. wondering which is the good one…

  5. I love your tutorial! I just have a quick question before proceeding ( it’s my first rodeo):

    For pin #17 it says the following “VCC 3.3V and /HOLD and /WP” – does that mean that I either:

    1. Connect ONLY the VCC BIOS pin to RPI pin #17, while leaving the other BIOS pins (HOLD, WP) disconnected altogether?

    2. Or, do I simply connect all 3 BIOS pins (VCC, HOLD, WP) to the same RPI pin #17??

    Thank you very much!!

      1. Okay sounds good!! I was thinking option #2 would be correct but didn’t want to chance it and fry the chip or PI itself, as would be my luck.

        Thanks again.

  6. Waiting for the SOIC8 clip to arrive I prepare my jessie sdcard.

    I downloaded the jessie version you mention to avoid compatibility problems.

    I follow your instructions but I have a problem with “make && make install”.

    make report a problem : fatal ambiguous argument ‘hooks/’ : unkown revision or path not in the working tree

    Of course the commands ends with :
    make: *** [install] error 1…

    I removed flasrom directory and redownloaded (re-git clone it) it.. same problem..

    Any idea please.

      1. After installing Jessie (full version),

        “pi@raspberrypi:~/flashrom $ cat /etc/os-release
        PRETTY_NAME=”Raspbian GNU/Linux 8 (jessie)”

        I copy/paste your suggested command

        pi@raspberrypi:~ $ git clone https://github.com/flashrom/flashrom.git
        Cloning into ‘flashrom’…
        remote: Counting objects: 9886, done.
        remote: Compressing objects: 100% (87/87), done.
        remote: Total 9886 (delta 86), reused 111 (delta 69), pack-reused 9730
        Receiving objects: 100% (9886/9886), 3.04 MiB | 42.00 KiB/s, done.
        Resolving deltas: 100% (7517/7517), done.
        Checking connectivity… done.

        Seems OK…

        Then make && make install…

        and aleas :

        “fatal: ambiguous argument ‘hooks/’: unknown revision or path not in the working tree.
        Use ‘–‘ to separate paths from revisions, like this:
        ‘git […] — […]’
        Checking for a C compiler… found.
        Target arch is arm
        Target OS is Linux
        Checking for FTDI support… not found.
        Checking if Linux SPI headers are present… yes.
        Checking for utsname support… found.
        Checking for clock_gettime support… found.
        mkdir -p /usr/local/sbin
        mkdir -p /usr/local/share/man/man8
        mkdir: cannot create directory ‘/usr/local/share/man/man8’: Permission denied
        Makefile:1382: recipe for target ‘install’ failed
        make: *** [install] Error 1”

        Thanks for your help….

  7. Hello worked late on it..
    I tried stretch with gui and succeded to install flashrom.
    I installed the utilities and set to on the spi in raspberry parameters.

    To do so I downloaded the 1.0 version from flashrom unziped it cd flashrom make make install and no error message.

    I launched a flashrom -r and no message… as I have no attached soic8 it seems logical… Just wondering why it doesn’t detect that tjere’s nothing connected….

    1. Did you keep the ” -p linux_spi:dev=/dev/spidev0.0″ between flash roman and the -r?

      That tells flashrom what hardware to use for reading/writing.
      (in this case, the pi’s pins)

    2. Hi, as mentioned before Strech will not work. Even if you are able to compile and install flashrom, flashrom will not recognize your chip. It’s best to stick to the Jesie version I linked to. If flashrom fails to compile try installing it trough apt-get. I believe both versions should work.

  8. I worked on it again… using

    sudo make
    Replacing all version templates with 0.9.9-117-g305a2b3.
    fatal: ambiguous argument ‘hooks/’: unknown revision or path not in the working tree.
    Use ‘–‘ to separate paths from revisions, like this:
    ‘git […] — […]’
    Checking for a C compiler… found.
    Target arch is arm
    Target OS is Linux
    Checking for libpci headers… found.
    Checking version of pci_get_dev… new version (including PCI domain parameter).
    Checking if libpci is present and sufficient… yes.
    Checking for libusb-0.1/libusb-compat headers… found.
    Checking if libusb-0.1 is usable… yes.
    Checking for libusb-1.0 headers… found.
    Checking if libusb-1.0 is usable… yes.
    Checking for FTDI support… not found.
    Checking if Linux SPI headers are present… yes.
    Checking for utsname support… found.
    Checking for clock_gettime support… found.

    then

    sudo make install
    Replacing all version templates with 0.9.9-117-g305a2b3.
    fatal: ambiguous argument ‘hooks/’: unknown revision or path not in the working tree.
    Use ‘–‘ to separate paths from revisions, like this:
    ‘git […] — […]’
    Checking for a C compiler… found.
    Target arch is arm
    Target OS is Linux
    Checking for FTDI support… not found.
    Checking if Linux SPI headers are present… yes.
    Checking for utsname support… found.
    Checking for clock_gettime support… found.
    mkdir -p /usr/local/sbin
    mkdir -p /usr/local/share/man/man8
    install -m 0755 flashrom /usr/local/sbin
    install -m 0644 flashrom.8 /usr/local/share/man/man8

    Eventhough “fatal: ambiguous argument ‘hooks/’: unknown revision or path not in the working tree.” it seems OK :

    flashrom
    flashrom 0.9.9-117-g305a2b3 on Linux 4.9.35-v7+ (armv7l)
    flashrom is free software, get the source code at https://flashrom.org

    Please select a programmer with the –programmer parameter.
    Previously this was not necessary because there was a default set.
    Valid choices are:
    dummy, gfxnvidia, drkaiser, satasii, atavia, it8212, serprog, buspirate_spi,
    dediprog, pony_spi, nicintel, nicintel_spi, nicintel_eeprom, ogp_spi, linux_spi,
    pickit2_spi, ch341a_spi.

    Then :

    flashrom -p linux_spi:dev=/dev/spidev0.1
    flashrom 0.9.9-117-g305a2b3 on Linux 4.9.35-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).
    No EEPROM/flash device found.
    Note: flashrom can never write if the flash chip isn’t found automatically.

    flashrom -p linux_spi:dev=/dev/spidev0.1 -r YOURBIOS
    flashrom 0.9.9-117-g305a2b3 on Linux 4.9.35-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).
    No EEPROM/flash device found.
    Note: flashrom can never write if the flash chip isn’t found automatically.

    As I ain’t got the SOIC8 clip… it’s normal…. I guess

    1. I was able to reproduce the error you got: “fatal: ambiguous argument ‘hooks/’: unknown revision or path not in the working tree.”. I’m guessing this is due to a recent update in the flashrom github. You could fall back to an older version or install via apt-get. But as you stated earlier although the error occurs, flashrom will still finish. And yes sudo is required to make install, sorry for that.

  9. For user using Stretch, reducing speed (spispeed) should work :

    sudo flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512

  10. Hello,

    I succeeded in wiring the bios directly on the motherboard, thanks to your tutorial !!!

    My problem was that SOIC8 clip cablewiring is somewhat illogical to me. Happily for me my multimeter solved the problem.

    I first red the bios to save it in a file just in case.
    Then I erased the chip to avoid any problem, and to check if chip is OK…

    Then I tried to restore the bios I downloaded BUT ,(did you noticed that problem always occurs with “But”), the file is only 8MB… and the chip is 16MB…

    –> flashrom forbid me to write the 8MB file….

    What is strange is that the bios file (a self exe) containt x2 8MB files :
    L77_0142.bin
    L78_0142.bin

    Both .bin contain data…

    But when I create a bootable USB Bios update key, it only contains : L78_0142.bin which is 8MB

    Any idea is very welcome…

  11. Hi
    I have bricked MSI B250M Mortar MB with winbond “25q128fvsq”
    Is it possible to flash it with raspberry PI Zero WH ? (Pi Zero is a little bit cheaper)

    1. As pi zero w handle spi too there is no reason for it not to work.
      Double check gpio pin bit it should work as per rpi 2 3..

Leave a Reply

Your email address will not be published.