HOWTO: Fixing a broken EDID EEPROM with a Bus Pirate v4

This post is about fixing a broken EDID ROM in a monitor. There are several ways to do this. Typically this involves writing the EEPROM with the Windows only tool PowerStrip (see here for a HOWTO) . Here I want to present an alternative solution using the Dangerous Prototypes Bus Pirate – a device which every hardware hacker with self-respect should have anyway. You should already be tech-savvy to attempt this procedure.

Introduction

So I own 3 Samsung Syncmaster 2343BW with a staggering 2048×1152 pixels of resolution on 23″. When I bought them 3 years ago – this was really amazing. (Nowadays, such monitors are not even for sale anymore… but there is the ipad… Hopefully Apple sets a trend here for higher resolution…

So one of these monitors often suffers from a broken EDID EEPROM. Since this ROM is used to store all important information for Plug&Pray, the monitor not being detected anymore at all. I had this happen to me 3 times during warranty and they always exchanged the whole motherboard. But unfortunately continues to appear after warranty, so I set out to fix it myself.

Ok, so the first 16 bytes have just been erased – beautiful! So presumably, if I fix these bytes my monitor will start working again.

Getting a correct EDID file

This chapter is about extracting a correct EDID file from the broken one. If you already have a correct EDID ROM (i.e. from a second monitor you own) and you want to flash it – just skip it.

Extracting the corrupted EDID ROM as binary

So first we have to get the broken EDID file. This is simple, since all the EEPROMs Linux finds are exposed to use under /sys/bus/i2c/devices/$bus-00$addr/eeprom. If you cannot find these devices your kernel is either too old or you do not have the eeprom module loaded. Depending on your computer there might be several eeproms, so let’s find the correct one with a bash one-liner:

So let’s try edit broken_edid.bin and insert the missing header (so the first line in the hex dump). You can easily to this with any Hex-Editor, if you don’t know one I can recommend Okteta. Once you think you have fixed your EDID file, save it as fixed_edid.bin. You can check if you new file is valid with the edid-decode program (also in the Debian/Ubuntu repositories).

Great! So no errors here! Now we go on flashing the EEPROM. Note that depending on what bits you changed you might have to also correct the check sum. This happens for example if you alter the serial number. But don’t worry, you will be warned by edid-decode and it calculates the correct check sum by itself. (Thanks Kaz for pointing that out.)

Flashing a new EDID in the EEPROM

Now that we have a correct EDID ROM we need to flash it. All modern monitors use a I2C bus which is exposed over its display connector. I won’t go into the details, this is just about what you need to do to read an write on the EEPROM.

Connecting the Bus Pirate to the monitor

If you have an old analog monitor connecting to the I2C bus is easy. You can just use 1-pin dual-female jumper wire (i.e. from Seed Studio) and connect the pins of the male Sub-D connector cable with the pins on the monitor. I ran into problems connecting to DVI though since these connectors have not the right pin size. So the easiest way is just to get a cheap passiv VGA to DVI adapter. Don’t worry about digital versus analog video signals – it does not matter since we are only interested in the I2C bus which is identical. If you have a HDMI monitor, I could imagine you can cascade a VGA-DVI and a DVI-HDMI connector. I have not tried that though.

Talking to the EEPROM

Initialize the Bus Pirate

Now it’s time to talk to the EEPROM. Your monitor does not need to be switched on since it is supplied with 5V directly from the Bus Pirate. Use your preferred terminal program to connect to the Pirate. I personally like picocom.

Reading and writing to the EEPROM

Now, if you have never used I2C to talk to EEPROMs this might feel a bit awkward but just bear with me. There are two I2C address, one for reading (0xa1) and one for writing (0xa0) commands to.

Reading

So if you want to read from the EEPROM, you first have to write your address you want to start. The address counter of the EEPROM is internally increased for each bit you read. So let’s first try to set our start address to zero, the beginning of the EDID block.

Notice how we use the read address 0xa1 and ask the Bus Pirate to read 8 bytes in a row. Also note that we get the same result we also saw in the Linux kernel error message. Of course you could also start reading somewhere else in the ROM by just changing the start address.

Writing

Now it’s time we write to the EEPROM. Notice that some monitors protect the EEPROM against writes – you might have to google on how to get into the service menu to deactivate the write protection. In my case, I could just write to it (which is probably why it gets corrupted in the first place…).

So remember that there there was the writing address0xa0 and we used it to write the address counter to the place we wanted to start reading. Now, instead of reading we just continue to write:

Notice how this commands writes 8 bytes, starting at the addresses 0 and 8. Naturally, you could also just write only one byte if you want. In my case, this fixes the whole 16 bytes of the broken EDID header.

Conclusion

Now that the EDID is fixed you should be able to connect your monitor again and everything should work as before. Congratulations!

Post navigation

This is a great idea, but I’m not sure you’ve actually fixed your EDID at this point. I suspect if you only wrote bytes 0-15 of the other monitor’s EDID, you’ve borked the checksum, because some of those bytes are a serial # (going on to bytes 16-17). So you probably need to write 16-17 from the other monitor, and swipe its checksum also and write it into byte 127. (And of course, verify that no other data is different.) Alternatively, calculate the new checksum, which is pretty simple: sum up all bytes of the EDID except for the checksum byte, take the remainder from 256 and subtract from 256, and that’s your checksum byte — it should add up such that the sum of each 128 byte block is evenly divisible by 256.

You are totally correct. I did this write up after I fixed the monitor. As I wrote I have several monitors and each monitor also has VGA. The VGA EDID of the broken monitor was still OK. Using that EDID you’ll naturally use the old serial number – and the check sum is fine. Unfortunately, I wrote the article after I had fixed the monitor and mixed it up a bit. I’ll fix the article accordingly.

Btw: You won’t have to calculate the checksum yourself, edid-decode also warns you and gives the correct checksum.

Ah, that’s handy then. I’ve just seen cases where the PC detects a valid EDID header (the 00 FF FF FF FF FF FF 00) and then when the checksum is bad, it tries again… and again… and never gives up and causes issues.

Awesome writeup! I just fixed the checksum on my ViewSonic VX2025wm monitor. Linux kept choking on it because of the checksum so I calculated it and it was different than what was programmed. After replacing just that one byte, my monitor works like a champ! Many thanks for writing this up.

YUP, I used my BP v3 and just modified the commands a bit to match. I have now had to do this to both of my monitors (same model) to fix this problem. I have even gone ahead and made a cable that has the 10pin header on one end and a VGA connector on the other, so all I have to do next time is plug it in rather than trying to pin it out. I am sure it will come in handy again some time…

Hi Tamagotono,
I used your site as reference to fix edid of my fujitsu siemens monitor.. it had single byte in name set to ff breaking checksum.. and I couldn’t use dvi connector on linux/windows without some configuration changes.
I user Rasberry Pi instead buspirate