tl-wr802n v1: 编译bootloader: tuboot.bin

开发所使用的系统为ubuntu-14.04 x86_64

  • 从openwrt官网下载gcc toolchain

https://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2

解压并将gcc加入到PATH中:

$ tar -xvf OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar.bz2
$ cd OpenWrt-SDK-15.05-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin
$ export PATH=`pwd`:$PATH
  • 从tp-link官网下载GPL code

http://www.tp-link.com/resources/gpl/TL_WR802NV1_GPL.rar

从中取得uboot源码:

$ unrar x TL_WR802NV1_GPL.rar 
$ cd TL_WR802NV1_GPL/soho5_qca_trunk_prep/ap143/boot/u-boot/
  • 配置编译环境:
$ export CROSS_COMPILE=mips-openwrt-linux-
$ COMPRESSED_UBOOT=1 \
    CFG_BOARD_TYPE=ap143-2.0 \
    ETH_CONFIG=_s27 \
    FLASH_SIZE=4 \
    FW_RECOVERY=y \
    FW_RECOVERY_DEV=wr841nv10 \
    FW_INPUT_BUTTON_GPIO=12 \
    FW_OUTPUT_LED_GPIO=3 \
    FW_OUTPUT_LED_ON=0 \
    make distclean
$ rm -rf include/asm
$ chmod +x mkconfig

$ COMPRESSED_UBOOT=1 \
    CFG_BOARD_TYPE=ap143-2.0 \
    ETH_CONFIG=_s27 \
    FLASH_SIZE=4 \
    FW_RECOVERY=y \
    FW_RECOVERY_DEV=wr841nv10 \
    FW_INPUT_BUTTON_GPIO=12 \
    FW_OUTPUT_LED_GPIO=3 \
    FW_OUTPUT_LED_ON=0 \
    make ap143-2.0_config

打开Makefile, 将231行的LZMA修改成如下:

#LZMA = $(BUILD_DIR)/util/lzma
LZMA = $(shell which lzma) #$(BUILD_DIR)/../util/lzma/bin/lzma

[2016-01-23 22:34:31]

LZMA要使用TL_WR802NV1_GPL.rar/soho5_qca_trunk_prep/util/lzma/bin/lzma,不然编译出来的bootloader可能会无法启动。将lzma修改成可执行文件:

$ chmod a+x soho5_qca_trunk_prep/util/lzma/bin/lzma

所以Makefile中的相关代码需要修改成:

LZMA = ../../../util/lzma/bin/lzma
  • 编译:
$ COMPRESSED_UBOOT=1 \
    CFG_BOARD_TYPE=ap143-2.0 \
    ETH_CONFIG=_s27 \
    FLASH_SIZE=4 \
    FW_RECOVERY=y \
    FW_RECOVERY_DEV=wr841nv10 \
    FW_INPUT_BUTTON_GPIO=12 \
    FW_OUTPUT_LED_GPIO=3 \
    FW_OUTPUT_LED_ON=0 \
    make

最终会生成我们所需要的文件:tuboot.bin

  • 写入mac地址与版本信息[2016-01-24 13:43:53]

mac地址位于flash 0x1fc00开始的6个字节,而设备的版本信息位于flash 0x1fd00开始的8个字节

先将tuboot.bin用0xff填充至128KB:

$ tr '\000' '\377' < /dev/zero | dd of=tuboot_128k_pad.bin bs=1 skip=$(stat -c "%s" tuboot.bin) count=$((128*1024 - `stat -c "%s" tuboot.bin`))
$ cat tuboot.bin tuboot_128k_pad.bin > tuboot_128k.bin

写入mac地址(假设提取出来的固件名为tl-wr802n_v1_fw.bin):

$ dd if=tl-wr802n_fw_v1.bin of=tuboot_128k.bin bs=1 skip=$((0x1fc00)) seek=$((0x1fc00)) count=6 conv=notrunc

写入版本信息:

$ dd if=tl-wr802n_fw_v1.bin of=tuboot_128k.bin bs=1 skip=$((0x1fd00)) seek=$((0x1fd00)) count=8 conv=notrunc

[2016-01-27 23:12:53] 这里面涉及到一个问题:为什么要用0xff填充?

我们在往flash中写入数据的时候,总是要先进行擦除的操作,擦除实际上就是往flash中写1, 同时flash是按块(block)进行操作的。块中的一个字节如果需要修改,得先将这个块中的所有数据都copy出来,再擦除整个块,再将数据写进去。

使用0xff进行填充是为了减少flash块擦除的次数,增长flash的使用寿命?

参考:https://wiki.openwrt.org/doc/techref/flash

  • 关于调试:

tuboot.bin由两部分组成:

  1. bootstrap.bin
  2. u-boot.bin/u-boot.bin.lzma/u-boot.lzimg
rm -rf u-boot.bin.lzma
../../../util/lzma/bin/lzma --best --keep u-boot.bin
./tools/mkimage -A mips -T firmware -C lzma \
		-a 0xffffffff80010000 \
		-e 0xffffffff80010000 \
		-n 'u-boot image' -d u-boot.bin.lzma u-boot.lzimg
Image Name:   u-boot image
Created:      Sun Jan 24 01:00:11 2016
Image Type:   MIPS Linux Firmware (lzma compressed)
Data Size:    35451 Bytes = 34.62 kB = 0.03 MB
Load Address: 0x80010000
Entry Point:  0x80010000
cat bootstrap.bin > tuboot.bin
cat u-boot.lzimg >> tuboot.bin

设备上电时会最新开始执行bootstrap.bin, 先进行ram/flash相关的初始化,将解压u-boot.lzimg执行u-boot.bin

bootstrap.bin的debug信息可以通过lib_bootstrap/Makefile打开:

diff --git a/boot/u-boot/lib_bootstrap/Makefile b/boot/u-boot/lib_bootstrap/Makefile
--- a/boot/u-boot/lib_bootstrap/Makefile
+++ b/boot/u-boot/lib_bootstrap/Makefile
@@ -29,7 +29,7 @@ LIB   = libbootstrap.a
 OBJS   = bootstrap_board.o LzmaDecode.o string.o crc32.o LzmaWrapper.o time.o
 #OBJS  = bootstrap_board.o LzmaDecode.o string.o crc32.o LzmaWrapper.o ctype.o display_options.o string.o vsprintf.o lists.o devices.o console.o time.o
 
-#BOOTSTRAP_PRINTF_STATUS = BOOTSTRAP_PRINTF_ENABLED
+BOOTSTRAP_PRINTF_STATUS = BOOTSTRAP_PRINTF_ENABLED
 
 ifeq ($(BOOTSTRAP_PRINTF_STATUS), BOOTSTRAP_PRINTF_ENABLED)
 #overwrite objs

之后,你可以从串口log中看到如下信息:

U-Boot 1.1.4-ge4671519-dirty (Jan 22 2016 - 12:12:13)

DRAM:  32 MB

 relocating to address 81ff8000 
 Compressed Image at 9f0056a8 
 Disabling all the interrupts
   Uncompressing UBoot Image ... 
U-Boot uncompress address 80010000
 Stream with EOS marker is not supportedLZMA ERROR 1 - must RESET board to recover

NOTE: 由于使用了ubuntu系统的lzma, bootstrap无法解压u-boot.lzimg, 报错。

DRAM:  32 MB

 relocating to address 81ff8000 
 Compressed Image at 9f0056a8 
 Disabling all the interrupts
   Uncompressing UBoot Image ... 
U-Boot uncompress address 80010000
 Uncompression completed successfully with destLen 92984
 U-Boot Load address 80010000
 

U-Boot 1.1.4-ge4671519-dirty (Jan 22 2016 - 12:50:08)

ap143-2.0 - Honey Bee 2.0

DRAM:  32 MB
Flash Manuf Id 0xef, DeviceId0 0x40, DeviceId1 0x18
flash size 16MB, sector count = 256
Flash: 16 MB
Using default environment

In:    serial
Out:   serial
Err:   serial
Net:   ath_gmac_enet_initialize...
ath_gmac_enet_initialize: reset mask:c02200 
Scorpion ---->S27 PHY*
S27 reg init
: cfg1 0x800c0000 cfg2 0x7114
eth0: xx:xx:xx:xx:xx:xx
athrs27_phy_setup ATHR_PHY_CONTROL 4 :1000
athrs27_phy_setup ATHR_PHY_SPEC_STAUS 4 :10
eth0 up
Honey Bee ---->  MAC 1 S27 PHY *
S27 reg init
ATHRS27: resetting s27
ATHRS27: s27 reset done
: cfg1 0x800c0000 cfg2 0x7214
eth1: xx:xx:xx:xx:xx:xx
athrs27_phy_setup ATHR_PHY_CONTROL 0 :1000
athrs27_phy_setup ATHR_PHY_SPEC_STAUS 0 :10
athrs27_phy_setup ATHR_PHY_CONTROL 1 :1000
athrs27_phy_setup ATHR_PHY_SPEC_STAUS 1 :10
athrs27_phy_setup ATHR_PHY_CONTROL 2 :1000
athrs27_phy_setup ATHR_PHY_SPEC_STAUS 2 :10
athrs27_phy_setup ATHR_PHY_CONTROL 3 :1000
athrs27_phy_setup ATHR_PHY_SPEC_STAUS 3 :10
eth1 up
eth0, eth1
Setting 0x181162c0 to 0x4b97a100
is_auto_upload_firmware=0
Autobooting in 1 seconds
## Booting image at 9f020000 ...
   Uncompressing Kernel Image ... Stream with 

NOTE: flash已经从4M换成了16M

评论

Be the First to Comment!

提醒我
avatar

wpDiscuz