u-boot分析一

u-boot分析

Posted by hades on April 25, 2018

u-boot分析一

u-boot分析以ar9331和ar953x 的为例。 获取u-boot源码

git clone https://github.com/pepe2k/u-boot_mod.git 

一般u-boot的初始化过程:

  • 硬件设备初始化
  • 加载U-Boot都RAM空间
  • 设置好栈
  • 跳转到C语言入口

LSDK中最后编译完成后生成的u-boot为tuboot,查看顶层Makefile :

ifdef COMPRESSED_UBOOT
all: $(ALL) tuboot.bin
else
all: $(ALL) u-boot.img
endif

最后生成的u-boot的压缩文件,到底如何压缩呢:

tuboot.bin: System.map bootstrap.bin u-boot.lzimg
	@echo
	$(call echo_green,Merging bootstrap.bin with u-boot.lzimg...)
	$(call echo_size,    Bootstrap size,bootstrap.bin)
	$(call echo_size,   LZMA image size,u-boot.lzimg)
	@cat bootstrap.bin > $@
	@cat u-boot.lzimg >> $@
	$(call echo_size,  Total image size,$@)

tuboot.bin依赖三个文件: System.map bootstrap.bin u-boot.lzimg,并使用cat命令将bootstrap.bin与u-boot.lzimg拼接在一起生成tub-boot.bin

  • System.map为编译生成的符号连接表
  • bootstrap.bin 为bootstrap引导程序
  • u-boot.lzimg 为u-boot的lzma压缩文件 编译信息如下:
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:      Wen Jan 24 01:00:11 2018
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 u-boot引导启动的完整打印信息如下:

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 2018 - 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 ... 

查看u-boot.lzimg是如何生成的:

u-boot.lzimg: lzma_host $(obj)u-boot.bin System.map
	@echo
	@rm -rf u-boot.bin.lzma
	@$(call echo_green,Compressing U-Boot image $<...)
	@$(LZMA) --best --keep $(obj)u-boot.bin
	$(call echo_green,Preparing LZMA compressed U-Boot image $@...)
	$(MKIMAGE) -A $(ARCH) -T firmware -C lzma \
	           -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | \
	            awk '{ printf "%s", $$1 }') \
	           -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | \
	            awk '{ printf "%s", $$1 }') \
	           -n '$(call ih_name)' -d $(obj)u-boot.bin.lzma $@

可以看到u-boot.lzimg是通过lzma压缩和mkimage制作而成的 记录一下mkimage命令的使用:

Usage: ./mkimage -l image
          -l ==> list image header information
       ./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
          -A ==> set architecture to 'arch'
          -O ==> set operating system to 'os'
          -T ==> set image type to 'type'
          -C ==> set compression type 'comp'
          -a ==> set load address to 'addr' (hex)
          -e ==> set entry point to 'ep' (hex)
          -n ==> set image name to 'name'
          -d ==> use image data from 'datafile'
          -x ==> set XIP (execute in place)

另外记录一下lzma压缩命令的使用:

LZMA 4.57  Copyright (c) 1999-2007 Igor Pavlov  2007-12-06

Usage:  LZMA <e|d> inputFile outputFile [<switches>...]
  e: encode file
  d: decode file
  b: Benchmark
<Switches>
  -a{N}:  set compression mode - [0, 1], default: 1 (max)
  -d{N}:  set dictionary - [0,30], default: 23 (8MB)
  -fb{N}: set number of fast bytes - [5, 273], default: 128
  -mc{N}: set number of cycles for match finder
  -lc{N}: set number of literal context bits - [0, 8], default: 3
  -lp{N}: set number of literal pos bits - [0, 4], default: 0
  -pb{N}: set number of pos bits - [0, 4], default: 2
  -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4
  -mt{N}: set number of CPU threads
  -eos:   write End Of Stream marker
  -si:    read data from stdin
  -so:    write data to stdout

u-boot.lzimg的制作是通过u-boot.bin文件,而u-boot.bin 是通过u-boot文件生成的:

u-boot.bin: u-boot
	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

到了u-boot才到真正的编程生成的二进制文件,u-boot生成过程如下:

u-boot: fsdata depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LIBS_SHARED) $(LDSCRIPT)
	UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) $(LIBS_SHARED) | \
	           sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p' | \
	           sort | uniq`; \
	$(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
	      --start-group $(LIBS) $(LIBS_SHARED) \
	      --end-group $(PLATFORM_LIBS) \
	  	-Map u-boot.map -o u-boot

fsdata depend version前三个依赖文件都是相关文件

version:
	@echo -n "#define U_BOOT_VERSION \"U-Boot $(U_BOOT_VERSION)\"" > $(VERSION_FILE)

fsdata:
	$(call echo_green,Preparing web server files...)
	@echo
	cd httpd && ./vendors/makefsdatac $(DEVICE_VENDOR)

depend dep:
	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir .depend; done

后面的几个才是编译重点:

$(LIBS):
	$(MAKE) -C `dirname $@`

$(SUBDIRS):
	$(MAKE) -C $@ all

$(OBJS )才是u-boot的入口

# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o