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” “ * ”
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“的值修改掉。