(2)结合Makefile分析uboot

u-boot的配置命令:
make 100ask24x0_config
u-boot的编译命令:
make


一、 从make 100ask24x0_config引出

uboot体验的时候,我们怎么知道是怎么配置编译的呢,可以查看README文件。

分析配置过程
因为配置命令是make 100ask4x0_config
所以在Makefile里搜索“100ask4x0_config”:

100ask24x0_config	:	unconfig
	@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0

搜索“MKCONFIG”:

MKCONFIG	:= $(SRCTREE)/mkconfig  

搜索“SRCTREE”:

SRCTREE		:= $(CURDIR) #$(CURDIR)是make的内嵌变量,表示当前目录

所以@$(MKCONFIG) ===> 当前目录下的mkconfig文件

https://blog.csdn.net/anfeng3664/article/details/101179905
“@” 和 "$ @"一样表示目标
$ (@:_config=) 表示100ask24x0_config里的_config替换为空
所以$ (@:_config=) ===> 100ask24x0

最后@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
===> mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
所以执行命令“make 100ask24x0_config”就相当于执行“mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0”

接下来分析“mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0”命令是什么意思。

所以打开mkconfig文件:

二、分析mkconfig脚本文件(可以了解到系统是如何配置的)

shell脚本基本语法:
https://www.cnblogs.com/yinheyi/p/6648242.html
https://blog.csdn.net/zhu_xun/article/details/24796235

$0$1$2$3$4$5$6
mkconfig100ask24x0armarm920t100ask24x0NULLs3c24x0

第1部分

APPEND=no	# Default: Create new config file
BOARD_NAME=""	# Name to print in make output
while [ $# -gt 0 ] ; do
	case "$1" in
	--) shift ; break ;;
	-a) shift ; APPEND=yes ;;
	-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
	*)  break ;;
	esac
done

忽略此部分代码,因为我们的命令里没有 “–” “-a” “-n” “ * ”

第2部分

[ "${BOARD_NAME}" ] || BOARD_NAME="$1"

${BOARD_NAME}成立就不执行“||”后面的代码。
因为BOARD_NAME="",所以BOARD_NAME为空;
所以BOARD_NAME="$1";
因为$1是100ask24x0,所以BOARD_NAME=100ask24x0。

第3部分

[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit

“$ #”为6;
-lt 4表示小于4;
-gt 6表示大于6;
如果“$#”小于4 大于6 就退出。
$# = 6,表达式不成立,因此忽略这部分代码。

第4部分

echo "Configuring for ${BOARD_NAME} board..."

在终端打印信息,我们make 100ask24x0_config的时候可以看到。

第5部分

if [ "$SRCTREE" != "$OBJTREE" ] ; then

在makefile文件里搜索”OBJTREE“:

OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))

如果$(BUILD_DIR)不为空,则OBJTREE等于 $ (BUILD_DIR),如果为空则等于$(CURDIR)。

BUILD_DIR := $(O)

因此搜索得出BUILD_DIR为空,所以OBJTREE等于$(CURDIR)
SRCTREE也等于$(CURDIR)
所以if [ "$ SRCTREE" != "$OBJTREE" ] 不成立,所以执行else的代码

第6部分

else
	cd ./include
	rm -f asm
	ln -s asm-$2 asm
fi

rm -f asm-$2/arch

ln -s asm-arm asm 表示建立软链接文件,可以查看下:
```

为什么要建立asm软链接呢?
因为我们可以看到include里asm有很多架构,有asm-arm、asm-i386等;
我们在写源码的时候,在arm架构下写#include<asm-arm/type.h>,如果在i386架构下写#include<asm-i386/types>;
要一直修改,不如直接写#include<asm/type.h>,配置的时候直接指向某个架构。

第7部分

if [ -z "$6" -o "$6" = "NULL" ] ; then

-z 表示zero
-o 表示or
意思就是第六个参数如果为0或者为NULL,显然$6为s3c24x0,不为0也不为空,所以执行else分支:

ln -s ${LNPREFIX}arch-$6 asm-$2/arch

${LNPREFIX}搜索下,没有定义
ln -s arch-s3c24x0 asm-arm/arch
因为第六部分 cd ./include,所以现在是在include目录下:
asm-arm/arch -> /include/asm/arch-s3c24x0

这部分代码同理:


if [ "$2" = "arm" ] ; then
	rm -f asm-$2/proc
	ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi

ln -s proc-armv asm-arm/proc

第9部分

#
# Create include file for Make
#
echo "ARCH   = $2" >  config.mk 
echo "CPU    = $3" >> config.mk
echo "BOARD  = $4" >> config.mk

新建config.mk 文件,并将 “ARCH = arm” 覆盖到config.mk 文件
“CPU = arm920t” 追加到 config.mk
“BOARD =100ask24x0” 追加到 config.mk
我们可以打开config.mk查看下:
在这里插入图片描述

第10部分

#
# Create board specific header file
#
 if [ "$APPEND" = "yes" ]	# Append to existing config file
then
	echo >> config.h
else
	> config.h		# Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h

exit 0

新建config.h文件,
config.h文件的内容:

/* Automatically generated - do not edit */
#include <configs/100ask24x0.h>

总结u-boot的配置过程(mkconfig的作用):
参考 <Linux应用开发手册P250>
1、确定开发板名称BOARD_NAME
BOARD_NAME=100ask24x0
2、创建平台/开发板相关的头文件链接
ln -s asm-arm asm
ln -s arch-s3c24x0 asm-arm/arch
ln -s proc-armv asm-arm/proc
3、创建顶层Makefile包含的文件include/config.mk
4、创建开发板相关的头文件文件include/config.h

二、分析编译过程

include $(OBJTREE)/include/config.mk

说明配置文件mkconfg生成的config.mk用上了

OBJS  = cpu/$(CPU)/start.o

∵ $ (CPU)在config.mk文件,可知CPU = arm920t
∴ OBJS = cpu/arm920t/start.o

LIBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
......

LIBS += board/100ask24x0/lib100ask24x0.a
LIBS += cpu/arm920/libarm920.a
可以猜测是把把XXX文件夹里的所有文件打包成XXX.a这样的库

ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)

all:		$(ALL)

all目标依赖于$(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

$(obj)u-boot.hex:	$(obj)u-boot
		$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@

$(obj)u-boot.srec:	$(obj)u-boot
		$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@

$(obj)u-boot.bin:	$(obj)u-boot  #u-boot.bin是二进制文件,u-boot是elf格式文件
		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

$(obj)u-boot.img:	$(obj)u-boot.bin
		./tools/mkimage -A $(ARCH) -T firmware -C none \
		-a $(TEXT_BASE) -e 0 \
		-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
			sed -e 's/"[	 ]*$$/ for $(BOARD) board"/') \
		-d $< $@

这些文件又依赖于$(obj)u-boot $(obj)u-boot.bin ,其中u-boot是elf格式的文件

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

cd $(LNDIR) 进入某个目录
$(LD)链接
$(LDFLAGS) 链接的参数
$(__OBJS)所有的.o文件
$(__LIBS) 所有的库
这些展开都是都是什么,我们可以通过make命令,在终端查看——最后几行:
在这里插入图片描述
对比,大概得出uboot依赖于一些库和u-boot.lds的链接脚本,
于是我们查看下u-boot.lds链接脚本:

SECTIONS
{
	. = 0x00000000;  #当前地址为0  然后将文件放到0x33F0000运行

	. = ALIGN(4);
	.text      :
	{
	  cpu/arm920t/start.o	(.text)   #然后放 cpu/arm920t/start.o 这个文件的代码段
          board/100ask24x0/boot_init.o (.text)  #放   board/100ask24x0/boot_init.o 这个文件的代码段
	  *(.text) # 所有文件的代码段
	}
	
	. = ALIGN(4);
	.rodata : { *(.rodata) }   #所有文件的只读数据段
	
	. = ALIGN(4);
	.data : { *(.data) }    #所有文件的数据段

	. = .;
	__u_boot_cmd_start = .;
	.u_boot_cmd : { *(.u_boot_cmd) } #所有文件的u_boot_cmd,这是u-boot自定义的段
	__u_boot_cmd_end = .;

通过makefile文件我们知道了:
1、运行的第一个文件是 cpu/arm920t/start.o,我们可以通过分析这个文件把uboot串起来
2、链接地址是board/100ask24x0/u-boot.lds + 0x33f80000
在这里插入图片描述
那么 0x33f80000 在哪里定义?
在这里插入图片描述
根据makefile的最后几条命令,可以知道 ( L D F L A G S ) 是 包 含 了 地 址 的 , 所 以 我 们 查 找 下 ‘ (LDFLAGS)是包含了地址的,所以我们查找下` (LDFLAGS)(LDFLAGS)在哪里定义: 在uboot目录下搜索下grep “LDFLAGS” * -nr` (-n表示显示行号 -r表示递归 * 表示匹配内容任意次)
在这里插入图片描述
所以我们如果想修改sdram的地址,我们可以到board/100ask24x0/config.mk下把”TEXT_BASE“的值修改掉。


总结:(通过makefile文件我们知道了:)
1、运行的第一个文件是 cpu/arm920t/start.o
2、链接地址是board/100ask24x0/u-boot.lds + 0x33f80000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值