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

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:

69 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..

  12. in case anyone has problem with unknown flash error
    add parametter “,spispeed=512” or “,spispeed=30000”
    like so:
    detect flash
    flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=512

    make backup
    flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=512 slowbackup.rom

    write flash
    flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=512 -w newbios.rom

    read and check
    flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=30000 -r newbackup.rom

    diff slowbackup.rom newbackup.rom

  13. Thank you for this guide it has really helped me with the proposed flashing of libreboot to to the SPI (Winbond W25X64) chip of my Lenovo T400 laptop.
    In the guide it says (RPi pin 23)to be connected to the (SPI flash pin SCK).My data sheet for the (Winbond W25X64) doesn’t list a SCK pin but it does list a CLK (serial clock input) pin.
    Would that be the same?

  14. Hi
    I got the latest full raspbian from raspberry pi main site.Installed flashrom from the add remove programs bit then enabled spi from config window, rebooted then opened a terminal and
    I used
    sudo su
    then I used
    flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=512
    but that did not find the chip so without changing the setup I used
    flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=512
    and it promptly found it .
    The only difference was spidev0.1 was changed to spidev0.0
    This might help anyone who uses the newest raspbian gui version on the pi

  15. Hi, I tried with the latest raspbian (debian 9.4 stretch) but flashrom does not find the chip (winbond w25x32). I also tried to compile flashrom from github and changed the device (both /dev/spidev0.0 and 0.1) but without luck. Any ideas ?
    maybe I have to downgrade to jessie ?

  16. Hi, I have sent a reply some days ago but maybe it’s not arrived.
    Anyway, I have installed jessie and built flashrom from source. But I haven’t solved the problem. Now I come back to stretch and the following is the output of flashrom (pkg):

    # flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=500
    flashrom v0.9.9-r1954 on Linux 4.14.70-v7+ (armv7l)
    flashrom is free software, get the source code at https://flashrom.org

    Calibrating delay loop… OK.
    No EEPROM/flash device found.
    Note: flashrom can never write if the flash chip isn’t found automatically.

    I have also tried the following command with the same output:
    # flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=500
    # flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=1000
    # flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=2000
    # flashrom -p linux_spi:dev=/dev/spidev0.1,spispeed=3000
    and:
    # flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=500
    # flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000
    # flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=2000
    # flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=3000
    and:
    # lsmod|grep -i spi
    spidev 16384 0
    spi_bcm2835 16384 0

    I have also changed the raspberry itself, I mean I have inserted the fresh installed raspbian sd on an other raspberry, but nothing was changed.
    Also I have an anomaly.. when I reboot I have a kernel crash, I don’t have the log but the problem seems to concern the bcm2835 driver. About this I am a bit confused because I don’t know if it is the wifi driver or the spi driver. In the log there was printed exactly bcm2835 but an lsmod|grep bcm give me only spi_bcm2835 and btbcm..

    Anyway now I try to built flashrom from source.

      1. Yeah, the wires are ok, I have changed it with others. But I have a doubt, the wire on rp 17 pin is connected to three wires that on my chip are connected to the 3,7 and 8 pins (/WP /HOLD and VCC). Is it correct ?
        This is the shot from the winbond w25x32 datasheet pdf: http://imgur.com/doCogqhl.png

          1. Hi Tom, sure I take the picture, but before two things:
            1) a guy on #flashrom@freenode says to check the wires length that shouldn’t be more than 10 cm. Then I have cut the wire(s) connected to the pin 17 because it was 20 cm (the first wire)+20 cm (the other three wires). Then from the pin 17 to the chip it was about 40 cm of wire.
            2) After cut the wire from 40cm to 22 cm I have powered on the raspberry again but it seems doesn’t want to power on.. the pin 17 wires are a bit warm.. then an other guy on freenode has said me to desolder the chip… ?!?!?!

          2. Hi Frank,

            I think you should take a step back and rethink your approach before continuing. I can confirm that wire length is an issue as longer wires pick up noise which will interfere with programming. I would not recommend desoldering chips just yet. Let’s start with a picture of how you connected everything and maybe some more info on the machine you are trying to fix?

            Kind regards, Tom

    1. Thanks for the pictures. However, would it be possible to make a picture showing how the raspberry pi and the winbond chip are connected (preferably in one picture)? I can’t make out from the current pictures if the wires go to the correct pins on the chip. Do you have the datasheet for the Winbond chip?

      1. The datasheet should be this:
        http://support.spectrumdigital.com/boards/dskda830/revf/files/102801-0001R-SPIFlash.pdf
        I don’t understand very well your first question. I mean, to see how they are connected u have to follow the colored wire. For example:
        The pin17 on rpi (yellow wire) is connected to 3 wire (two orange and one red). Those 3 wires are connected to the pins 3, 7, 8 on the winbond chip.
        The pin19 on rpi (blue wire) is connected to the pin 5 on the winbond chip.
        and so on..
        Then:
        rpi pin17(yellow)–>Clip pin3 (orange,/WP),pin7(orange,/HOLD),pin8(red,VCC)
        rpi pin19(blue)–>Clip pin5 (DI0)
        rpi pin21(grey)–>Clip pin2 (D0)
        rpi pin23(purple)–>Clip pin6 (CLK)
        rpi pin25(black)–>Clip pin4 (GROUND)
        rpi pin24(white)–>Clip pin1 (/CS)
        Then I connect the clip pin 1 aligned with the pin 1 on the flash chip.

  17. I don’t know if my previous message was arrived. Anyway the pc is an old desktop “HP Compaq 8000 Elite Small Form Factor”. Chipset “Intel Q45 Express”. If u want I can take a pic of the winbond chip.
    Thank you.
    PS Can I ask you your email? I want ask you something in private.

  18. Hi, in my case I have a 25Q32 and want to copy its code to a 25Q128 (old answering machine) to quadruple its available memory. Has anyone ever done this?

    Extra bonus points: has anyone ever recovered a chip which seems to have flipped bits. I suspect its just old age but if I can identify which ones don’t correspond to the stock image it may be repairable.

    -Andre

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.