http://blog.sina.com.cn/s/blog_6441e0640100fxgf.html

 

按:本文译自<Hacking the Kindle part 2bootloader 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--第二部分:启动加载和固件的更新_第1张图片

版式本的数值是由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,这样你就会看到下面的菜单:

破解kindle--第二部分:启动加载和固件的更新_第2张图片

2、"Firmware Reset" 命令会清除所有的用户定义和设置数据,恢复Kindle的出厂状态。我不肯定如果没有Kndle技术人员另外的初始化是不是能用。

3、"Exit"会开始正常的启动进程。

0(不显示)开始启动加载诊断。交互式的在控制台上,Kindle屏上看不到这些 。

1"Firmware update"开始一个手动的更新进程。