uboot配置编译阶段根目录下的mkconfig的分析
文件的来源:uboot的原生文件;
文件的路径:uboot/mkconfig
文件被引用的地方:被uboot/Makefile调用两次:
第一次被调用是在配置阶段:
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
这里是将x210_sd_config 后面的_config替换为空,然后x210_sd作为执行MKCONFIG的参数和后面的arm s5pc11x x210 samsung s5pc110一起传给MKCONFIG。传入之后$1=x210_sd $2=arm $3=s5pc11x $4=x210 $5=samsung $6=s5pc110 $#=6
第二次是在编译时make执行过程,Makefile内的代码被以此执行,然后被应用调用:(101行)
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
mkcongfig具体的功能:
1.确定了开发板的一些名称信息;
2.创建了相关头文件的链接;
3.根据具体板子的信息,在根目录下创建config.mk文件;
注:mkconfig是uboot的链接脚本。
下面是对config.mk的具体分析:
1.定义了两个变量在后面指导链接文件的生成:
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
选择mkconfig的默认值为创建新的配置文件;设置BOARD_NAME 板子名默认值为空。
2.规定了传入参数的个数限制:
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
注:查询BOARD_NAME是否有值,没有的话赋值为$1(smdkv210single_config)
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
规定了传入参数的个数要求,$#必须大于4小于6 即传入的参数必须4~6
3.make配置阶段的一个调试信息的打印:
echo "Configuring for ${BOARD_NAME} board..."
在我们make配置完之后会打印出,这里的BOARD_NAME会替换为 $1=x210_sd
4.创建符号链接(这个是mkconfig中比重很大的一部分)
从这里开始的代码便是创建符号链接及一些头文件,其根本目的是使uboot具有可移植性。uboot中有很多功能平行的代码文件,各自属于各自不同的平台/开发板/cpu。通过传入此shell脚本的参数,来创建指向我们需要的文件的符号链接。但uboot并不直接与这些功能平行的代码建立联系,符号链接帮助uboot屏蔽了许多用不到的代码。比如某源文件中包含了一个#include“asm/xx.h”,其中asm为本脚本文件创建的符号链接,它指向的地址为根目录下include/asm-arm,由此便可以定位到真正的路径,即”根目录下include/asm-arm/xx.h”。综上所述,创建符号链接的本质是通过不同的参数,令源代码文件包含特定的文件
符号链接文件是我们整个配置过程的核心,这些符号链接文件(文件夹)的主要作用是给头文件包含等过程提供指向性链接,使得uboot有可移植性。
uboot的移植原理:在uboot之中有很多彼此平行的代码,各自属于各自不同的架构/CPU/开发板,我们在具体到某个开发板的编译时用符号连接的方式提供一个具体名字的文件夹供编译器使用。就可以在配置过程中通过配置使用不同的文件,从而正确的包含正确的文件。
(1)在include目录下创建asm文件,指向asm-arm 43~48行
mkdir asm-$2
ln -s asm-$2 asm
是将asm-$2 这个文件指向asm文件,在访问asm文件时就相当于访问了asm-$2;
2)在include/asm-arm下创建一个arch文件,指向include/asm-arm/arch-s5pc110 56行;
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi
(3)在include目录下创建一个reg.h文件,指向include/s5pc110.h文件 86行
if [ "$3" = "s5pc11x" ] ; then
rm -f regs.h
ln -s $6.h regs.h
(4)将include/asm-arm下的arch文件指向include/asm-arm/arch-s5pc11x (覆盖了2中的符号链接) 88行
rm -f asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
(5)在include目录下创建了proc文件,指向 include/asm-$2/procproc-armv 109
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
注1:OBJTREE和SRCTREE在当前目录下本地编译时它所代表的目录是相同的,在-o指定目录编译时不相等,此时OBJTREE仍然代表根目录,SRCTREE则是指定目录的根目录。
注2:在创建链接文件时首先看创建的链接文件的路径,被链接的文件的路径在没有绝对路径的情况下是和被创建的文件的路径保持一致。例:
ln -s arch-$3 asm-$2/arch(当前目录:/include)
则在/include/asm-$2下创建了arch文件,文件指向/include/asm-$2目录下的arch-$6文件;
注3:在将来的代码之中会固定的包含头文件,而这些头文件实际会被链接到不同的路径的文件中去。
5.指导生成我们的uboot/include/config.mk文件:
#
# Create include file for Make
#
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
注:>:检查目录,如果文件不存在则创建,然后在文件内追加>之前的内容。
>>:在文件内的尾行追加>>之前的内容
在查看shell脚本程序是时刻注意自己当前的目录。
6.创建于板子相关的头文件:
#
# 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
简单的判断之后在include目录下下创建一个config.h文件。而在后面利用管道向其内写了一段话,并且包含了我们板子对应的头文件。而那个头文件是我们移植是最重要的文件,它涉及我们对开发板的宏定义配置文件。
这些/uboot/include/configs/*****.h>文件会被用来autoconf.mk文件,autoconf.mk文件会被主Makefile引用,指导整个编译过程,这里面的宏定义会影响我们对uboot中大部分.c文件的条件编译的选择,从而实现可移植性。