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 |
---|---|---|---|---|---|---|
mkconfig | 100ask24x0 | arm | arm920t | 100ask24x0 | NULL | s3c24x0 |
第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