主要涉及到两个关键的Makfile,因为这些Makefile的自动化程度不高,所以代码显得很繁琐,但正因为如此,才相对显得比较简单。
首先是asuswrt/release/src-ra-mt7620目录下的Makefile
略去前面的变量定义部分,进入关键的部分:
image: @if [ -z "$(BUILD_NAME)" ]; then \ echo "No BUILD_NAME is assigned"; \ exit 1; \ fi @rm -f image/$(BUILD_NAME)_$(KERNEL_VER).$(FS_VER)_$(SERIALNO).trx @$(MAKE) -C router image ifeq ($(CONFIG_RALINK),y) #开始生成image else #非ralink设备,只进行简单的打包 endif
@rm -rf $(PLATFORMDIR)/zImage.lzma ; \ mipsel-linux-objcopy -O binary $(LINUXDIR)/vmlinux $(PLATFORMDIR)/vmlinus ; \ asustools/lzma -9 -f -c $(PLATFORMDIR)/vmlinus > $(PLATFORMDIR)/zImage.lzma ; \ cp -f $(PLATFORMDIR)/zImage.lzma $(PLATFORMDIR)/zImage.img ; \首先生成kernel的bin目标文件vmlinus,然后调用lzma进行最高强度的压缩,生成zImage.lzma,最后将文件拷贝到$(PLATFORMDIR)目录,
通过前面的定义
export PLATFORM := mipsel-uclibc export PLATFORMDIR := $(SRCBASE)/router/$(PLATFORM)可知,该目录位于router/mipsel-uclibc
此部分的代码比较多,但是容易理解,用到了shell中的wc、awk、expr、dd、tr等命令,此处不详述,感兴趣的读者可以对照Makefile文件研究。
核心代码是调用mkimage命令,生成trx刷机固件文件。
我们知道mkimage需要知道代码的入口点,这个入口点如何用程序获取呢?这个技巧值得我们去学习:
@ENTRY=`LANG=en_US readelf -h $(ROOTDIR)/$(LINUXDIR)/vmlinux | grep "Entry" | awk '{print $$4}'` ; \ ISIZE=`wc -c $(PLATFORMDIR)/zImage.img | awk '{print $$1}'` ; \ KSIZE=`wc -c $(PLATFORMDIR)/zImage.lzma | awk '{print $$1}'` ; \ RSIZE=`wc -c $(PLATFORMDIR)/target.image | awk '{print $$1}'` ; \ PAD2=`expr $${ISIZE} - $${KSIZE} - $${RSIZE}` ; \ RFSOFFSET=`expr 64 + $${KSIZE} + $${PAD2}` ; \ echo "PAD2: $${PAD2}" ; \ asustools/mkimage -A mips -O linux -T kernel -C lzma -a 80000000 -e $${ENTRY} -r $${RFSOFFSET} \ -n $(BUILD_NAME) -V "$(KERNEL_VER)" "$(FS_VER)" "0" "0" "0" "0" "0" "0" "0" "0" \ -d $(PLATFORMDIR)/zImage.img image/$(BUILD_NAME)_$(KERNEL_VER).$(FS_VER)_$(SERIALNO)_$(SWPJVER)$(EXTENDNO).trx ; \它利用readelf -h,读出vmlinux的header部分信息:
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x8000c150
Start of program headers: 52 (bytes into file)
Start of section headers: 3445604 (bytes into file)
Flags: 0x70001001, noreorder, o32, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 21
Section header string table index: 18
利用grep "Entry" | awk '{print $$4}',就能获取到入口地址0x8000c150
利用通配符,实现了一些简化的操作,如:
mk-%: @$(MAKE) -C router $(shell echo $@ | sed s/mk-//)和:
%: dummy @[ ! -d router/$* ] || $(MAKE) -C router $@ %-clean: dummy @-[ ! -d router/$* ] || $(MAKE) -C router $@ %-install: dummy @[ ! -d router/$* ] || $(MAKE) -C router $* $@ %-stage: dummy @[ ! -d router/$* ] || $(MAKE) -C router $* $@ %-build: dummy $(MAKE) $*-clean $* %-tags: dummy @[ ! -d router/$* ] || ctags -a -R $(CTAGS_EXCLUDE_OPT) $(SRCBASE)/../src/router/$*
有意放在最后来介绍,因为此处就要跳转到router目录,进行下一个重要编译过程
all: rt_ver @echo "" @echo "Building $(BUILD_NAME)_$(KERNEL_VER).$(FS_VER)_$(SERIALNO).trx" @echo "" @echo "" @-mkdir image @$(MAKE) -C router all @$(MAKE) -C router install @$(MAKE) image实际上是进入到router目录,对all和install目标进行编译。
我将在下一篇文章中,对router目录中的Makefile进行描述。