http://blog.sina.com.cn/s/blog_6441e0640100fxgf.html
按:本文译自<Hacking the Kindle part 2: bootloader and firmware updates >,可惜原站点已经无法登录,只能从Google的网页快照来翻译。
启动加载(Bootloader)
Kindle使用的是Das U-Boot加载器,只要在reset后按任意键,就可以进入交互式shell。键入help命令就可以得到下面的命令列表:
KINDLE> help
? - alias for 'help'
badblocks - print OneNAND bad block info
base - print or set address offset
bbm - BBM sub-system
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootf - boot from various options
bootm - boot application p_w_picpath from memory
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
dcache - enable or disable data cache
diags - execute the User Diagnostics from OneNAND
dsleep - sleep USB device controller
dwake - wake USB device controller
echo - echo args to console
erase - erase FLASH memory
exit - exit script
factory - string [lock] [LLL_RR_PP]
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fb - framebuffer subsystem
flinfo - print FLASH memory information
gain - displays/sets the gain value
go - start application at address 'addr'
help - print online help
hsuspend - suspend the 1761 USB host controller
hwake - wake USB host controller
icache - enable or disable instruction cache
iminfo - print header information for application p_w_picpath
itest - return true/false on integer compare
keys - prints out hex values from device keyboard until console key is pressed
kindle - print info about Kindle's revision
load - load OneNAND page into DataRAM
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loop - infinite loop on address range
loopw - infinite write loop on address range
mbboot - boot bootloader from MMC/SC card
md - memory display
mdc - memory display cyclic
mkboot - boot kernel & initrd from MMC/SD card
mm - memory modify (auto-incrementing)
mmcinit - init mmc card
mtest - simple RAM test
mw - memory write (fill)
mwc - memory write cyclic
nand - NAND sub-system
nboot - boot from NAND device
nm - memory modify (constant address)
ohms - calculates board resistance
onenand - print OneNAND register info
opamp - displays/sets the op-amp offset value
otp - dump/read/write OneNAND OTP
printenv- print environment variables
protect - enable or disable FLASH write protection
reboot - alias of reset to match kernel
reset - perform RESET of the CPU
run - run commands in an environment variable
rve - displays/sets the rve (reference voltage error) value
saveenv - save environment variables to persistent storage
serial - set/display board serial number in OTP
setenv - set environment variables
sleep - delay execution for some time
snuz - put PXA to sleep
test - minimal test like /bin/sh
update - update sub-system (updates p_w_picpaths from MMC/SD card to flash)
usb_init - init USB host controller
version - print monitor version
write - write DataRAM buffer to OneNAND page
看一下bbm命令的作用:
KINDLE> ? bbm
bbm format
- format device
bbm open
- open device
bbm eraseall
- erase all blocks
bbm erase 'start' 'end'
- erase blocks from 'start' to 'end'
bbm load p_w_picpath 'id' ['start']
- load p_w_picpath from partition 'id' into RAM;
p_w_picpath is loaded into RAM at location 0xA2000000
or into 'start' if 'start' is specified (in hex)
bbm save p_w_picpath 'id' ['start'] 'size'
- save p_w_picpath of 'size' to partition 'id';
p_w_picpath should be loaded into RAM at 0xA2000000
or into 'start' if 'start' is specified (in hex)
- Partition Info -
bbm show partition
- show partition information
bbm save partition
- save partition information
bbm del partition
- delete last partition
bbm add partition 'id 'attr' 'blocks'
- add partition 'id' of type 'attr' and of size 'blocks'
KINDLE> bbm show partition
<< PARTITION INFORMATION >>
id : Bootloaders, Diagnostics (3)
attr : RW (1)
first_blk : 0 (0x00000000)
no_blks : 12 (1.5 MB)
---------------------
id : Standard Kernel (17)
attr : RW (1)
first_blk : 12 (0x00180000)
no_blks : 12 (1.5 MB)
---------------------
id : Recovery Kernel (16)
attr : RW (1)
first_blk : 24 (0x00300000)
no_blks : 12 (1.5 MB)
---------------------
id : Standard Initrd (15)
attr : RW (1)
first_blk : 36 (0x00480000)
no_blks : 10 (1.3 MB)
---------------------
id : Recovery Initrd (14)
attr : RW (1)
first_blk : 46 (0x005C0000)
no_blks : 10 (1.3 MB)
---------------------
id : Read-only Root Filesystem (8)
attr : RW (1)
first_blk : 56 (0x00700000)
no_blks : 96 (12 MB)
---------------------
id : Default Content (9)
attr : RW (1)
first_blk : 152 (0x01300000)
no_blks : 120 (15 MB)
---------------------
id : Read/Write Root Filesystem (10)
attr : RW (1)
first_blk : 272 (0x02200000)
no_blks : 144 (18 MB)
---------------------
id : Userstore (11)
attr : RW (1)
first_blk : 416 (0x03400000)
no_blks : 1584 (198 MB)
---------------------
id : Environment Variables (4)
attr : RW (1)
first_blk : 2000 (0x0FA00000)
no_blks : 2 (256 KB)
---------------------
U-Boot的诊断镜像的内容保存在第一分区。
有两个内核,一个标准内核,一个还原内核,对应着相应的虚盘。还原内核用于固件的更新。
它有一个只读的根文件系统,和一个读写的部分。默认的分区内容用于恢复出产设置。
还有一个用户存贮分区,对应着用户可以见到的U盘。
没有从闪存拷贝内容到SD/MMC的命令,但是我可以把闪存的内容拷贝到内存,再把它导出。
KINDLE> bbm load p_w_picpath 3
Loading partition "Bootloaders, Diagnostics" into 0xA2000000... Success
KINDLE> base a2000000
KINDLE> md.b 0 100
a2000000: 4e 69 63 6b ff ff ff ff ff ff ff ff ff ff ff ff Nick............
a2000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
a2000020: 0e 00 00 ea 18 f0 9f e5 2c f0 9f e5 18 f0 9f e5 ........,.......
a2000030: 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 ................
a2000040: 60 00 00 a2 20 01 00 a2 80 01 00 a2 e0 01 00 a2 `... ...........
a2000050: 40 02 00 a2 a0 02 00 a2 00 03 00 a2 40 03 00 a2 @...........@...
a2000060: 00 00 0f e1 80 00 c0 e3 00 f0 29 e1 7c 00 9f e5 ..........).|...
a2000070: 21 0a 40 e2 02 0c 40 e2 02 0a 40 e2 0c d0 40 e2 !.@...@...@...@.
a2000080: 70 00 9f e5 70 10 9f e5 00 20 a0 e3 00 20 80 e5 p...p.... ... ..
a2000090: 04 00 80 e2 01 00 50 e1 fb ff ff 1a e6 80 00 ea ......P.........
a20000a0: 00 00 a0 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
a20000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a20000c0: 28 00 1f e5 18 10 90 e5 01 10 81 e3 18 10 80 e5 (...............
a20000d0: 10 10 90 e5 02 1b 81 e2 02 1b 81 e2 0c 10 80 e5 ................
a20000e0: fe ff ff ea ef be ad de ef be ad de ef be ad de ................
a20000f0: 00 00 00 a2 20 00 00 a2 1c 56 06 a2 98 52 4a a3 .... ....V...RJ.
(Nick参考见Nick Vaccaro的Lab126文, 他显然是Kindle 软件的主要开发者, 你好, Nick!)
由于我的线缆和不稳定的终端,我导出的数据超过256字节时,要么返回开始的,要么返回最后的。所以我不得不借助一个小的Python脚本,把数据分成256字节的块导出,再写入到一个文件。每个分区都要写上几个小时,不过最后我终于导出了我想要的东西。在还原内核的initrd镜像部分我发现了执行固件更新的脚本,我转成了刷新的文件(update)格式。
固件更新(fireware updates)
固件更新可以通过手机下载或者通过SD卡和用户的U盘存贮分区来实现。
固件更新文件名必需符合"update*.bin" ,放在用户存贮分区的根目录(Kindle的USB盘)或者放在SD/MMC卡上,只能放成这样。更新文件有一个文件头,而且必需是.tar.gz的更新文件。
版式本的数值是由Kindle的版式本字串组成。在我的机器上是292-Kindle-012138 版本数值为121380292 (12138*10000 + 292).
手动更新除了检查签名和MD5值外,不检查其它任何的域。
干扰(scrambled)算法为:
byte = rol(byte,4)^0x7A;
解扰(descrambled)算法为:
byte = rol(byte^0x7A,4);
tgz文件还要包含名为"update*.dat"的文件.它的每行格式如下:
id md5 filename block_count display_name
id为要写入的分区的ID。我知道的数值如下:
6 基本的只读文件系统(RO fs) (squashfs 镜像)
7 默认内容 (squashfs)
块计数(block_count )为闪存中128k块的序数。(见上面bbm命令显示的分区输出内容)
id为129,被认为是shell的脚步本,是可以执行的.
id为128, 除了做md5校验没有别的用处。
我编了一个Python脚步本来编译我的update文件, 并自动的加上校验值。下一次将会公布。
要进行更新,首先必需把更新文件放在Kindle的USB盘的根目录或者SD/MMC卡上。然后按HOME键,重启Kindle,这样你就会看到下面的菜单:
2、"Firmware Reset" 命令会清除所有的用户定义和设置数据,恢复Kindle的出厂状态。我不肯定如果没有Kndle技术人员另外的初始化是不是能用。
3、"Exit"会开始正常的启动进程。
0(不显示)开始启动加载诊断。交互式的在控制台上,Kindle屏上看不到这些 。
1"Firmware update"开始一个手动的更新进程。