Skip to content

Instantly share code, notes, and snippets.

@cleverca22
Last active July 27, 2022 12:17
Show Gist options
  • Save cleverca22/2a7e68d4a3d7802fcb3fe72c0aaa152a to your computer and use it in GitHub Desktop.
Save cleverca22/2a7e68d4a3d7802fcb3fe72c0aaa152a to your computer and use it in GitHub Desktop.
rpi eeprom decode
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200 00 b0 00 01 f0 81 00 c0 e0 00 00 6d 82 18 0d 1f |...........m....|
00000210 1d c0 41 07 18 e8 00 e8 00 80 19 e8 67 e8 00 80 |..A.........g...|
00000220 31 68 f9 c0 01 cf 2d 1f 1d c0 40 07 18 e8 00 e8 |1h....-...@.....|
...
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
BOOT_ORDER=0x1
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0
with import <nixpkgs> {};
let
myghc = haskellPackages.ghcWithPackages (ps: with ps; [ formatting ]);
in runCommand "extractor" { buildInputs = [ myghc ]; } ''
mkdir -pv $out/bin
ghc ${./extractor.hs} -o $out/bin/extractor
''
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NamedFieldPuns #-}
module Main where
import Data.Binary
import Data.Binary.Get
import qualified Data.ByteString as BS
import GHC.Generics
import Control.Applicative
import System.Environment
import Formatting ((%), sformat, hex, shown, stext)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
data FirmwareFile = FirmwareFile
{ firmwareEntries :: [ Entry ]
} deriving (Generic, Show)
instance Binary FirmwareFile where
get = FirmwareFile <$> many readEntry
put = undefined
data Entry = Entry
{ entryOffset :: ByteOffset
, entryMagic :: Word32
, entrySize :: Word32
, entryBody :: BS.ByteString
, entryPadding :: ByteOffset
} | FileEntry
{ entryFileMagic :: Word32
, entryFileName :: T.Text
, entryFileBody :: BS.ByteString
} deriving Show
readEntry :: Get Entry
readEntry = do
offset <- bytesRead
magic <- getWord32be
len <- getWord32be
body <- getByteString $ fromIntegral len
tailOffset <- bytesRead
let
remainder = tailOffset `mod` 8
paddingLen = if remainder == 0 then 0 else (8 - remainder)
padding <- getByteString $ fromIntegral paddingLen
if ( (magic == 0x55aaf22f) || (magic == 0x55aaf11f) )
then do
let
filename :: T.Text
filename = T.decodeUtf8 $ BS.takeWhile (\c -> c /= 0) $ BS.take 16 body
filebody = BS.drop 16 body
pure $ FileEntry magic filename filebody
else
pure $ Entry offset magic len body tailOffset
decodeFirmware :: FilePath -> IO FirmwareFile
decodeFirmware = decodeFile
main :: IO ()
main = do
args <- getArgs
let
prettyPrintEntry :: Entry -> IO ()
prettyPrintEntry Entry{entryMagic, entryBody} = do
let
formatter = "Entry magic=" % hex % " initial_body=" % shown
putStrLn $ T.unpack $ sformat formatter entryMagic (BS.take 32 entryBody)
prettyPrintEntry FileEntry{entryFileMagic, entryFileName, entryFileBody} = do
let
formatter1 = "File Entry magic=" % hex % " name=" % stext % " body=" % shown
formatter2 = "File Entry magic=" % hex % " name=" % stext % " body=hidden"
go2 = putStrLn $ T.unpack $ sformat formatter1 entryFileMagic entryFileName (BS.take 100 entryFileBody)
go3 = putStrLn $ T.unpack $ sformat formatter2 entryFileMagic entryFileName
case entryFileName of
"bootconf.txt" -> go2
_ -> go3
go :: [String] -> IO ()
go [file] = do
parsed <- decodeFirmware file
mapM_ prettyPrintEntry (firmwareEntries parsed)
mapM_ extractFiles (firmwareEntries parsed)
print "hello world"
go args
extractFiles :: Entry -> IO ()
extractFiles Entry{entryMagic, entryBody}
| entryMagic == 0x55aaf00f = do
BS.writeFile "main-body.bin" entryBody
| otherwise = pure ()
extractFiles FileEntry{entryFileName, entryFileBody} = do
BS.writeFile (T.unpack entryFileName) entryFileBody
$ ./result/bin/extractor pieeprom-2019-10-16.bin
"hello world"
Entry magic=55aaf00f initial_body="\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"
Entry magic=55aafeef initial_body="\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255"
File Entry magic=55aaf22f name=memsys00.bin body=hidden
File Entry magic=55aaf22f name=memsys01.bin body=hidden
File Entry magic=55aaf22f name=memsys02.bin body=hidden
File Entry magic=55aaf22f name=memsys03.bin body=hidden
File Entry magic=55aaf22f name=memsys04.bin body=hidden
File Entry magic=55aaf22f name=memsys05.bin body=hidden
File Entry magic=55aaf22f name=memsys06.bin body=hidden
File Entry magic=55aaf22f name=memsys07.bin body=hidden
File Entry magic=55aaf22f name=mcb.bin body=hidden
Entry magic=55aafeef initial_body="\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255"
File Entry magic=55aaf11f name=bootconf.txt body="[all]\nBOOT_UART=0\nWAKE_ON_GPIO=1\nPOWER_OFF_ON_HALT=0\nDHCP_TIMEOUT=45000\nDHCP_REQ_TIMEOUT=4000\nTFTP_F"
-rw-r--r-- 1 clever users 61K Nov 11 19:29 main-body.bin
-rw-r--r-- 1 clever users 3.8K Nov 11 19:29 mcb.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys00.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys01.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys02.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys03.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys04.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys05.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys06.bin
-rw-r--r-- 1 clever users 21K Nov 11 19:29 memsys07.bin
00000000 1c 00 00 00 40 06 00 00 80 0c 00 00 08 00 00 00 |....@...........|
00000010 00 00 00 00 00 00 00 00 98 00 00 00 ef a6 32 01 |..............2.|
00000020 00 00 00 00 00 00 00 00 89 4d 3a ea 02 02 00 00 |.........M:.....|
00000030 02 3d 00 00 21 5c 10 00 b0 11 27 00 50 b2 00 00 |.=..!\....'.P...|
...
@cleverca22
Copy link
Author

cleverca22 commented May 31, 2020

magic 55aaf33f has some kind of 32 byte footer after the body??, probably a sha256 hash of the body?

@dividuum
Copy link

As I poked around pieeprom for a bit as well: Did you by any chance figure out how the files are compressed? Looking at qrcode.bin, you see that there's TRU\x00EVISION-\x00XFILE in there, hinting that it's saved as a TGA file. But the zero-bytes within the string itself suggest that there's some kind of mangling/compression at work as well.

@cleverca22
Copy link
Author

https://git.venev.name/hristo/rpi-eeprom-compress/
raspberrypi/rpi-eeprom#153
and i have since moved this code over to https://github.com/librerpi/rpi-tools/tree/master/eeprom

i think the reason the decompress code errors out, is because the sha256 of the uncompressed body was appended to the end, so i need to cut just the compressed payload out, decompress, then validate the hash

@dividuum
Copy link

Thank you very much! I especially like that your compressor seems to be better than the one used to compress the existing files. :-)

@cleverca22
Copy link
Author

cleverca22 commented Nov 12, 2020

wasnt my decompressor, somebody else made that comment

i still need to implement that decompression into my extraction code

i'm also on #raspberrypi-internals on freenode if you want to chat more about pi things

@jpmorrison
Copy link

wasnt my decompressor, somebody else made that comment

i still need to implement that decompression into my extraction code

i'm also on #raspberrypi-internals on freenode if you want to chat more about pi things

Is there Pi eeprom extraction tool? I see vl805.bin inside and wondering if there's newer vl805 firmware inside?

I flashed vl805_fw_0138a1.bin from raspberry pi to a vl805 based PCIe card - it works but didn't fix UAS performance issues.
Wondering if the Pi has other firmware or tricks for this chipset.

@cleverca22
Copy link
Author

@jpmorrison the vl805 firmware inside this eeprom is in a different format, and cant be flashed to the vl805 eeprom

it must instead be sideloaded at runtime, https://github.com/librerpi/rpi-open-firmware/blob/master/docs/vl805.txt partially explains how

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment