IPMI analysis tools
Switch branches/tags
Nothing to show
Clone or download
devicenull Merge pull request #1 from KickerTom/master
Added support for ASpeed firmware
Latest commit 78423e3 Jan 7, 2015

README.md

ipmi_firmware_tools

Various tools for interacting with (SuperMicro) IPMI firmware blobs.

Firmware using the Winbond WPCM450 controller is supported (pretty standard on the X8 and X9 variants), as well as ASpeed AST2400 controller (common on X10 boards).

  • read_header.py - Given an IPMI firmware image, read throught it and extract all the different parts. This is done by looking for and decoding the image headers used by the bootloader
  • rebuild_image.py - After extracting an image with read_header.py and making changes to the extracted image, this tool will rebuild the image and give you a file that can be flashed to the controller.

Tested:

Not working:

  • X9SCL-F (SMT_X9_315.bin)
  • X9DAX-7F (SMT_X9_331.bin)
  • X10SLD-HF (ASpeed) (SMT_X10_109.bin)
  • X8ST3-F (WPCM450) (X8ST3_204.ima) - This is based on U-Boot 1.1.4

Winbond bootloader

0x0 - 0xfa40 - This is the standard WinBond bootloader, aka "WPCM450 Boot Loader [ Version:1.0.14 ]". This is shared between virtually all X8 and X9 the firmware.

ASpeed nvram

ASpeed firmware does not have bootloader specific part, it has uBoot bootloader referenced in the image footer. On the other hand, it has a part of image starting at offset 0x00100000 and 0x00300000 bytes long, which is described as nvram in the X10 SDK files. In all examined X10 firmwares, this part was always filled with zeroes.

Image footer Winbond

64 bytes total. To find these, read through the file in 64 byte chunks and look for a valid signature string in the correct position. Seriously, this is how the "offical" tools do it.

The actual footer contents look like this:

12 bytes - padding, value does not matter, though it's usually 0xFF
4 bytes - image number, these are usually between 2 and 5.  Image number 0 is reserved for special things, and is never present
4 bytes - base address, this determines where the image starts in the file.  I've noticed these are too big by 0x40000000, though I'm not sure why
4 bytes - load address, the bootloader will copy the image to memory starting at this location
4 bytes - exec address, if this image is to be executed, this is where execution will begin
16 bytes - image name, padded with 0x00
4 bytes - image checksum, this is computed using some strange method.  See FirmwareImage.computeChecksum
4 bytes - signature, this should be \xa0\xff\xff\x9f and is how you recongize an image
4 bytes - type, bitmask controlling what the bootloader does with this image.  See FirmwareImage.IMAGE_*
4 bytes - footer checksum, this is computed using all the preceeding fields (excluding the padding).  Same method as the image checksum

Image footer ASpeed

ASpeed is a bit smarter, there is an "index" block at offsett 0x01FC0000 describing all images stored in the firmware:

text - "[img]: "
hexadecimal number in ascii - image start
hexadecimal number in ascii - image length
hexadecimal number in ascii - image checksum
text - image file name

File footer 1

This appears once in the file. This particular format is used by the older firmware versions (seems to be anything before 3.00)

ATENs_FW - string, this is how you find the footer
1 byte - integer, firmware major version
1 byte - integer, firmware minor version

File footer 2

Again, this appears only once in the file. This particular format is used by the newer firmware (> 3.00)

ATENs_FW - string
1 byte - integer, firmware major version
1 byte - integer, firmware minor version
0x71 - constant, helps you find the footer
4 bytes - crc32 of all image blocks.  To find this, calculate the crc32 of each image data block.  Concatenate the raw values of all of them (in order by image number), and take the crc32 of that
0x17 - constant, helps you find the footer

File footer 3

Used in ASpeed firmwares. Extension to version 2 above.

ATENs_FW - string
1 byte - integer, firmware major version
1 byte - integer, firmware minor version
4 bytes - string, upper part of rootfs checksum
4 bytes - string, upper part of rootfs length
0x71 - constant, helps you find the footer
4 bytes - string, upper part of webfs checksum
4 bytes - string, upper part of webfs length
0x17 - constant, helps you find the footer