Bootloader appears to be generated by 'Intel(R) Consumer Electronics Firmware Development Kit (Intel(R) CEFDK)', or CEFDK Bootloader.
This resides on the first 64KB or so of flash, which is only accessible via ioctl calls. See Boot Process for more details.
Analyzing nand block8 as dumped by the tool on the nandflash page:
$ $ hexdump -e '"%07_ax " 4/4 " %08x" "\n"' dump8.datå // with selected bits cut out
0000000 00000006 000000a1 00010000 80000001
0000010 00008086 20070514 00003f41 00000040
0000020 00000040 00000001 00000580 00000480
0000030 00000000 00000000 00000000 00000000
*
0000090 00000000 d3059537 77460601 f1a9598d // probably an RSA sig (used for what?)
00000a0 27072956 e44bf0e9 9ea5d817 589c7a88
00000b0 81a31d75 b15b1394 f3e44b69 b3eaf5ac
00000c0 6cfecfe6 7d9c511f 60422cd9 066e6e24
00000d0 c03a2baa 12d842cd 0a8cea9e f881740d
00000e0 6add0c37 8fca4f85 13a1c175 4f1348ad
00000f0 cb3feaa6 885c337d a9a92cf3 fb61e843
0000100 b1070e63 4ff25ddf c19ca67f af17be75
0000110 8008c01e e872456c 4a8d9e5d 07099d64
0000120 fe645a18 71384df3 c735c513 9435a16e
0000130 6f4cea33 600bc386 8cd9479a 2623cee3
0000140 adc1d36d e1422afd ae484ea3 66a6e182
0000150 8da159e1 66b2cd88 a92ce384 2edd6a39
0000160 3b99d0eb 536e9bf9 b2288900 e5cbd1dd
0000170 6d5f5f5d f6981ce8 f5a2c5e6 2284d2a2
0000180 4bca3fb3 d68f41e4 aff1ea30 1484d7db
0000190 47968cb1 00010001 00000000 00000000 // modulus = 0x10001 (65537)
00001a0 00000000 00000000 00000000 00000000
*
0x480 to 0x580 is likely a signature to be verified with the above key as the data here is completely different in my dump8.dat and in hdisk1/DMS4110/nandflash_v1.4.0/v1.4.0_CEFDK.bin.signed found in dlink_boxee_rma.img.
In hdisk1/DMS4110/nandflash_v1.4.0/v1.4.0_CEFDK.bin the key at 0x94 to 0x198 is all zeros, as is 0x480 to 0x580, otherwise the two versions of v1.4.0_CFDK.bin are identical.
0x580 appears to be where the real bootloader x86 code exists.
Guess what's at 0xfff0?
$ dd if=dump8.dat bs=1 skip=0xfff0 count=5 | ndisasm -
5+0 records in
5+0 records out
5 bytes transferred in 0.000030 secs (166441 bytes/sec)
00000000 EA800500F0 jmp word 0xf000:0x580
In other words, a jump to our 0x580.
0xfff0 happens to be the reset vector on x86, in other words the address of the first instruction executed after a reset.
We can run the cefdk boot loader with the help of Bochs after extracting it:
$ dd if=dump8.dat of=cefdk.dat count=0x10000 bs=1
$ bochs 'romimage: file=cefdk.dat'
Of course the CEFDK will have to be loaded from nand-flash first which is done somewhere else possibly together with the previously mentioned signature test.
Bootloader signature verification
Thanks to the tool "/bin/bootblockverifier" in the rma image, we now know how exactly how the key and signature are used to verify the boot block. Please see this piece of Go code.
Unknown at the moment whether this would allow a custom boot loader to boot up as I'm too scared of bricking my boxeebox by trying to change it ;)
Relevant strings from bootloader:
GOOD
Genu
ineI
ntel
Verify stage2 FAIL
Verify stage2 PASS
,:Intel Lincroft SCH Microcode Version 000.064d:00000000:Apr 28 2009
:10:46:28
;ASTEP=def;
LGI_POWER_OVER_RIDE=def;
ENABLE_DDR_RCOMP=def;
USE_DRAM_RDY=def;
CSTATE_TIMINGS=undef;
DPSLP_INVERSION=undef;
LAB_DEBUG_MESSAGES=undef;
ENABLE_DDR_RCOMP=def;
CSTATE_TIMINGS=undef;
CLK_RATIO_12_TO_1=undef;
CEFDK - Production Release %s
core : %s
cs_gen4 : %s
MemType : DDR2
MemType : DDR3
MemSpeed : 800
MemSpeed : 1066
MemSpeed : 1333
MemSpeed : 1600
MemSpeed : Unknown
Channels Enabled :
Channel Mode :
Hit a key to start the shell...
Attempting to boot Linux from NAND ...
DENALI_FTL_Page_Read FAIL at 0x%X.
Kernel not found at 0x%X block in NAND.
-----fail read block=%d addr=0x%x
console=ttyS0,115200 root=/dev/ram0 rw mem=exactmap memmap=1M\$0 memmap=639M@1M
console=ttyS0,115200 ramdisk_size=153600 root=/dev/ram0 rw mem=exactmap memmap=1M\$0 memmap=639M@1M
CE4100 Stepping:
Unknown revision
Board: GoldenBeach:
Board: ChesapeakeBay
Board: FalconFalls
Board: PowerHouseLake
Version Information -
Memory configuration -
Linear
Interleave Mode 1
Interleave Mode 2
All A/V devices use IRQ 4.
*** Recovery ***
*** RMA ***
--- Normal ---
*** Normal ***
Can't PP Block #%d
PP Checksum fail %x %x
=== Upgrade(%d) ===
FTL Lite read MAC data fail.
FTL Lite initialized failed
Use Recovery Now ...
Load Kernel done.
Load Initrd done.
Use RMA Now ...
fail read block=%d addr=0x%x
Shell exit
Please restart the board
CE4100 4.020-DSM380 v1.8.0
0606
0606
0606
bad reg address
bad dev address
success
not initialized
bad op type
tx empty timeout
rx full timeout
unknown error %d
!!! I2C WR: *%08x=%08x
!!! *retData=0x%x
I2CWaitRxFull
I2CWaitTxEmpty
!!! IN %s: stop=%d ISR=0x%08x mask=%08x rwm=%08x
!!! EXIT(%d) %s: count=%d ISR=0x%08x mask=%08x rwm=%08x
!!! EXIT(%d) %s: count=%d ISR=0x%08x mask=%08x rwm=%08x toTick=%08x%08x roll=%08x%08x procTicks=%08x%08x
!!! IN %s: stop=%d op=%d ISR=0x%08x mask=%08x rwm=%08x
Usage:
i2c 0|1|2 <I2C dev 7bit addr> [<PCI bus> <dev> <fun>]
i2c r[ead] [<bytes> [<dest addr>]] | w[rite] <byte value> [<val2> <val3> ...]]
i2c w 0x4 1 0 0 0xff 0 0 0 0 0 0 0 0
i2c r
Error: First do: %s <bus> <dev addr>
Bad arg.
Usage: i2c r[ead] [<bytes> [<buffer addr>]]
Bad arg.
Usage: i2c w[rite] <byte value> [<val2> <val3> ...]
I2C buses read and write (SV ver).
i2c d[ebug]
[<debug msg level: 0|1|2>]
Example:
i2c 2 0x44
STATUS:
I2C Bus: %s
%d (0x%x)
I2C Dev: %s
PCI: 0x%x.%x.%x
Bad byte count %d need >0
0x%02x%s
I2C error: %s (%d)
Read %d bytes
I2C DEBUG @ %d
BAR%d: %08X
ICR_%d %08X
ISR_%d %08X
(ISAR_%d %08X)
IDBR_%d %08X
(ICCR_%d %08X)
IBMR_%d %08X
IWCR_%d %08X
ISMSCR_%d %08X
ISMLCR_%d %08X
IFMSCR_%d %08X
IFMLCR_%d %08X
IDDS_RATE_LB%d %08X
IDDS_RATE_UB%d %08X
Unknown arg.
writeCount = 0x%X
Done
Erasing block at 0x%x
Data = 0x%08X
Rounding up copy size to an erase boundary.. Copy Size = 0x%x
Burning the flash using the write buffer
bootkernel
Usage: bootkernel.
root=/dev/ram
Boot Linux kernel from NAND flash block %d...
DENALI_FTL_Page_Read FAIL at 0x%X.
Error booting Linux: Invalid or missing kernel at block 0x%X.
Error booting Linux: Invalid or missing initrd.
Boot Linux kernel from NAND flash.
console=ttyS0,115200 root=/dev/ram0 mem=exactmap memmap=255M@1M
Usage:
address of src buffer
size of src buffer
MD5 sum:
%02x
md5 <src> <size> -Calculate MD5.
Calculate a MD5 sum for an input data string.
Invalid or missing initrd.
mem=
Error: No room in IRQ table to add entry for device %02x:%02x:%02x
pciIsBridge(bus, dev, func)
pci_alloc.c
Assert failed at %s:%d (%s)
Error: Link %d for PCI device %X:%X:%X exceeds maximum (%d)
Intel(R) Consumer Electronics Firmware Development Kit (Intel(R) CEFDK)
Copyright (C) 1999-2010 Intel Corporation. All rights reserved.
Build Time (%s).
07/09/10 16:18:43
{%x}
exit
help
%10s - %s
reset
shell>
Error: Missing ".
Error: Invalid command.
Displays this screen.
Stops the shell.
Error: Unable to open redirection file: '%s'.
Invalid %s: '%s'