Howto customise the boot logo

From Joggler
Jump to navigation Jump to search

So, here it is, a step by step procedure.

First off, a warning :

Following this procedure comes with minimal risk until the very final stage, when you risk “bricking” your device. A suitably worded warning comes immediately prior to the relevant steps.

You may well have to modify some of the paths in this howto to suite your setup.


Some prerequisites. You will need :

  • To be reasonably comfortable in a *nix cmd shell,
  • To understand decimal/hexadecimal numbers and endieness,
  • A hex editor, ( I used Okteta in kde4 ),
  • A graphics package ( I used gimp ),
  • EFI Tiano decompressor,
  • EFI Tiano compressor,
  • Patience,
  • Tea/Coffee/Beer,
  • To understand that I am only human (well nearly) and as such there maybe mistakes in this document!

EFI Huffman/Tiano decompressor

You will need to checkout the fantastic efidump.py utility created by Andrew de Quincey, or “adq”.

It can be found here.

http://code.google.com/p/adqmisc/source/browse/#svn/trunk/efi

This tool extracts all the content of the EFI. I have made a quick python script that utilises the Huffman decompression algorithm provided by it to decompress the one bit of the EFI we are interested in. The efidump.py tool is then only needed at the very end as a basic test that our resulting modified image might work.

Create a new file, call it efidecompress.py and put the following in it, then make it executable.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import struct

import EfiDecompressor

def savedata(name, data):
  outstream = open(name, "wb")
  outstream.write(data)
  outstream.close()

instream = open(sys.argv[1])
instream.seek(0, 2)
streamlength = instream.tell()
instream.seek(0, 0)

compressed = instream.read(streamlength)
efidecompressed = EfiDecompressor.Decompress(compressed)
savedata(sys.argv[2],efidecompressed)

EFI Huffman/Tiano Compressor

This part I extracted from the EFI edk found here:

http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK

I will try to cobble and host somewhere a tarball with my working compressor – the code there required some hacking and fiddling to get it to build on my system (seems to all be aimed at the Windows crowd and only a small part of a far larger project).


The procedure

Throughout this procedure we will save each stage as a new file, allowing one to easily drop back to the beginning of each step if something goes wrong.

Part A) – Acquire an efi image

If you don't have it already you can obtain it as follows :

There are two known ways to achieve this step :

Method 1 - with stock o2 or Openpeak firmware

1)boot the joggler on stock firmware with the “telnet hack” enabled. Google “joggle telnet hack” if you don't know what this is.

2)Log in and load the fh module : “modprobe fh”.

3)Insert a USB storage device with at least 1 meg free space and copy the EFI image to it : “dd if=/dev/fh of=/mnt/efi.bin bs=1024k”

Method 2 - with flashrom in a ubuntu/debian etc environment

1) boot the joggler into ubuntu/debian or similar -

2) Install flashrom , for ubuntu thats :

sudo apt-get install flashrom

3) Run the following, change the path/filename as desired :

flashrom -r ~/joggler/efi.bin

Part B) – Extract the driver file

1)On a PC load the acquired efi.bin into a hex editor.

2)Search for the hex value “f0e5132b”. This identifies the driver file and is at the beginning of a header of length 24 bytes After this header is a further header, 9 bytes of length, after which the driver file data we are interested in follows. The first 3 of this latter 9 bytes is the length of this 9 byte header and the driver file. e.g. 7D2501 (from the openpeak efi). This value is in hex 01257D or in decimal 75133. Subtracting 9 from this gives us 75124, the length of the data we are after. The last of the 9 bytes is the value 01.

3)Select the driver file data starting from the first byte after the 9 byte header (the last byte of which is 01). The length of data to select is as determined above (75124). The very last byte in the selection should be 00, and the following bytes should be FF, if this is not the case its time to re-calculate and try again.

4)Create a new file and copy/paste the selection into it. Save the new file iegd.bin.

5)Run the efidecompress.py tool created above on the saved file creating a new inflated file as follows “./efidecompress.py iegd.bin iegd.bin.decompressed”

6)Open the resulting file ( iegd.bin.decompressed) in the hex editor.

7)Looking in the file you should find the “bitmap” of the logo near the beginning. It starts immediately after the ascii string “$ssd” and spans until the ascii string “ENDSSDATA”

8)There is some amount of empty padding afterwards allowing a slightly larger logo to be used if desired. The maximum space without experimenting with shifting things about is 51597 bytes – or 17199 pixels.

Part C) – Create a new logo/Motiff

1)Create your desired artwork bearing in mind the restraints above (maximum 17199 pixels) and save it as a tiff image uncompressed. It must be 24bit RGB. If you have layers in your design it will probably be saved as 32 bit (with alpha channel).”flatten” the image and save and it should be 24 bit. To help locate image data in the hex editor (next step) it is a good idea to put some pattern you will recognise in the top left and bottom right corners.

2)Open your image in the hex editor and locate the image data. Select it all and verify the length is 3 times the number of pixels in your design. e.g. if your design is 200x80 pixels you should have selected exactly 48000 bytes. Copy the selection to clipboard.

Part D) – Replace the driver files image data

1)Starting at the start of the original image data (immediately after “$ssd”), select as many bytes as you have in your new image. Paste your new image data over the selection – The total filesize should (and must) remain identical. If it does not you may need to work out how to achieve this in your hex editor.

2)I have not verified that this step is necessary – but to conform with the original format you should now append ENDSSDATA immediately after your pasted image data. If your image is smaller and some of the original image data follows it should be zeroed out.

3)Modify the dimensions to suit your new image data. In the text string that ends with “$ssd” are some values, 4 of which determine the offset (x and y) and the dimensions (width and height) of the image. These values are in the order listed here and immediately before the string “$halc”. They are in hex. If you need to make any of them longer by an ascii digit (i.e. 0xF0 becomes 0x105) you can do so, but you probably must subtract the difference from the end of the image data so that the overall file length stays the same. I did exactly this and the result works. (I have yet to experiment with moving the rest of the file to make way for larger (full screen :-) ) logos.

4)Save the file to iegd.bin.decompressed.customised.

5)Compress the file using the Tiano algorithm “eficompress -tTiano iegd.bin.decompressed.customised iegd.bin.decompressed.customised.compressed”

6)Open the result in the hex editor. Select the entire file and copy to clipboard. Also using the checksum tool, make a note of the files 8-bit sum, and also make a note of the file length.


Part E) – Merge the modified driver back into the EFI binary.

1)Going back to the original file efi.bin, the EFI binary, save it as a new file (the one we will customise).

2)From the same position where we originally copied the driver image (33 bytes in from the start of F0E5132B), select the same number of bytes as the length recorded in part D step 6 and paste the copied data over the selection. If your data is shorter than the original you should probably overwrite the remainder of the original with FF's.

3)The Headers each contain a length including themselves of the data they contain. The first header (the 24 byte long one) Contains itself, the 9 byte header, and the compressed driver data, so a field within (starting at offset 21) must contain a value which is equal to the sum of these lengths. The original value is 0x12595. Replace this with the relevant value. The following header starting at offset 25 should contain the same value less 24. the original value is 0x1257D.

4)The 24byte header contains 2 checkums (header checksum and data checksum at offsets 17 and 18) which must now be corrected. The header checksum is of the header data minus the 2 checkum bytes and the 24th byte (0xF8). Zero these all out temporarily and select the 24 byte header. Click the calculate button in the hex editor to obtain the 8 bit checksum and enter the value in the first checksum field (offset 17). The data checksum is of the 9 byte header and the driver data. Select the 9 byte header and click calculate. Add the result to the checksum of the driver data recorded in Part D step 6 and record the result in the data checksum field (offset 18). Now set the 24th byte back to F8.

5)Save the file as efi.customised.bin.

Part F) – Verifying the result.

1)At this stage we have an EFI binary that hopefully works with our customised logo. Flashing this image is not without risks and could (very easily) result in a unit that is “bricked” - read – Does not work – at all!!

2)Using the efidump.py tool we can get a good indication as to whether or not we succeeded in the above. Create a new directory, efi.dumped and cd into it. Now execute ../efidump.py efi.customised.bin.

3)This process should complete without error leaving 116 files in the directory. Pay particular attention to the output regarding the file we modified. (Search your terminal output for 2b13e5).

Part G) – Flashing the result!!

1)A final warning. This process could well leave your unit non-functional. If you are not pre-pared to open your device, and another device and “hotswap” the EFI chips or have an alternative way to re-program flash chips, DO NOT CONTINUE!

2)If you have read http://www.jogglerwiki.info/index.php?title=Recovering_a_bricked_EFI and are comfortable with the procedure, then go right ahead!

3)Transfer the new efi.customised.bin file to usb storage with at least 1meg free space.

4)Boot your joggler with stock firmware and the telnet hack enabled.

5)Load the firmware module “modprobe fh”

6)Flash the new firmware “dd if=/mnt/efi.customised.bin of=/dev/fh bs=1024k”

7)Reboot the unit keeping fingers crossed, with a bit of luck your new artwork will appear on the screen as it boots.