NthTry99
January 2026 (Revised April 2026)
The Access Protection Page (APP)
This document describes a process to recover a lost/unknown Supervisor Password (SVP, aka BIOS password) from an IBM ThinkPad T40 (circa 2003). The SVP data is stored in an EEPROM chip on the motherboard, which will be obtained by dumping the data directly from the chip, using a Raspberry Pi Pico as an external I2C programmer. With this data, the password can be decoded via a script/software.
This process should also work for several other IBM ThinkPad models (i.e T41 and T42), and likely other laptops from that era.
I’m sure there are other methods, firmware, software, and tools available which are easier and do not require as many specific configurations. But, I am still learning and this is the process I was most comfortable with and knew the most about.
DISCLAIMER: I am not responsible for any damage caused by, or misuse of, the information in this document. This document is purely for educational/informational purposes in the context of security research.
If you decide to try this and there is anything you do not understand in this document, be sure to ask or look it up!
Before beginning, it is important to have a general understanding of electronics, components, memory, and familiarity with Windows/WSL or Linux.
Physical Tools Required:
Verify (either physically or via research) that your IBM ThinkPad (target PC) uses a 24-series I2C serial EEPROM chip. Many IBM ThinkPad laptops in the late 1990s through early 2000s used these EEPROM chips. In this procedure I will be using my T40 (from 2003). While it is likely that this process would work on other laptops/PCs which use this series of EEPROM, I cannot guarantee anything.
Disassemble the laptop and locate the EEPROM chip. Look for an 8-pin SOIC-8 form-factor chip. On my T40 the EEPROM chip is under the Intel WM3B2100 internal WiFi network adapter card, which is directly under the TrackPad.



Once you have found your EEPROM chip, it is important to look up its datasheet and learn about it. My EEPROM chip is an Atmel AT24RF08CN.
Here is a snippet from the datasheet:

The datasheet says its operating range is 2.4V-5.5V. To verify using a multimeter, I carefully tested the DC voltage from the EEPROM’s VCC pin to a motherboard ground and it was 3.3V. The Raspberry Pi Pico also operates at 3.3V so I will use it in this guide.
If your EEPROM chip operates at 5V or 1.8V, see Appendix 1 (AP1).
The commands and tools used are Linux-based, so we will need either Windows with a specially configured Windows Subsystem for Linux (WSL2) environment OR (preferably) a Linux distro running on bare metal, which should work with minimal (if any) additional configuration.
I was very hesitant on keeping the following section (3.1 WSL2 Configurations) in this writeup as opposed to putting it in its own document. However, I decided to keep it here because it is still a requirement if you are following along and using Windows.
[WINDOWS ONLY] [if using Linux skip to 3.2]
At the time of this writing, the stock Microsoft WSL2 kernel does not include I2C kernel modules, which function as device drivers for I2C adapter hardware. Therefore, we will have to compile a custom kernel to include these I2C modules.
3.1.1.2 Open PowerShell and install WSL:
powershell:
wsl --install
This will install Ubuntu by default. The computer should restart. If it doesn’t, do a manual restart. A Linux terminal should automatically open. If it doesn’t, launch Ubuntu manually:
powershell:
wsl
Follow the prompts and create a username/password for your Ubuntu distro. Then, immediately update Ubuntu (and restart if necessary):
bash:
sudo apt update && sudo apt upgrade
3.1.2 Configure Custom WSL2 Kernel Modules
bash:
sudo apt update && sudo apt install build-essential flex bison libssl-dev libelf-dev bc dwarves python3 pahole cpio libncurses-dev
3.1.2.2 Identify the current kernel version:
bash:
uname -r
Output should be something like “6.6.87.2-microsoft-standard-WSL2” which means we want version 6.6.87.2
3.1.2.3 Go to Home directory and clone the specific branch of the kernel source:
bash:
cd && git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1 -b linux-msft-wsl-6.6.87.2
See Appendix 2 (AP2) for why we changed to home directory (cd).
See Appendix 3 (AP3) for option meanings.
3.1.2.4 Verify the VERSION and PATCHLEVEL match the expected version:
bash:
cd WSL2-Linux-Kernel
head -n 5 Makefile
output:
VERSION = 6
PATCHLEVEL = 6
SUBLEVEL = 87
EXTRAVERSION = .2
3.1.2.5 Copy the standard Microsoft configuration as a starting point:
cp Microsoft/config-wsl .config
3.1.2.6 Modify the configuration file to include the i2c-tiny-usb module/driver:
bash:
cp make menuconfig
A DOS-style GUI will appear.
Navigate (using arrow keys) down to “Device Drivers —>” and press Enter.
Navigate down to “I2C support —>” and press Enter.
Make sure “I2C device interface” is enabled (with <*> by it). Press Y if not.
Navigate down to “I2C Hardware Bus support —>” and press Enter.
Navigate down to “Tiny-USB adapter” and press Y. You might see a screen saying “This feature depends on another which has been configured as a module. As a result, this feature will be built as a module.” This is ok, press Enter.
You should now see <M> by Tiny-USB adapter:
Navigate to the right and select Save and then Exit.
Overwrite the old .config file.
bash:
make -j$(nproc)
See Appendix 4 (AP4) for option meanings.
**To keep one core free for system use, you can use
bash:
make -j$(($(nproc) - 1))
When it finishes, it should creae a file:
./WSL2-Linux-Kernel/arch/x86/boot/bzImage
If this file is 0 bytes in size, then it did not compile correctly.
bash:
sudo make modules_install
bash:
cp ./WSL2-Linux-Kernel/arch/x86/boot/bzImage /mnt/c/Users/YourUsername/bzImage
bash:
nano /mnt/c/Users/YourUsername/.wslconfig
Add the following 2 lines, with the second line including the path to your bzImage. If “[wsl2]” is already there, do not add it again, just add the second line below it. Make sure to use double backslashes for the path:
[wsl2]
kernel=C:\\path\\to\\your\\bzImage
bash:
exit
powershell:
wsl --shutdown
wsl
Download/install usbipd-win_5.3.0_x64.msi https://github.com/dorssel/usbipd-win/releases/tag/v5.3.0
USBIPD-WIN is an open-source virtual passthrough adapter used to share locally connected USB devices (our I2c Pico) from a Windows host to other machines or environments (WSL2).

[LINUX ONLY]
NO SPECIAL CONFIGURATION REQUIRED
Most major Linux distros already include I2C kernel modules, although they may not be loaded by default. Verifying/loading them will be the same process as for WSL, later in this guide. You will also not need a virtual passthrough adapter (usbipd-win) since the I2C programmer will be directly communicating with the Linux kernel.
[BOTH WSL and Linux]
Download i2ctools and usbutils:
bash:
sudo apt install i2c-tools usbutils
The remainder of this guide is the same for both WSL2 and Linux unless otherwise noted
Next, we will need to flash special firmware to the Raspberry Pi Pico which will transform it into a USB-to-I2C bridge.
I will be using I2C-Pico-USB firmware from https://github.com/dquadros/I2C-Pico-USB
On this GitHub repo, within the “firmware” directory, you can find a “build_pico” directory, which contains i2cpicousb.uf2 (use “build_pico2” if you are using a Pico2). This is the pre-compiled firmware we will be flashing to our Pico. Save this file.
Alternatively, if you would like, you can clone this repository and compile it yourself. There are instructions on the GitHub page above.
To flash firmware to a Raspberry Pi Pico, hold the “BOOTSEL” button on the Pico while plugging it into the host PC, then release the button. This will put the Pico into Bootloader Mode.
The Pico should now show up in Windows Explorer/File Manager as a USB Mass Storage Device, like a USB flash drive. Copy i2cpicousb.uf2 directly to the root of the Pico.
Now that the host-PC environment is prepared and the Pico firmware has been flashed, it is time to configure their connection:
[WINDOWS ONLY] [if using Linux skip to 5.2]
Before configuring drivers, the I2C-Pico-USB will show up in Device Manager as an “Other device” and not have any drivers:




Make sure you have WSL open in one window/tab and a regular PowerShell (admin) open in another. We will be using both.
usbipd list
BUSID VID:PID DEVICE STATE
1-4 0403:c631 i2c-pico-usb Not shared

usbipd bind --busid 1-4

usbipd attach --wsl --busid=1-4

NOTE: you will have to run this command every time you connect the Pico to the host PC in order for WSL to see it. Run the above command from a separate PowerShell window while WSL is running.
Also, i2c-pico-usb will no longer show up in Device Manager after attaching it to WSL via the usbipd attach command, but it will be visible to Linux.
[BOTH WSL and Linux]
Load the I2C kernel modules:
bash:
sudo modprobe -a i2c-tiny-usb i2c-dev
lsmod | grep i2c
i2c_dev 24576 0
i2c_tiny_usb 16384 0
usbcore 356352 1 i2c_tiny_usb

sudo lsusb
Output should be something like:
Output (abridged):
Bus 001 Device 002: ID 0403:c631 Future Technology Devices International, Ltd i2c-tiny-usb interface
sudo i2cdetect -l
Output should be something like:
Output (abridged):
i2c-0 i2c i2c-tiny-usb at bus 001 device 002 I2C adapter

Next, we will prepare jumper wires (including the necessary pull-up resistors) from the EEPROM/SOIC-8 test clip to the Pico.
—It is VERY IMPORTANT to understand that we will be using the TARGET LAPTOP itself to provide the 3.3V to the EEPROM (in circuit), NOT THE PICO. For more information on why, see Powering the EEPROM Chip—
–For this project, we will not use L1 (pin 1), L2 (pin 2), or WP (pin 7)–
See Appendix 5 (AP5) for a deeper explanation of these pin functions.
Here is the wiring to the test clip/EEPROM:

Connections to Make:

Schematic:

Pico Connections:
Here is the wiring to the Pico:

Here is my wiring setup:

Once everything is connected, double and triple check that everything is connected properly.
On the test clip, you should have:
See Appendix 6 (AP6) for wiring tips.
Official instructions/source for the I2C-Pico-USB firmware are on https://github.com/dquadros/I2C-Pico-USB
With the host PC and Raspberry Pi Pico configured, and all wiring prepared, it is time to actually read the EEPROM data.
Here is another part where I’m sure there’s room for improvement: I will be using i2cdump, which reads the data and outputs it into a human-readable formatted hex dump as well as ASCII translations. I am sure there is a command to dump the memory block directly as a raw binary file (.bin). However, I tried several different tools/commands, including i2ctransfer, and was unable to get consistent, safe results.
Due to the nature of I2C EEPROMs, reading from an address actually requires a “dummy write” to set the chip’s internal address pointer prior to retrieving the data. While it isn’t supposed to actually write data during this dummy write, when I tried i2ctransfer it DID somehow either write or otherwise corrupt data at the first offset of the memory address I was attempting to dump. Luckily, I was able to recover the data to its original state, but this was enough to steer me back to just using/converting i2cdump.
In the future, I am going to buy a loose AT24RF08CN EEPROM chip and troubleshoot/test other read commands without risking bricking a laptop. I might even just write my own program to read/write/unlock it.
Attach test clip to EEPROM chip, power on the target laptop first (it likely won’t boot or display anything on the screen), then connect Pico to host PC.


bash:
sudo i2cdetect -y -r 0
See Appendix 7 (AP7) for options meanings.
You should get a table of responding addresses:

The above addresses are the 7-bit addresses (the 8th bit indicates read/write). The 24RF08CN datasheet uses 8-bit addresses but i2ctools (i2cdetect, i2cdump, etc.) use 7-bit addresses.
For details on how data is stored on this EEPROM chip see Appendix 8 (AP8).
For an explanation of 7-bit vs 8-bit addresses, see Appendix 9 (AP9).
The main data blocks are at addresses 0x54-0x57, the SVP is in Block 6 (first half of 0x57).
sudo i2cdump -y 0 0x57 > 0x57DUMP.txt

**NOTE: if your 0x57 dump looks like this (with all the XXs):
then go to The Access Protection Page (APP) section at the bottom.
Run the following command to convert the formatted hex dump (.txt) to binary (.bin):
bash:
cat 0x57DUMP.txt | awk '/^[0-9a-f]0:/{for(i=2;i<=NF;i++) if($i ~ /^[0-9a-fA-F]{2,4}$/) printf "%s", $i} END{print ""}' | xxd -r -p > 0x57DUMP.bin
For an explanation of this command, see Appendix 10 (AP10).
Now that we have a dump of the memory block containing the Supervisor Password data, it is time to decode and uncover the password. Within that 0x57 block dump, the SVP should be at offset 0x38 and repeat at 0x40.
Note that the hex data at these offsets are scancodes representing the SVP, not ASCII (human-readable) data. To uncover the password, you need to decode these scancode values into ASCII characters. There are 4 primary options:
OPTION 1:

WINDOWS:
Simply run ibmSVP_scanDecoderV3.1.exe:
Very straightforward. My application can decode the SVP from the specific SVP block or a full 1024-byte EEPROM dump, and can process dumps in .txt OR .bin formats. So you can just load the output of i2cdump right into it if you want.
chmod +x ibmSVP_scanDecoder-3.1-x86_64.AppImage
python .\ibmSVP_scanDecoder_CLI.py --file yourDUMP.bin
python3 ibmSVP_scanDecoder_CLI.py --file yourDUMP.bin

Power on the target PC and use the Supervisor Password you uncovered:

You should now have full access to the BIOS settings where can keep, change, or remove the SVP:

Reassemble the laptop and you are done.
This is the safest and easiest way to recover an unknown Supervisor Password from a BIOS-locked IBM ThinkPad of this era which utilizes this series of EEPROM. If you were to try directly changing or removing (zeroing out) the SVP within the EEPROM (in 0x57), you would likely encounter a POST error (Error 0177) because there are data validation measures (a checksum) in place to prevent this very thing. If you are interested in more details regarding this, I have a separate project called IBM_ThinkPad_CRC_Calculator where I dive into this, as well as other BIOS/POST Errors related to CRCs.
The Access Protection Page (APP)
The following info is based on this forum post: https://forum.reveltronics.com/viewtopic.php?t=292
Many 24-series EEPROM chips (including my AT24RF08CN) have additional security features which can prevent access to main data blocks. It does this by setting certain bits in memory called Protection Bits (PB) to either 0 or 1. These bits are stored at certain offsets in the APP at memory address 0x5C. Specifically, this feature can be used to “lock” access to block 6 (memory address 0x57) which is where the SVP data is. More info is available on the datasheet.
I have not been able to determine exactly what triggers the setting of these Protection Bits. Interestingly, if you do have access to the BIOS menu, changing the SVP or any BIOS setting seems to oftentimes toggle this lock. However, if you do not have access to the BIOS menu and this lock is engaged, there is no option other than manual intervention via an external programmer to unlock it and therefore access the SVP data.
For testing purposes, one way I was able to get this lock enabled was to engage the “Security Chip” setting in the BIOS settings:
On the main BIOS menu, there is a Security page:

On the Security page, there is an IBM Security Chip page:

On the IBM Security Chip page, there is an option to enable or disable the Security Chip. I simply enabled this feature:


sudo i2cdump -y 0 0x5c
output:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: ae ae ff ff ff ff 83 83 ff ff 7f ff ff ff ff 49
10: 93 07 1d 85 d8 5c 52 38 df 64 63 60 ff ff ff 7f
Note how offset 0x06 (which controls access for block 6 where SVP is) is 0x83, which is 10000011 in binary. Last 2 digits (PB bits) are 11 which means “Read/write - No access constraints for data within this block” (from the datasheet).
sudo i2cdump -y 0 0x5c
output:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: ae ae bf bf af af 80 83 ff ff 7f ff ff ff ff 49
10: 93 07 1d 85 d8 5c 52 38 df 64 63 60 ff ff ff 7f
In this case at 0x06, it is 0x80 = 10000000 in binary (PB bits are 00 which means “No access permitted in the block”).
This will cause the data at 0x57 to all display as XX.
sudo i2cdump -y 0 0x5c > app_locked_backup.txt

–only worry about the first 32 bytes, not the XXs–

–I show it being done manually here just to better illustrate what is going on. Feel free to write a script–
sudo i2cdump -y 0 0x57 > 0x57DUMP.txt


With this done, you can now proceed normally in the main guide at Step 7.1.4.
Appendix 1 (AP1)
If your EEPROM chip operates at 1.8V or 5V you will also need a bidirectional logic level converter wired between your programmer and the target EEPROM chip. See https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all and also look up more info online.
Appendix 2 (AP2)
cd changes to the home directory in Linux.
From this point on unless otherwise noted: in WSL, try to operate within the native Linux filesystem (i.e /home/USERNAME which is ext4, and is on a virtual hard disk) instead of the default /mnt/c/Users/USERNAME, which is the Windows filesystem (NTFS). It will be much faster since accessing Windows requires Linux to translate between ext4 and NTFS. Technically, the Windows C drive is being mounted into the system’s directory tree, hence “/mnt/c/Users/USERNAME”.
[back to 3.1.2.3 Go to Home directory and clone the specific branch of the kernel source]
Appendix 3 (AP3)
bash:
cd
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1 -b linux-msft-wsl-6.6.87.2
--depth=1: Creates a shallow clone by fetching only the latest commit of the repository’s history. You get the current files without the gigabytes of previous version history, making the download much faster.
-b Specifies a branch or tag to clone (linux-msft-wsl-6.6.87.2 in this case)
[back to 3.1.2.3 Go to Home directory and clone the specific branch of the kernel source]
Appendix 4 (AP4)
bash:
make -j$(nproc)
-j flag sets the number of parallel jobs and $(nproc) returns the total number of logical CPU cores available to the system. This command forces all logical cores to run multiple compilation jobs in parallel.
[back to 3.1.3 Compile the Custom Kernel and Modules]
Appendix 5 (AP5)
[back to 6. Wire Pico to Test Clip]
Appendix 6 (AP6)
In retrospect, I would recommend putting the pull-up resistors and wire splices closer to either the male or female ends of the wires instead of the middle since (as you can see) things ended up bending a little awkwardly. Longer wires would definitely make it more convenient but the longer they are, the higher the probability of signal integrity issues, parasitic capacitance, corrupted data, etc.
And remember to put your heat shrink on before you solder your wires…
[back to 6. Wire Pico to Test Clip]
Appendix 7 (AP7)
[back to 7.1.2 Check Connectivity To Chip]
Appendix 8 (AP8)
The AT24RF08CN EEPROM has 8 main data blocks (0-7) which are 128 bytes each. The datasheet refers to memory addresses in their 8-bit address format, so it says the main data blocks are 0xA8-0xAF, whose 7-bit addresses are 0x54-0x57. However, 2 blocks are stored together at 1 memory address, so each address is actually 256 bytes (2 x 128-byte blocks). They are as follows:
There is also:
The APP and ID Pages are stored together at 0xB8 (8-bit address) which is 0x5C (7-bit address).
In total, the chip stores 8448 bits of data. They are located and organized as follows:
-----Total: 1056 bytes (8448 bits)-----
SIDE NOTE IF PROGRAMMING A BLANK EEPROM CHIP
If you ever intend to clone/program an EEPROM chip such as this, make sure you write the main data blocks FIRST, then write the APP/ID section. Otherwise, you run the risk of locking yourself out of the main blocks.
[back to 7.1.2 Check Connectivity To Chip]
Appendix 9 (AP9)
8-bit address vs 7-bit address:
In I2C communication, an 8-bit address is typically the 7-bit address shifted left by one bit, with the 8th bit (the Least Significant Bit or LSB) serving as the Read/Write flag (0=write, 1=read).
So for 0xA8 and 0xA9:
i2ctools (i2cdetect, i2cdump, etc) will automatically handle shifting and setting that 8th bit for you based on whether you call a read or write function, hence you use the 7-bit address.
[back to 7.1.2 Check Connectivity To Chip]
Appendix 10 (AP10)
Explaining the .txt dump to .bin command:
bash:
cat 0x57DUMP.txt | awk '/^[0-9a-f]0:/{for(i=2;i<=NF;i++) if($i ~ /^[0-9a-fA-F]{2,4}$/) printf "%s", $i} END{print ""}' | xxd -r -p > 0x57DUMP.bin
This command reads out (concatenates, aka cat) 0x57DUMP.txt, the puts that output through awk (to extract data from specific fields), regular expressions, and xxd together to strip headers or sidebar text and convert the hex to raw binary, which is needed for ibmpass2.2Lite, ibmsupervisor, or my script/program ibmSVP_scanDecoder.
The code between the slashes /^[0-9a-f]0:/ is a regex constant. It filters the input file to find lines that match a specific structure.
^: Asserts the match must start at the beginning of a line.
[0-9a-f]: Matches exactly one hexadecimal character (0-9 or a-f)
AWK automatically splits each line into fields (columns) based on whitespace. $2 is the second column, $3 the third, and so on.
for(i=2;i<=17;i++) iterates 16 times to grab columns 2 through 17.
i<=NF (Number of Fields) ensures you catch all data regardless of whether a line has 16 bytes or fewer.
The if($i ~ /^[0-9a-fA-F]{2,4}$/) check ensures that only hex digits are passed to xxd, skipping any ASCII sidebars (Hex-only filter).
printf "%s " adds a space after every byte.
The xxd command is used for the actual conversion back to binary.
-r (Revert): Tells xxd to do the reverse of a hex dump, converting hex characters into their original raw binary form.
-p (Plain/Postscript): Informs xxd to expect a “plain” stream of hex digits without line numbers or ASCII sidebars.
[back to 7.2 Convert Dump (.txt) to Raw Binary (.bin)]
I did not originally have to unlock the APP, but then I found https://forum.reveltronics.com/viewtopic.php?t=292 and wondered what it was all about. I was able to get my chip to enter this locked state, and thus the Access Protection Page section was born. Also it is entirely plausible that in many cases, the block containing the SVP data could be locked, and in that case this info is important.
Originally the first time I compiled my own custom kernel and modules, my bzImage was 0 bytes and I had compile errors. The computer I was working on was just an old T470 I had lying around, only 8GB RAM, a dual-core Intel CPU, running Windows 11 (unsupported of course); I suspected it ran out of memory. So I had to set compile specs:
[wsl2]
memory=4GB
processors=3
swap=12GB
[experimental]
autoMemoryReclaim=gradual
Powering the EEPROM Chip
Originally I had a lot of trouble actually getting the Pico to read or detect the EEPROM. Also, at first, my plan was to use the Pico to supply 3.3V to the EEPROM chip. Note how in the guide however, I say to let the target laptop power the EEPROM chip. This will be important in a few paragraphs.
From my SPI programming project I knew that wiring an in-circuit chip to a Raspberry Pi Pico with jumper wires an a test clip can be a little janky. In that process, I had to lower the speed in order to read the SPI flash chip. So of course that is the first thing I tried.
This required going into the I2C-Pico-USB code to change it to operate at 50kHz instead of 100kHz. I then recompiled it and flashed it to the Pico but had the same inability to read/detect the EEPROM.
I actually took a break for a couple of days at this point. I had read that this chip requires some unusual variation of START or ACK commands which differ from other EEPROM chips and thought there could be some unusual compatibility issues with i2ctools.
But then I entered into “just fiddle with it and not write it down” mode. I tried connecting the WP pin (Write Protect) to VCC (which would have been read-only, preventing writes), tried tying it to GND (which would allow writes), then disconnected it altogether and none of it made any difference. So I just left it disconnected, which is why I never mentioned it.
I somehow figured out that the Pico wasn’t even being recognized by the host PC when the test clip was connected to the EEPROM. Then I discovered it WOULD be recognized if the test clip was disconnected. Both my modified 50kHz version as well as the original I2C-Pico-USB firmware behaved this way.
In the back of my mind I knew there are always inherent risks/problems with in-circuit programming. Like backfeeding. Which turned out to be exactly what the problem was. Using a multimeter, I checked voltage between VCC to GND of the Pico with it plugged into the host PC and the test clip disconnected: 3.3V. Then I tested it with the test clip connected: around 50mV and jumping all around.
What was happening was the programmer (Pico) was backfeeding current into the main power rail of the target PC’s motherboard, drawing too much current, and triggering the host-PC’s USB Overcurrent Protection (OCP), thus not being detected. The Raspberry Pi Pico lacks a built-in current-limiting fuse or smart “overcurrent protection” circuit on its power rails.
So I removed the connection between the Pico and the EEPROM VCC pin (you can see it dangling in some of the pics), but left the EEPROM VCC attached to the test clip (SCL and SDA still needed to be pulled up to 3.3V and PROT still needed to be tied HIGH) and decided to try it by letting the target PC power the EEPROM. This is what finally worked.
[back to 6. Wire Pico to Test Clip]
Failed Attempts at .txt to .bin commands (and regex…)
This was my first attempt at a command to convert a .txt hex dump to binary:
(OLD COMMAND)bash:
cat input.txt | awk '/^[0-9a-f]0:/{for(i=2;i<=17;i++) printf "%s ", $i}' | xxd -r -p > output.bin
This did not always work correctly. It would sometimes shift the data by a few bytes, resulting in my SVP starting at 0x35 instead of 0x38.