Preliminary information
The
Broadcom96345 used in the 9106 uses the CFE bootloader (or a variant of it) ; at least, it's a ~64K loader, with a
CFE1CFE1 signature near the beginning, and it has a
e=192.168.1.1:ffffff00 h=192.168.1.100 g= r=f f=vmlinux i=bcm96345_fs_kernel d=1 parameter string, too.
The CFE bootloader has some interesting symbols in it :
"strings -8" output of the CFE bootloader on my 9106
CFE1CFE1
CFE1CFE1
e=192.168.1.1:ffffff00 h=192.168.1.100 g= r=f f=vmlinux i=bcm96345_fs_kernel d=1
PANIC: out of memory!
!Error allocating memory for LitDecoder m_Coders!
Error in allocating memory for reverseBitTreeDecoder2!
!Error in allocating memory for bitTreeDecoder!
Error in allocating memory for reverseBitTreeDecoder!
CodeReal: invalid data
The last strings are from the LZMA decompression code used by the custom CRAMFS in the kernel. This code has interesting
#ifdef _CFE directives, which seems to confirm that the CFE bootloader includes a LZMA decompressor, and that the source code is just right there (but again, some files might be missing ; because the code also includes some
#ifdef _HOST_TOOL, probably to generate the LZMA-CRAMFS images, but there's no host tool source around).
The LZMA Kernel
I compare here the first bytes of two kernels :
$ hexdump -C 910*HIP*kernel
00000000 80 01 00 00 80 01 04 6c 00 06 0f a1 5d 00 00 40 |.......l...¡]..@|
00000010 00 00 00 6f fd ff ff 80 37 9a 11 2b 84 36 a9 8d |...oýÿÿ.7..+.6©.|
00000020 ec 30 ee 88 2a c0 0f 0e 29 f8 ae f5 53 93 9b 51 |ì0î.*À..)ø®õS..Q|
00000030 c3 d6 e6 61 4a 47 1b 84 38 7c 99 80 c4 c2 3b 18 |ÃÖæaJG..8|..ÄÂ;.|
00000040 c8 56 22 93 68 a1 bd 7c 12 fa 3d 3c 66 70 61 a3 |ÈV".h¡½|.ú=<fpa£|
00000050 cd 4a bf 0b b8 4a 11 87 d7 87 17 d7 a1 57 8f 9e |ÍJ¿.¸J..×..סW..|
00000060 d0 06 49 7c ec e9 74 f0 ae cb 6e 2f cc 65 74 1c |Ð.I|ìétð®Ën/Ìet.|
$ hexdump -C 9105_USR96345R_Release2.1.bin*kernel
00000000 80 01 00 00 80 01 04 6c 00 05 fb 0f 5d 00 00 40 |.......l..û.]..@|
00000010 00 00 00 6f fd ff ff 80 37 9a 11 2b 84 36 a9 8d |...oýÿÿ.7..+.6©.|
00000020 ec 30 ee 88 2a c0 0f 0e 29 f8 ae f5 53 93 9b 51 |ì0î.*À..)ø®õS..Q|
00000030 c3 d6 e6 61 4a 47 1b 84 38 7c 99 80 c4 c2 3b 18 |ÃÖæaJG..8|..ÄÂ;.|
00000040 c8 56 22 93 68 a1 bd 7c 12 fa 3d 3c 66 70 43 da |ÈV".h¡½|.ú=<fpCÚ|
00000050 4c 0d ad 9d 81 09 e8 98 b8 08 05 ff 60 8e e3 4f |L....è.¸..ÿ`.ãO|
00000060 57 bf ba 76 c4 26 c2 6d 20 99 7e e3 64 8e 45 b7 |W¿ºvÄ&Âm .~ãd.E·|
The highlighted values are a header :
0x80010000 is the address at which the decompressed kernel should be loaded ;
0x8001046C is the address of the
kernel_entry symbol (at which the bootloader should jump after decompressing the kernel) ; and the next 4 bytes are the size of the compressed kernel minus 12 bytes. Saying it differently : it's the number of remaining bytes in the file.
The compressed data can then be handled with standard LZMA decompression routines (actually, I used the
pylzma package, and ran the remaining of the file thru the
uncompress routine, and it worked).
The uncompressed kernel
The uncompressed kernel is a kind of "flat binary" ; to obtain it, run
mips-linux-objcopy -O binary vmlinux vmlinux.bin at the kernel source top level directory after the compilation.
vmlinux should be in ELF format, and
objcopy -O binary will convert it in the correct format. You can check in the
System.map that the kernel starts at
0x80010000 and that the
kernel_entry symbol is at
0x8001046C.
To compress the "binary" kernel, the
compress routine of the
pylzma package should work ; to be on the safe side, we should specify a dictionary order of 22. The kernels I have use 22 ; and the LZMA default is 23.