(2)分析uboot的配置和编译过程

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


一、分析配置过程

总结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

因此打开makefile文件,搜索“100ask24x0_config”:

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

搜索“MKCONFIG”:

MKCONFIG	:= $(SRCTREE)/mkconfig  

搜索“SRCTREE”:

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

MKCONFIG ===> 当前目录下的mkconfig文件

$ (@:_config=)意思相当于 bj=$(srcfiles:%.c=%.o): 由.c得到对应的.o文件
https://blog.csdn.net/anfeng3664/article/details/101179905

∵ “@” 和 "$ @"一样表示目标
$ (@:_config=) 表示100ask24x0_config里的_config替换为空,得出100ask24x0

∴ 得出 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脚本文件(同理的代码就没写出来):

在linux脚本里:

$0 $1 $2 $3 $4 $5 $6
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0

1

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” “ * ”

扫描二维码关注公众号,回复: 10104730 查看本文章

2

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

和c语言一样${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 就退出。
不成立,因此忽略代码。

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等于当前目录
所以if [ “$ SRCTREE” != “$OBJTREE” ] 不成立,所以执行else的代码

6

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

ln -s asm-$2 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也不为空

8

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

asm-arm/arch -> /include/asm/arch-s3c24x0

9

echo "ARCH   = $2" >  config.mk 
echo "CPU    = $3" >> config.mk
echo "BOARD  = $4" >> config.mk

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

二、分析编译过程

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

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 在哪里定义?
在这里插入图片描述
我们查找下$(LDFLAGS)在哪里定义:
在uboot目录下搜索下grep “LDFLAGS” * -nr (-n表示显示行号 -r表示递归 * 表示匹配内容任意次)
在这里插入图片描述
所以我们如果想修改sdram的地址,我们可以到board/100ask24x0/config.mk下把”TEXT_BASE“的值修改掉。

发布了56 篇原创文章 · 获赞 3 · 访问量 2363

猜你喜欢

转载自blog.csdn.net/qq_40674996/article/details/105029063