Kindle4: 编译bootloader – u-boot

Kindle4是美国亚马逊出的一款电子书产品,其特点是使用EInk作为显示设备,耗电小,充一次电可以用很长一段时间。

CPU: Freescale iMX508, ARM Cortex-A8 core, 800MHz

RAM: 256MB Hynix H5MS2G22AFR Mobile DDR SDRAM

Display: EInk 6-inch, 600×800 x 4bits

USB: USB 2.0, micro-B connector

Buttons:  reset,  4-way button + 1 center, Left Page up & down, Right Page up & down

Storage: 2GB EMMC

WLAN: Atheros AR6103 802.11b/g/n

Battery: 3.7v, 1800mAH with fuel gauge

  • 代码下载
  1. http://www.amazon.com/gp/help/customer/display.html?nodeId=200203720
  2. https://kindle.s3.amazonaws.com/Kindle_src_4.0_1308590058.tar.gz
  3. http://kindle.s3.amazonaws.com/Kindle_src_4.1.3_2692310002.tar.gz
  • u-boot 2009.08源码

4.0与4.0.1 代码相同, 而4.1.0、4.1.1和4.1.2代码相同。简单看一下它们之前文件有什么区别:

$ git diff --stat 4.0 4.1.3
 Makefile                                     |   6 +
 board/imx50_yoshi/imx50_yoshi.c              |  12 +-
 board/imx50_yoshi/ram_init.S                 | 525 +++++++-----------------------------------------------
 config.mk                                    |   2 +-
 include/asm-arm/arch-mx50/mx50_yoshi_board.h |  94 ++++++++++
 include/configs/imx50_yoshi.h                |   4 +
 include/configs/imx50_yoshime.h              | 235 ++++++++++++++++++++++++
 include/configs/imx50_yoshime_bist.h         | 316 ++++++++++++++++++++++++++++++++
 post/board/imx50_yoshi/inventory.c           | 156 ++++++++++++++++
 9 files changed, 881 insertions(+), 469 deletions(-)

新代码加入了yoshime项目的代码。看起来kindle的开发代码都是以鸡尾酒命名,像之前的tequla, 以及当前的yoshi与yoshime。

  • 相关工具

这里包含大量的工具软件:http://wiki.mobileread.com/wiki/Kindle_Tools_Index, 其中我们可能会用到:

  1. fastboot – http://www.mobileread.com/forums/showthread.php?t=174923
  2. imx_usb_loader – http://www.mobileread.com/forums/showthread.php?p=2185626#poststop
  3. select boot for Kindle4 & Touch – http://www.mobileread.com/forums/showthread.php?p=2185626#poststop
  4. toolchain – arm-eabi-4.6:  https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/

NOTE: toolchain需要选择arm-eabi-4.6, commit id: d73a051,否则编译出来的u-boot USB/fastboot可能不起作用。

  • 编译u-boot代码(4.1.3)

在ubuntu 14.04 x86_64系统下编译。u-boot代码使用的是4.1.3版本的:

$ cd ~/imx/arm-eabi-4.6/bin && export PATH=`pwd`:$PATH
$ cd ../u-boot-2009.08
$ CROSS_COMPILE=arm-eabi- ARCH=arm TYPE=prod make imx50_yoshi_config
Configuring for imx50_yoshi board...
$ CROSS_COMPILE=arm-eabi- ARCH=arm TYPE=prod make

编译出来的是用来加载Linux kernel的u-boot,其实还有一个bist(builtin self test)的u-boot, 需要在编译的时候指定TYPE=bist, 具体编译指令如下:

$ CROSS_COMPILE=arm-eabi- ARCH=arm TYPE=bist make imx50_yoshi_bist_config
Configuring for imx50_yoshi_bist board...
$ CROSS_COMPILE=arm-eabi- ARCH=arm TYPE=bist make
  • 分区表信息

eMMC包含这几个物理分区:rpmb, boot0, boot1, mmcblk0

[    0.873365] mmcblk0: mmc0:0001 SEM02G 1.82 GiB 
[    0.883649] mmcblk0boot0: mmc0:0001 SEM02G partition 1 1.00 MiB
[    0.886841] mmcblk0boot1: mmc0:0001 SEM02G partition 2 1.00 MiB
[    0.893357] mmcblk0rpmb: mmc0:0001 SEM02G partition 3 128 KiB

从include/asm-arm/arch-mx50/mx50_yoshi_board.h中可以看到bootloader存放在boot0分区中,大小为376KB。同时prod类型的uboot在这块分区最开始的120KB,而bist类型的uboot在紧接着的256KB, userdata分区则在0x3f000(252KB)开始的5K字节:

boot0(1MB)
bootloader(376KB)  HOLDER – 648KB
u-boot – prod (120KB) u-boot – bist(256KB)
HOLDER – 132KB userdata(5KB)

编译出来的u-boot – prod只有64KB,而编译出来的u-boot – bist只有117KB, userdata不会被覆盖。在修改u-boot代码的时候要小心,不要超过了限制。

我们再看一下mmcblk0(userpartition)的布局:

mmcblk0(1.82GB)
mbr(1KB) kernel(14MB) diags_kernel(14MB) system(350MB) diags(64MB) data – ~1.4GB
       HOLDER(0x41000:260KB)
  • 加载地址

由board/imx50_yoshi/config.mk可以看到:

ifeq ($(TYPE),prod)
LDSCRIPT := $(SRCTREE)/board/$(VENDOR)/$(BOARD)/u-boot.lds

TEXT_BASE = 0xF8007000
else
LDSCRIPT := $(SRCTREE)/board/$(VENDOR)/$(BOARD)/bist.lds

TEXT_BASE = 0x79800000
endif

u-boot – prod加载位置在0xF8007000, 而u-boot – bist的加载位置在0x79800000

而256MB DDR RAM所在的地址应该是0x70000000 ~ 0x7FFFFFFF。

  • 相关log

NOTE: 可能需要1.8v的TTL串口线才能看到串口log及对串口进行操作。

1. u-boot开机log:

U-Boot 2009.08-lab126 (Sep 22 2011 - 21:33:57)

CPU:   Freescale i.MX50 family 1.1V at 800 MHz
mx50 pll1: 800MHz
mx50 pll2: 400MHz
mx50 pll3: 216MHz
ipg clock     : 50000000Hz
ipg per clock : 50000000Hz
uart clock    : 24000000Hz
ahb clock     : 100000000Hz
axi_a clock   : 400000000Hz
axi_b clock   : 200000000Hz
weim_clock    : 100000000Hz
ddr clock     : 800000000Hz
esdhc1 clock  : 80000000Hz
esdhc2 clock  : 80000000Hz
esdhc3 clock  : 80000000Hz
esdhc4 clock  : 80000000Hz
MMC:  FSL_ESDHC: 0, FSL_ESDHC: 1
Board: Tequila
Boot Reason: [POR]
Boot Device: MMC
Board Id: 0031501114259ZUJ
S/N: B00E15101255040P
Initing MDDR memory
ZQ calibration complete: 0x128=0x06090010 0x12C=0x00000508
DRAM:  256 MB
Using default environment

In:    serial
Out:   logbuff
Err:   logbuff
Quick Memory Test 0x70000000, 0x10000000
POST done in 13 ms
Hit any key to stop autoboot:  0 

2. u-boot – prod所支持的命令,在出现Hit any key to stop autoboot时输入任意字符进入交互模式:

Hit any key to stop autoboot:  0 
uboot > help
?       - alias for 'help'
bist    - start Built In Self Test
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
go      - start application at address 'addr'
help    - print online help
idme    - idme    - Set nv ram variables


log     - manipulate logbuffer
printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
setenv  - set environment variables
version - print monitor version

3. 进入u-boot – bist交互模式,在当前模式下运行bist命令:

uboot > bist


U-Boot 2009.08-lab126 (Sep 22 2011 - 21:34:10)

CPU:   Freescale i.MX50 family 1.1V at 800 MHz
mx50 pll1: 800MHz
mx50 pll2: 400MHz
mx50 pll3: 216MHz
ipg clock     : 50000000Hz
ipg per clock : 50000000Hz
uart clock    : 24000000Hz
cspi clock    : 54000000Hz
ahb clock     : 100000000Hz
axi_a clock   : 400000000Hz
axi_b clock   : 200000000Hz
weim_clock    : 100000000Hz
ddr clock     : 200000000Hz
esdhc1 clock  : 80000000Hz
esdhc2 clock  : 80000000Hz
esdhc3 clock  : 80000000Hz
esdhc4 clock  : 80000000Hz
MMC:  FSL_ESDHC: 0, FSL_ESDHC: 1
Board: Tequila
Boot Reason: [POR]
Boot Device: MMC
Board Id: 0031501114259ZUJ
S/N: B00E15101255040P
I2C:   ready
DRAM:  256 MB
Using default environment

In:    serial
Out:   serial
Err:   serial
POST done in 2 ms
Battery voltage: 3084 mV

Battery voltage too low.  Please plug in a charger
Battery voltage: 3084 mV
USB speed: HIGH
Connected to USB host!
USB configured.

由于电池电量太低,进入充电模式了。当电池电量到达一定程度之后,会自动进入交互模式:

helio > help
?       - alias for 'help'
autoscr - DEPRECATED - use "source" command instead
base    - print or set address offset
bist    - start Built In Self Test
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
check   - perform MMC CRC32 check
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
diag    - perform board diagnostics
echo    - echo args to console
fail    - fail blink fail pattern on LED
fastboot- Fastboot
fdt     - flattened device tree utility commands
fstor   - File Storage
go      - start application at address 'addr'
halt    - halt board
help    - print online help
i2c     - I2C sub-system
idme    - idme    - Set nv ram variables

iminfo  - print header information for application image
itest   - return true/false on integer compare
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
loopw   - infinite write loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - mmcinfo <dev num>-- display MMC info
mtest   - simple RAM read/write test
mw      - memory write (fill)
nm      - memory modify (constant address)
ocotp   - OCOTP sub system
panic   - panic halt
pass    - pass blink pass pattern on LED
pmic    - pmic    - PMIC utility commands

printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
setenv  - set environment variables
sleep   - delay execution for some time
source  - run script from memory
sspi    - SPI utility commands
version - print monitor version

可以看到bist中的命令要比prod中的要多很多。

  • 写入自编译u-boot

我们知道kindle4开机之后,首先会去执行u-boot – prod,而u-boot – prod默认情况下会去加载并运行kernel, 我们又知道kernel的位置在mmcblk0中0x41000开始的16MB空间中。同时我们知道u-boot – bist会被加载到0x79800000开始的一段内存中。那么我们能不能在mmcblk0中,在0x41000开始的一块区域中放置u-boot – bist呢。下面我们来试试看:

1. 使用tools/mkimage创建一个fake的linux kernel,以便u-boot能够正确识别与加载:

$ tools/mkimage -A arm -O linux -T kernel -C none -a 0x79800000 -e 0x79800000 -n 'u-boot - bist' -d u-boot.bin u-boot-bist
Image Name:   u-boot - bist
Created:      Wed Mar 16 23:24:30 2016
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    119600 Bytes = 116.80 kB = 0.11 MB
Load Address: 79800000
Entry Point:  79800000

2. 在bist中执行fastboot命令使kindle4进入fastboot模式:

bist > fastboot 
Entering fastboot mode...
Battery voltage: 3960 mV
USB speed: HIGH
Connected to USB host!
USB configured.

3. 使用fastboot将u-boot-bist写入到kernel分区中:

$ ./fastboot devices
0031501114952ZUJ	fastboot
$ ./fastboot flash kernel u-boot-bist 
downloading 'kernel'...
OKAY [  0.006s]
writing 'kernel'...
OKAY [  0.022s]
finished. total time: 0.029s

4. 通过fastboot命令重启:

$ ./fastboot reboot
rebooting...

finished. total time: 0.000s

使用fastboot命充进行reboot之后,可以在串口中看到如下log:

resetting ...


U-Boot 2009.08-lab126 (Sep 22 2011 - 21:33:57)

CPU:   Freescale i.MX50 family 1.1V at 800 MHz
mx50 pll1: 800MHz
mx50 pll2: 400MHz
mx50 pll3: 216MHz
ipg clock     : 50000000Hz
ipg per clock : 50000000Hz
uart clock    : 24000000Hz
ahb clock     : 100000000Hz
axi_a clock   : 400000000Hz
axi_b clock   : 200000000Hz
weim_clock    : 100000000Hz
ddr clock     : 800000000Hz
esdhc1 clock  : 80000000Hz
esdhc2 clock  : 80000000Hz
esdhc3 clock  : 80000000Hz
esdhc4 clock  : 80000000Hz
MMC:  FSL_ESDHC: 0, FSL_ESDHC: 1
Board: Tequila
Boot Reason: [POR]
Boot Device: MMC
Board Id: 0031501114259ZUJ
S/N: B00E15101255040P
Initing MDDR memory
ZQ calibration complete: 0x128=0x06090010 0x12C=0x00000508
DRAM:  256 MB
Using default environment

In:    serial
Out:   logbuff
Err:   logbuff
Quick Memory Test 0x70000000, 0x10000000
POST done in 13 ms
Hit any key to stop autoboot:  0 
## Booting kernel from Legacy Image at 70800000 ...
   Image Name:   u-boot - bist
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    119600 Bytes = 116.8 kB
   Load Address: 79800000
   Entry Point:  79800000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
Starting kernel ...


U-Boot 2009.08-lab126 (Mar 16 2016 - 23:08:00)

CPU:   Freescale i.MX50 family 1.1V at 800 MHz
mx50 pll1: 800MHz
mx50 pll2: 400MHz
mx50 pll3: 216MHz
ipg clock     : 50000000Hz
ipg per clock : 50000000Hz
uart clock    : 24000000Hz
cspi clock    : 54000000Hz
ahb clock     : 100000000Hz
axi_a clock   : 400000000Hz
axi_b clock   : 200000000Hz
weim_clock    : 100000000Hz
ddr clock     : 200000000Hz
esdhc1 clock  : 80000000Hz
esdhc2 clock  : 80000000Hz
esdhc3 clock  : 80000000Hz
esdhc4 clock  : 80000000Hz
MMC:  FSL_ESDHC: 0, FSL_ESDHC: 1
Board: Tequila
Boot Reason: [POR]
Boot Device: MMC
Board Id: 0031501114259ZUJ
S/N: B00E15101255040P
I2C:   ready
DRAM:  256 MB
Using default environment

In:    serial
Out:   serial
Err:   serial
POST done in 1 ms
Battery voltage: 3941 mV

bist > 

可以看到自编译的u-boot – bist被正常加载并运行了。

《Kindle4: 编译bootloader – u-boot》有6个想法

    1. 有WiFi芯片的那一面,右边标记P2的那个没有焊接的接口,3个PIN, 最上面那个是GND

    2. http://ereadertech.com/2011/09/29/kindle-4-disassembly-part-i/
      http://ereadertech.com/2011/10/01/kindle-4-disassembly-part-ii/

发表评论

电子邮件地址不会被公开。 必填项已用*标注