Boot Logo

From Joggler
Jump to: navigation, search

Disclaimer

This is a sure way to brick your device - ensure you have at least another identical unit available to recover your EFI flash chip before proceeding. This involves disassembling both units - and hotswapping the chip! Now you've been warned, lets continue!

Historical

The remainder of this page is left for historical purposes - in case there is anything I have overlooked and need to come back to.

For s step by step howto see howto customise the boot logo.

Work in progress

This is not yet complete - if you can help work out the final steps then please do!

Update (21st August 2010)

This procedure is now confirmed as working! I endeavour to make a clearer set of instructions and even a script to ease / automate most of the work. It should be noted that the below "procedure" was more a documentation of my findings as I experimented rather than an effort to make a howto.

One should also take note before trying to follow the below procedure that the extracted files resulting from efidump.py do away with a preceding 4 bytes (32 bit total length including self) which must be put back in place prior to compressing the modified driver.

Obtaining the EFI binary image

Obtain efidump :

svn checkout http://adqmisc.googlecode.com/svn/trunk/ adqmisc

login to your device using the well documented telnet "hack"

Attach a usb storage device and wait for it to mount, then unmount it and manually mount it so that it is mounted read-write

umount /mnt
mount /dev/sda1 /mnt

now load the firmware module

modprobe fh

Now dump the firmware to your usb storage medium.

dd if=/dev/fh of=/mnt/efi.original.bin 

Now unmount the medium

umount /mnt

Editing

Transfer it to your pc and dissect the file with efidump

Create an empty directory and cd into it - there will be a lot of files created in this step.

mkdir ~/tmp
cd tmp

Mount your medium and run efidump on it : Assuming the medium is mounted at /media/disk and the efidump tool is in ~/adqmisc/efi do the following

~/adqmisc/efi/efidump.py /media/disk/efi.original.bin

You should see a load of text pass by and end up with loads of files with long obscure names.

At this point your results may vary - The checksum printed on the EFI flash chip of my devices is "DBFFB" if yours is different you are bound to have a different EFI version and possibly different strings than in my findings below.

Locate the file called "V0001.F0050-2b13e5f0-e82e-4209-898a-8a53e8570db9.S0000-COMPRESSION.S0000-PE32" This was determined from the "drivers" command in the EFI shell.

Open this file in a hexeditor,

The image data starts at offset 1696 and is of length 19440 bytes. It is formatted RGB left to right top to bottom 80x81 pixels. You can load it in the gimp as "raw image data" choosing the appropriate settings in the dialog that appears.

It is relatively easy to get a new image back into the file we just opened but I have as yet to work out how to get this back into a working image which can be flashed to the device.


I tried compressing the modified iegd driver file using eficompress command in the efi shell and pasting the result into the efi binary - the result of course - a bricked device.

Looking an EFI binary in a hexeditor (the one extracted from flash above) you can locate the start of the IEGD driver file in the raw compressed form. The first hex string "2b13e5f0-e82e-4209-898a-8a53e8570db9" within the filename is the GUID of the file as it is named in the EFI FFS. the first part (2b13e5f0) - a little endian 32 bit value which can be found in a hex editor searching for "f0e5132b".

This is the start of a 24 bytes header.

The following 12 bytes are also part of the GUID Following this are some integrity check values (an 8 bit checksum for header and another for the file file), the data length and some attributes , notably the value 0x40 20 bytes into the. header specifies that the data should be verified by checksum.

bytes 20-23 are a little endian 24 bit value for the size of both the data and the header (and i think also a tail if it were used, but for this file it is not)

After the FFS file header are a further 9 bytes prior to the Huffmann encoded driver image. This is a EFI_COMMON_SECTION_HEADER followed by a EFI_COMPRESSION_SECTION_HEADER.

The first 3 bytes are another 24bit size value of the file size including itself - so the same as the previous size value - 24. There is then a single char 0x01 which indicates the section type is compressed data. The next header contains a 32 bit uncompressed data length of the Huffmann encoded data - this is identical to bytes 4-8 of the Huffman encoded data, there is then a further byte 0x01 which specifies that the data is compressed!.

The Huffman encoded IEGD driver module follows

There is a fair amount of pad (empty) space after the module so if your resulting compressed module ends up bigger due to use of a logo that is not as compressible this should be ok.


Add 24 to the size of the data you pasted in and convert this to hex. In the case of my EFI image the original hex is "9D1901" which is 0x01199D which is 72093, -24 is 72069.

The checksums can be worked out easily using okteta (in kde4) and probably other hexeditors. In the 24 byte ffs header set the state byte (last one) and the 2 checksum bytes to 0. Now select the entire 24 bytes of header and click "calculate" under checksum with type set to 8 bit sum. Enter the result for the header checksum.

Now highlight the file data and click calculate. enter the result for the file checksum.

remember to set the state value back to 0xf8 once done with the checksums.

This seems to be all that should be necessary to achieve the goal of replacing the logo - but so far all attempts have failed :(.

Before trying to flash the resulting binary check to see if efidump is able to extract all the contents correctly.

Further observations

The file as dumped by efi dump differs from that as produced by efidecompress. The latter is 4 bytes longer - on comparison the difference is obvious - there are 4 extra bytes at the start of the file. The 1st 3 bytes are a 24 bit value of the total file size. the 4th is possibly a checksum.

Decompressing the file and compressing it again (with eficompress in efi shell) yields different binary data, subsequent cycles remain identical. This can be observed by comparing both file size and md5sum of the original and each subsequent step.

Possibly a different Huffman implementation was used to create the original code than that provided by eficompress.

The efishell version of eficmpress appears completely broken. compressing a simple text file and decompressing it shows this.

I have found a cmd line eficompress/decompress tool. http://boeglin.org/static/efidecompress/


But also found this in a forum :


"I works for a EFI bios vendor. I know Apple use default algorithm, but we don't. Intel also use customized version fot[siq] its own board.
AMI use default on some engineering sample bios, but use customized one in its product bios."
http://www.wimsbios.com/forum/topic7944.html

I suspect the algorithm used differs and that adq's efidump knows about the different algorithm.


With a few tweaks I managed to compile the eficompress tool that is shipped with edk [1] for linux. By specifying the Tiano compression method the resulting file almost decompresses with efidump, failing 27 bytes from the end.

Update (21st August 2010)

I gave up to soon previously! The apparent failure to decompress after building the Tiano compressor and attempting a compress/decompress cycle was a red herring - the error message I was getting was in fact because I had not provided an output file to write to - I was merely misinterpreting the python back-trace.

I have managed to build a new EFI image that efidump successfully unpacks. later today i will try flashing it to see if it actually works.