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