After downloading many different firmwares, I tried to understand how they were structured to build my own. After some days of hacking and a little headache, I can provide the almost-complete format for the firmware used in BroadCom96345
First, here are some links to firmware images :
A firmware image is generally
made of 3 parts : a header, a root filesystem, and a kernel image. But the SE515 firmware had 4 parts : a header, a kind of loader, a root filesystem and a kernel image. By analyzing very closely this image, I could finally understand one thing : a firmware image isn't directly copied into the flash memory of the router. In fact, the header is just a "summary", depicting the size of the following parts, and the address at which they should be flashed. In other firmwares, the "loader" part is absent, probably because it's not useful to modify it. I don't know why it exists in the SE515 ; maybe they really needed to update the loader, maybe they just forgot to remove this section.
The header is 256-bytes long. It's made of null-terminated strings and a couple of checksums. When I mention "a 20-bytes string", that means like char string;
in C ; i.e. if the string is shorter than 20 bytes, it will be padded with 00 bytes.
- a 4-bytes magic number, 36 00 00 00 in all my firmwares (it might rather be a version number)
- a 20-bytes string, generally "Broadcom Corporation" (but some vendors did set this string to spaces)
- a 20-bytes string, generally "Firmware version 1.0" (sometimes erased, too)
- a 16-bytes string, maybe the router model ("96345GW", "96345R", "RTA230"...)
- a 2-bytes string, "1" each time (that is, 31 00)
2005-03-19 Heinz Peter Hippenstiel
I was analysing the Broadcom sources and flashed a vanilla Broadcom image to my SE515. It was moaning about the wrong board-id when I was trying to reflash my other selfmade images from the Broadcom web interface. A little analysis brought up that the header is a little different:
- a 20-bytes string, the vendor name "Broadcom Corporation" (but some vendors did set this string to spaces)
- a 14-bytes string, the fw version "Firmware version 2.0" (sometimes erased, too)
- a 6-bytes string, the board id "6345" (or "6348" for newer chips, may be blank)
- a 16-bytes string, the router model ("96345GW", "96345R", "RTA230" ... I expect this is a must have)
Then there is the size/address part. Each number is written as-is, as a decimal string ; sizes are 10-bytes strings, and adresses are 12-bytes strings. For instance, size 1234 will be encoded as 31 32 33 34 00 00 00 00 00 00
- the size of the image, without the header (that is, file size minus 256)
- the address at which the loader should be flashed (0xBFC00000?)
- the size of the loader
- the address at which the root filesystem should be flashed (was always 0xBFC10100)
- the size of the root filesystem
- the address at which the kernel filesystem should be flashed (was always root filesystem address + root filesystem size)
- the size of the kernel
If a part should not be flashed, both size and address will be 0 (that's the case of the loader part in most firmwares ; I didn't see yet a firmware without kernel or filesystem part, but I bet it's possible). The size of the image will always be equal to the sum of the sizes of the other parts.
After this part there's nothing until the last 40 bytes of the header ; byte 216 to 219 will be the data checksum (from byte 256 to the end of the file), and byte 236 to 239 will be the header checksum (from byte 0 to byte 235). The checksums are regular CRC32 checksums, but with all bits flipped.
The loader in the SE515 firmware seems to be a CFE bootloader ; I don't know much about it, but you can download CFE sources somewhere and have a look if you want. I don't know if other routers use CFE too, but I think it's the case, and I will try to find a way to extract the loader part of my router to check.
It's just a filesystem image "as-is".
I did not yet succeed into cross-compiling a MIPS kernel, so I can't compare to tell if it's a regular kernel or if it's mangled somehow.
I bet that the checksums are here to be validated by the "upload firmware" program. After all, there's no point into flashing a checksum itself, because once you have flashed and verified an image, it won't change by tomorrow :-)
The Flash memory seems to be mapped at 0xBFC00000. The fact that the root filesystem flash address is 0xBFC10100 means that it should be possible to flash a loader-less firmware straight at 0xBFC10000, but I don't know if it's a pure coincidence or if it's on purpose.