Close
0%
0%

Hacking a Supervisor Password - With a Beagle Bone

I found myself being intrigued with the low level safety features of my X201. I experimented with the I2C bus and it got interesting...

Public Chat
Similar projects worth following
******************************************************************************************************************************

DISCLAIMER: This project was done for learning purposes ONLY. It's a study of the security features on my personal laptop - coincidentally developed and sold by Lenovo. Almost all information about this mechanism is PUBLICALLY AVAILABLE in various public forums and presents nothing new. I simply connected the dots in an attempt to bring everything into one easy to use, simple software package to learn Python on Beaglebone with a specific, motivating goal that feel like a real win when accomplished.

******************************************************************************************************************************

I got a bunch of Beaglebone Black sitting around since my friend cleared out his garage. In my eyes, these are rather outdated compared to the vast fellowship the Raspberry Pi has - me too included.

But having these and not doing anything with them was an itch I constantly felt, so eventually I decided to do a bit of a learning project that was set to accomplish three goals:

  1. Learn Python - this was long overdue!
  2. Learn how to work with the Beaglebone Black / White / Pocket
  3. Identify an elegant way to "recover" the supervisor password in my own (not bios locked) Lenovo Thinkpad X201 Tablet

Using a non-locked laptop was mandatory for this idea because the password, if set, is/can be encrypted. Can't enter an encrypted password into the password prompt, can I? Therefore I needed to develop the encryption table by hand - but I'm getting ahead of myself.

The rest of the documentation can be found in the various log-entries of this project.

  • Progress bars, verify, and other menu items

    Timo Birnschein03/22/2021 at 00:35 0 comments

    Today, I spent some time making major changes to the code. I really wanted more control over what's happening when when, I also wanted to make it a bit more versatile and also safe.

    I added

    • Wizard guided flow
    • the ability to restore the eeprom from an existing binary file
    • an option to verify what has been written to the eeprom
    • fixed a bug with passwords shorter than seven characters
    • added the ability to select the i2c bus on the beaglebone black
    • added option to remove the password completely or chance to a new one
    • added status bars for the read, write, and verify operations

    The entire workflow of one session can be seen here:

    EEPROM Tool - Crack your favorite laptop - hopefully without breaking it...
    Author: Copyright 2021 - Timo Birnschein
    
    
    Please select task: restore EEPROM from file: type <restore>, or read, modify and write system EEPROM: type <modify> (default is <modify>)
    
    What i2c bus / SMBus would you like to use? Default is <2>:
    
    Selecting I2C bus 2
    
    Press Enter to read EEPROM contents...
    Reading from EEPROM...
    Reading EEPROM: |██████████████████████████████████████████████████| 100.0% Complete
    Writing binary to file...  eeprom.bin
    Extracting and translating password: hallo
    Checksum of password as read from eeprom:  0xa5
    Confirmation passcode (should be the same): hallo
    Checksum of re-entered password as read from eeprom:  0xa5
    Calculating own checksum: 0xa5
    
    The above password might not be correct as your system might use a different encryption scheme!
    If the password does not work, writing a new password also won't work! Only removing it altogether will work.
    
    Choices are: remove existing password from EEPROM or write a new password to the EEPROM
    Type <remove> or <new> without brackets and hit enter. If you just hit enter, the program will exit.
    remove
    Writing and encoding new password:
    Checksum added to eeprom:  0x0
    Writing confirmation password (must be the same):
    Adding checksum to confirmation password:  0x0
    Writing binary to file...  eeprom_mod.bin
    
    
    Do you really want to write to the EEPROM of your computer?
    ************** THIS MIGHT BRICK YOUR LAPTOP!!! **************
    Type:  and hit enter (case sensitive, no brackets!)...
    Yes I want to
    Writing binary file back into EEPROM, length: 256
    Writing EEPROM: |██████████████████████████████████████████████████| 100.0% Complete
    Reading EEPROM back for verification...
    Reading EEPROM: |██████████████████████████████████████████████████| 100.0% Complete
    Writing binary to file...  eeprom_verify.bin
    Verifing EEPROM: |██████████████████████████████████████████████████| 100.0% Complete
    Verification completed. EEPROM seems good. No guarantees!
    
    Done. Bye.
    

    I tested this using my 256 byte 24C02 instead of flashing my laptop a hundred times. This also led to me changing the address the script accesses to only 0x57 which is where the supervisor password is located. Eventually, I would like to blow this up even more by reading and writing the entire 24RF08 again but for only the supervisor password that's not required.

    I still don't know where all the other passwords and features are. Unfortunately, there is no nicely documented summary available - at least not as far as I know. If someone has one, please let me know. We could make this into a fully configurable toolkit if we wanted to. Similar to the Lenovo service diskette that allows setting serial numbers and owners and the like.

    Btw: Code is here now: https://github.com/McNugget6750/x201Password

    Maybe at some point I might look into this menu system a bit more: https://www.daniweb.com/programming/software-development/code/309413/console-application-menu-module

  • Demo Time!

    Timo Birnschein03/20/2021 at 01:16 0 comments

    To show off how all the pieces work together, let's do a demo on my X201.

    Please keep in mind that I do not know if the encoding that is used on my laptop will be the same on any other laptop. So my naive approach to reading and decoding the password might work nowhere else!

    However, what always works is deleting the password altogether because it doesn't even require any special knowledge of the checksum as it's simply 0x00.

    In the end, there are only two risks involved in this process and I want to make sure these are understood:

    1. Soldering any wires to your laptop might break it because the solder points are very small, there might be shorts, taking apart a complex device isn't easy or straight forward. Simply put: You can brick your laptop by just opening it up the wrong way and making electrical changes to the system might have side effects we cannot foresee.
    2. Even reading from the EEPROM can cause a hazard. This is due to the fact that the system accesses the I2C bus every four seconds even when the system is doing absolutely nothing. Without an oscilloscope or a similar device one has no idea when the bus is being accessed. Accessing the bus with another I2C master at the same time will cause data corruption. Something that I did which, in fact, messed up the RFID area in my X201.
      But then worst, writing to the EEPROM can definitely brick your device because we have no idea if we're able to write everything back into the EEPROM correctly (yet). And if we don't, the system wakes up broken. This is even worst when one writes to the EEPROM while the host system also intends to access the bus. Data corruption guaranteed!

    Having said all of the above, one way to get at least around the bus access every four seconds is to turn the laptop off completely and have it connected to a power supply. For some reason, the Thinkpad's mainboard power is on (anyone have any thoughts on the Intel Management Engine? - leave a comment down below) but no one is accessing the I2C bus at that time! Great news for me, as I can freely read and write the EEPROM.

    On my laptop, since I knew I wanted to fiddle around with this further, I broke out my I2C bus into the PCMCIA slot via a simple three pin connector. So I can just plug it in and do whatever I want on the bus. If I hadn't done that, I would not be experimenting with it now.

    My setup is simple: I use the Beagle Bone Black (even after many days of research still a terribly documented system and I don't understand why anyone would still use this in time of Raspberry Pi galore - yes, I'm aware of the PRU, I haven't looked into programming those in detail, yet) and connect it straight to my laptop's I2C bus.

    Then I fire up the cloud9 IDE and execute my Python project which accesses the bus and attempts to read from it. Since I know the bus is being accessed every four seconds, I have an oscilloscope set up to watch the signal lines. Once an access cycle is over, starting the four second gap, I hit enter to signal the BBB to start the process and read the bios EEPROM. Once read, it will spit out the currently set supervisor password in clear text, create a separate image with a modified, known password, confirm that it calculated everything correctly and then wait for another user input to start writing the new image file back to the EEPROM.

    I really didn't want to write junk to the EEPROM so I force the user (me) to type a security sentence to start the writing process. Watching the oscilloscope closely, waiting for the four second gap again, I hit enter once the gap is there. Within milliseconds, the new image is written to the bios EEPROM (only one of the four sections of the EEPROM) and the new password can be entered immediately to unlock the laptop.

    Obviously, the EEPROM write step isn't mandatory to unlock the laptop because the script already exposed the originally set super visor password. So once we have that, we can just enter it to unlock the bios. But if the password...

    Read more »

  • Different I2C devices with different power states

    Timo Birnschein02/21/2021 at 22:03 0 comments

    Laptop powered off with power supply plugged in after complete power off with battery out and power supply disconnect:

    debian@beaglebone:/var/lib/cloud9$ i2cdetect -r -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- 54 55 56 57 -- -- -- -- 5c -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --

     Laptop powered on, waiting before bios with power supply plugged in:

    debian@beaglebone:/var/lib/cloud9$ i2cdetect -r -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- 08 -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: 30 31 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- --
    50: 50 51 -- -- 54 55 56 57 -- -- -- -- 5c -- -- --
    60: -- 61 -- -- -- -- -- -- -- 69 -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --

    Powered up and booted to Ubuntu

    debian@beaglebone:/var/lib/cloud9$ i2cdetect -r -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- 08 -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: 30 31 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- --
    50: 50 51 -- -- -- -- -- -- -- -- -- -- 5c -- -- --
    60: -- 61 -- -- -- -- -- -- -- 69 -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --

    As can be seen, the 24RF08 chip is now hidden and there, cannot be accessed from the system. I know that the Lenovo Maintenance Disk (yeah, a floppy disk) can write to it. That would mean that Ubuntu or the booting system removes access to the eeprom during boot.

    I wonder, though, 0x5C is still there! Maybe the access flags have changed after boot? They do auto-reset after power cycle. Let's take a look!

    Shutdown: 

    debian@beaglebone:/var/lib/cloud9$ i2cdump -y 2 0x5c
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: ae ae bf bf af af 8f 8f ff ff 7e ff ff ff ff 10    ????????..~....?
    10: 26 07 5b 6d d1 00 84 c2 55 60 20 1f ff ff ff 7f    &?[m?.??U` ?...?

    Sitting at Ubuntu login:

    debian@beaglebone:/var/lib/cloud9$ i2cdump -y 2 0x5c
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: ae ae 3f 3f 2f 2f 0c 8f 7f ff 7e ff ff ff ff 10    ????//???.~....?
    10: 26 07 5b 6d d1 00 84 c2 55 60 20 1f ff ff ff 7f    &?[m?.??U` ?...?

    Very interesting indeed! You see the two addresses that can be read from 0x5c. The second line at 0x10 is the ID field used for RFID asset tags and it seems unchanged. There is no reason to change it during boot.

    But 0x00 to 0x0F changed a lot! Let's look at the details.

    Decoded the above, I can't see why the addresses of 0x54, 0x55, 0x56, and 0x57 would not show in the i2c device scan but what can be seen is that SB6 == b0 and PB6 == b00. This definitely prevents anyone from writing to this section of the EEPROM - here is where the supervisor password is stored. SP6 == b0 prevents one from changing PB6 to something like b11.

    To explain this better: The EEPROM is divided into eight blocks of 128 bytes. Each device address contains two blocks. Hence, 0x57 has two blocks and SB6 signifies the first block of the two, where the supervisor password is stored. So looking at byte 6 in the first line, we see 0x0c == b0000 1100 -> Can't change the bits in PB and PB is set to no access at all.

    In addition, the SBx can only be written to '0' and not to '1' making it impossible to change their state via software after the booting OS or bios set them to '0'.

    But still, why can't I see those addresses on the bus anymore...? 

  • Lenovo Thinkpad Supervisor Password - Gotta have a goal if you want to learn something...

    Timo Birnschein02/21/2021 at 19:58 0 comments

    So far, I have only understood where some Lenovo Thinkpads store their passwords. They are located at 0x380 and 0x400. I interpret this as password and confirmation password. These are seven bytes plus one checksum byte. This is not a CRC. It's literally the 8-bit sum of the previous seven bytes. That's it.

    Unfortunately, they use an "encryption" method to hide the password and make it non-human readable.

    Brute Force

    The supervisor password uses some form of encoding. Calling it encryption might push it a little because - at least on my personal X201 Tablet - the encoding is always the same no matter when I set a password. Maybe it will be different on a different Thinkpad? I'll find out when my "new" W530 arrives in the mail.

    To figure out how the encoding works, I bruteforced my way through all possible characters the Thinkpad accepts for the supervisor password and checked how it is represented in the 24RF08. Thankfully, a complete power cycle wasn't required and the EEPROM was written each time I entered a new password in the Bios' security settings. It looks like this:

    With that in place, I was able to create a map in Python to automatically give me the decrypted password straight from the binary file I read from the EEPROM.

    # (Hopefully) Complete mapping between Lenovo encoded characters and the ASCII table
    # Technically, the characters aren't needed because chr(hexcode) will give you the same but this is more debuggable and human readable
    pwdMap = [[' ', 0x00, 0x00], ['0', 0x30, 0x0b], ['1', 0x31, 0x02], ['2', 0x32, 0x03], ['3', 0x33, 0x04], ['4', 0x34, 0x05], ['5', 0x35, 0x06], ['6', 0x36, 0x07], ['7', 0x37, 0x08], ['8', 0x38, 0x09], ['9', 0x39, 0x0a], [';', 0x3b, 0x27], ['a', 0x61, 0x1e], ['b', 0x62, 0x30], ['c', 0x63, 0x2e], ['d', 0x64, 0x20], ['e', 0x65, 0x12], ['f', 0x66, 0x21], ['g', 0x67, 0x22], ['h', 0x68, 0x23], ['i', 0x69, 0x17], ['j', 0x6a, 0x24], ['k', 0x6b, 0x25], ['l', 0x6c, 0x26], ['m', 0x6d, 0x32], ['n', 0x6e, 0x31], ['o', 0x6f, 0x18], ['p', 0x70, 0x19], ['q', 0x71, 0x10], ['r', 0x72, 0x13], ['s', 0x73, 0x1f], ['t', 0x74, 0x14], ['u', 0x75, 0x16], ['v', 0x76, 0x2f], ['w', 0x77, 0x11], ['x', 0x78, 0x2d], ['y', 0x79, 0x15], ['z', 0x7a, 0x2c]]
    
    # takes an input value and encodes it into Lenovo speak if encodeDecode == 0
    # and decodes it into ascii if encodeDecode == 1
    # Granted, this is extremely inefficient but I'm not in a hurry. You?
    def convert_value(input, encodeDecode = 0):
        if encodeDecode == 0:
            for r in pwdMap: # look at every entry in our map to check for a match
                if input == r[1]:
                    return r[2]
            print(hex(input), " not found while encoding.")
            return -1 # something went wrong, symbol not found in map
        elif encodeDecode == 1:
            for r in pwdMap: # look at every entry in our map to check for a match
                if input == r[2]:
                    return r[1]
            print(hex(input), " not found while decoding.")
            return -1 # something went wrong, symbol not found in map
        else:
            print("convert_value(input, encodeDecode = 0) needs either 0 or 1 as input for the encoding direction. You provided: ", encodeDecode)
            return -1 # something went wrong, function called incorrectly
    def read_pwd_from_binary(data):
        print("\nExtracting and translating password:", end = " ")
        for i in range(7):
            print(chr(convert_value(data[0x38 + i], 1)), end = "")
        print("\nChecksum of password as read from eeprom: ", hex(data[0x38 + 7]))
        
        print("Confirmation passcode (should be the same):", end = " ")
        for i in range(7):
            print(chr(convert_value(data[0x40 + i], 1)), end = "")
        print("\nChecksum of re-entered password as read from eeprom: ", hex(data[0x40 + 7]))
        
        print("Calculating own checksum:", end = " ")
        print(hex(calculate_checksum(data[0x38:(0x38 + 7)])))

    All of this should be self-explanatory due to all my comments and prints in the code.

    All I need to do to read the actual password from the last eeprom dump is this:

    eeprom.read_pwd_from_binary(eepromDump)

    It was never easier. No reading miles long forum entries or sniffing...

    Read more »

  • Python on Beaglebone

    Timo Birnschein02/14/2021 at 22:48 0 comments

    The only time I used Python in the past was an attempt to scrape data from web-shops websites to buy a graphics card when available check the weather. So my experience is extremely limited and I have to look up pretty much every single function or import or even if-statements when I wanted to use them for the first time. Python is great and powerful but if you are used to C++ it's a bit of a mystery.

    I must emphasize that Adafruit has deprecated their libraries and none of them function at this point. It appears, Adafruit has abandoned the Beaglebone support completely as this information isn't even available on their website. Only old and very promising looking tutorials that are simply a waste of time to read!

    For ease of use, I use cloud9 - Cloud9 as my Beaglebone (link only works if your Beaglebone has a fresh install and is connected to your PC via the Mini-USB cable). It looks like a full blown Python IDE and has all sorts of nice features like system shell, python shell, debugger and I'm sure a whole lotta other things I haven't used, yet. Even some basic type of code completion.

    After successful tests on the console reading and writing to my I2C EEPROM, I wanted to recreate some of these functions in python to automate things. SMBus is the library of choice.

    from smbus import SMBus
    bus = SMBus(2) # select I2C bus 2, default pins are SCL:19; SDA: 20

     First, I wanted to read from the eeprom, so I wrote myself a little function

    # Read consecutive bytes from the eeprom
    def read_from_eeprom_8(bus, address, size=256):
        binary = [0] * size
        
        for i in range(int(size)):
            # To ensure we can actually read all 256 bytes from the EEPROM,
            # some memories like the 24RF08 require setting multiple page addresses.
            # The 24RF08 is organized in 128 byte pages that must be accessed individually
            # or the page will simply loop.
            # The 24C02 isn't. But it doesn't hurt to do it regardless.
            if i % 0x80 == 0:
                # print("setting new page at ", i)
                bus.write_byte(address, i) # write the new page address to the address counter
                sleep(0.01) # wait a bit to let the new address settle
                
            result = bus.read_byte(address)
            binary[i] = result
        return binary

    The above function is extremely simple. When called, you have to provide the bus object, an address to read and the number of bytes you wish to extract from that device address beginning at 0x00. If the bus and address can be accessed, it will return a byte array then we can then work with.

    I then wanted to write dump this to a file so I created another function

    def write_binary_to_file(data, filename = "binary.bin", append = 0):
        if append == 0:
            print("\nWriting binary to file... ", filename)
        elif append == 1:
            print("Appending binary to file... ", filename)
        # Open file to dump the EEPROM data into
        if append == 0:
            file = open(filename, "wb")
        elif append == 1:
            file = open(filename, "ab")
            
        for i in data:
            file.write(i.to_bytes(1, 'big'))
        file.close()

    This function takes the byte array, a file name, and whether you want to append the data to the file or rewrite the file. This is important if we have 8-bit addressed eeproms with multiple internal device addresses like the 24RF08.

    Now, with that done, we can simply dump the entire eeprom of a Lenovo Thinkpad X201 Tablet using six lines of code (IF YOU DON'T HAVE AN OSCOLLOSCOPE ATTACHED TO YOUR I2C BUS AND YOU DON' T KNOW WHEN THE LAPTOP IS ACCESSING THE BUS, DO NOT DO THIS OR TURN THE LAPTOP OFF WITH THE POWER SUPPLY STILL ATTACHED. SUSPEND OR SLEEP WON'T CUT IT!!)

    eepromDump = eeprom.read_from_eeprom_8(bus, 0x54, 256)
    eeprom.write_binary_to_file(eepromDump, "eeprom.bin", 0)
    eepromDump = eeprom.read_from_eeprom_8(bus, 0x55, 256)
    eeprom.write_binary_to_file(eepromDump, "eeprom.bin", 1)
    eepromDump = eeprom.read_from_eeprom_8(bus, 0x56, 256)
    eeprom.write_binary_to_file(eepromDump, "eeprom.bin", 1)
    eepromDump = eeprom.read_from_eeprom_8(bus, 0x57, 256)
    eeprom.write_binary_to_file(eepromDump,...
    Read more »

  • Scanning the bus - be amazed!

    Timo Birnschein02/14/2021 at 18:39 0 comments

    After a fresh installation of Debian on my Beaglebone Black I was greeted with a console interface that had all the essential tools already installed. It's a development platform after all. They provide everything for I2C devices as well. I had a 24C02 EEPROM sitting around, so made it my first target. I set the address to 0x57 in this example - why will be clear in a later entry.

    debian@beaglebone:/var/lib/cloud9$ i2cdetect -r -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --

     I was happy to see that the bus worked. I had one device connected to I2C-2 which is sitting on P9_19 (SCL) and P9_20 (SDA) and work right away.

    (source: https://datko.net/2013/11/03/bbb_i2c/)

    I ran a couple of experiments with this EEPROM to make sure I can read and write to the various addresses. It's a 2kBit (256byte) EEPROM - not a lot of space. this particular one can be accessed incrementally with a page size of 256byte. That makes, when reading, I can set the address counter to 0x00 and then run 256 consecutive reads and always get the next byte until it rolls over at the end of the page (address 0xFF).

    i2cset -y 2 0x57 0x00 // write to the address counter 0x00 i.e. RESET it
    
    ic2get -y 1 0x57 // returns byte at 0x01
    ic2get -y 1 0x57 // returns byte at 0x02
    ic2get -y 1 0x57 // returns byte at 0x03

     I tested this concept on the console before I jump in and write the python code - of which I knew almost nothing about at this point.

    You can also simply dump an entire 256 byte chunk of an EEPROM (with 8 bit address space) buy using

    debian@beaglebone:/var/lib/cloud9$ i2cdump -y 2 0x57
    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 21 f8 f8 f8 41 50 21 21 74 20 69 73 20 70 72 6f    !???AP!!t is pro
    10: 76 65 20 74 68 61 74 20 79 6f 75 20 68 61 76 65    ve that you have
    20: 20 77 72 69 74 74 65 6e 20 32 35 36 20 62 79 74     written 256 byt
    30: 65 73 20 69 6e 74 6f 20 61 6e 20 45 45 50 52 4f    es into an EEPRO
    40: 4d 2e 20 49 20 64 6f 6e 27 74 20 6b 6e 6f 77 20    M. I don't know
    50: 69 66 20 79 6f 75 72 20 45 45 50 52 4f 4d 20 69    if your EEPROM i
    60: 73 20 61 63 74 75 61 6c 6c 79 20 32 35 36 20 62    s actually 256 b
    70: 79 74 65 73 20 61 74 20 74 68 65 20 74 69 6d 65    ytes at the time
    80: 20 6f 66 20 77 72 69 74 69 6e 67 20 62 75 74 20     of writing but
    90: 6f 6e 20 74 68 65 20 6f 74 68 65 72 20 68 61 6e    on the other han
    a0: 64 20 69 74 20 64 6f 65 73 6e 27 74 20 72 65 61    d it doesn't rea
    b0: 6c 6c 79 20 6d 61 74 74 65 72 2e 20 54 68 65 20    lly matter. The
    c0: 69 6d 70 6f 72 74 61 6e 74 20 70 61 72 74 20 69    important part i
    d0: 73 20 74 68 61 74 20 79 6f 75 20 68 61 76 65 20    s that you have
    e0: 77 72 69 74 74 65 6e 20 32 35 36 20 62 79 74 65    written 256 byte
    f0: 73 20 73 75 63 65 73 73 66 75 6c 6c 79 21 21 21    s sucessfully!!!

     Very handy if you just want to see what the current contents of an EEPROM are. However, it must be said that at no time can two different bus masters access the same bus at the same time. On I2C there is always only one bus master allowed or corrupted data is guaranteed!

    To write the above content to the EEPROM, I decided to start with Python.

View all 6 project logs

Enjoy this project?

Share

Discussions

alex091704 wrote 01/06/2024 at 21:15 point

can you do this on a EC chip on a newer laptop?

  Are you sure? yes | no

Jermaine Wyman wrote 03/29/2021 at 14:17 point

hi

  Are you sure? yes | no

Timo Birnschein wrote 03/29/2021 at 19:10 point

hi! :)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates