uboot的配置与编译——分析/mkconfig文件(创建符号链接、构建/include/config.mk与config.h文件)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

一、mkconfig文件总结 

该文件创建了一些符号链接,构建了头文件/include/config.h,构建了脚本/include/config.mk。

(1)创建目标板相关文件的符号链接

#当前目录是顶层目录
ln s ./include/asm-arm ./include/asm   #./include/asm -> ./include/asm-arm
ln s ./include/s5pc110.h ./include/regs.h
ln s ./include/asm-arm/arch-s5pc11x ./include/asm-arm/arch
ln s ./include/asm-arm/proc-armv ./include/asm-arm/proc

(2)构建/include/config.h头文件

/include/config.h头文件内容如下,则它的内容等同于/include/configs/x210_sd.h的内容。

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

/include/configs文件夹中的每个文件对应着一个开发板的头文件(由uboot移植人员提供?),这些头文件都是一些宏定义配置文件,是移植时最主要的文件。

比如/include/configs/x210_sd.h文件被用来生成/include/autoconfig.mk文件,而autoconfig.mk文件被/Makefile引入而指导整个编译过程。x210_sd.h文件中的宏会影响大部分.c文件里的一些条件编译的选择,从而实现可移植性。 

xjh@ubuntu:~/iot/embedded_basic/uboot/uboot_jiuding-version/include/configs$ ls
x210_nand.h  x210_sd.h
xjh@ubuntu:~/iot/embedded_basic/uboot/uboot_jiuding-version/include/configs$ 

(3)构建include/config.mk脚本

/include/config.mk脚本内容如下。

ARCH   = arm
CPU    = s5pc11x
BOARD  = x210
VENDOR = samsung
SOC    = s5pc110

/Makefile文件中将/include/config.mk文件包含进来,则/include/config.mk文件的内容将在/Makefile文件中原地展开。/Makefile文件得到这几个变量值后,再将它们导出到环境变量,如下所示:

# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export	ARCH CPU BOARD VENDOR SOC

二、配置规则分析

在对uboot这个工程执行编译之前,需要先进行配置,即执行“make  x210_sd_config”。

其中x210_sd_config是主Makefile中的一个目标,如下所示。

x210_sd_config : unconfig
    @$(MKCONFIG)   $(@:_config=)  arm  s5pc11x  x210  samsung  s5pc110
    @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

为了完成该目标,规则的命令部分调用了MKCONFIG这个变量所代表的脚本。

这个变量在主Makefile中定义,表示/mkconfig脚本,它接收6个参数:

  • $1=x210_sd
  • $2=arm
  • $3=s5pc11x
  • $4=x210
  • $5=samsung
  • $6=s5pc110

$(@:_config=) 的解释:其中@代表的是x210_sd_config,那么$(@:_config=)就是将x210_sd_config中的"_config"替换成“空”(其实=后面是空),得到x210_sd。

Makefile为什么要这么干?为了适配多种工程文件。

接着,创建/board/samsung/x210/config.mk文件,将“TEXT_BASE = 0xc3e00000”写入其中。

三、mkconfig脚本分析

/mkconfig脚本的代码内容见下载链接

1、解析参数与检查参数合法性

(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
  • 首先利用while循环,判断$#的值(即参数个数,这里为6),是否大于0,如果大于0则进入循环。
  • shell的switch case语法中是不需要break的,故此处的switch case是为了跳出外面的while循环。
  • 这段代码上来先判断$1的值(即第一个参数),如果为一些特定的值,那么会进行shift操作,即向左移动参数列表一次,将第一个参数移出参数列表。但由于我们第一个参数为x210_sd,故只符合最后一个case,即“*”,也就是通配符,直接break跳出了while循环。
  • 其实这整段代码对我们没有产生什么作用。

(2)确定开发板的名称BOARD_NAME

[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
  • 本句判断变量BOARD_NAME是否为空,由于在(1)中对其赋为空值,所以此处将它的值赋为第一个参数的值,即x210_sd。
  • 这种“ [ xxx  ] || yyy ”写法表示:[ xxx ]如果成立,则不会执行yyy。注意都是先判断左边的式子。

(3)检查参数的合法性

[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
echo "Configuring for ${BOARD_NAME} board..."
  • 如果参数个数小于4,则这个脚本程序将退出,并返回1(表示出错)。
  • 如果参数个数大于6,则这个脚本程序将退出,并返回1(表示出错)。
  • 最后一句为打印配置信息。
  • 这种“ [ xxx  ] && yyy写法表示:[ xxx ]如果成立,则执行yyy;[ xxx ]如果不成立,则不会执行yyy。注意都是先判断左边的。

2、创建目标板相关文件的符号链接

创建符号链接是为了让uboot具有可移植性。

怎么理解这句话呢?uboot中有很多功能平行(即相同)的代码文件,各自属于不同的平台/开发板/cpu。uboot不直接与这些功能平行的代码建立联系,而是使用符号链接来屏蔽许多用不到的代码。创建符号链接的本质是通过不同的参数,令源代码文件包含特定的文件。

比如有asm-arm目录、asm-powerpc目录,分别是arm和powerpc的指令集相关的目录。这两个目录下都有一个reg.h文件。

我们编写一个源文件,为了源文件的通用性,我们把头文件包含写成#include “asm/reg.h”,而不是写成 #include "asm-arm/reg.h"或者 #include "asm-powerpc/reg.h",那么在编译的时候,如何指定包含具体目录下的reg.h文件呢?

我们可以创建一个符号链接asm,这个符号链接会根据传入 /mkconfig 脚本的参数的不同,而指向不同目录下的reg.h文件。如果传入 /mkconfig 的参数$2是arm,则asm指向asm-arm目录下的reg.h文件,则#include “asm/reg.h”就相当于#include “asm-arm/reg.h”;如果传入/mkconfig的参数是powerpc,则asm指向asm-powerpc目录下的reg.h文件,则#include “asm/reg.h”就相当于#include “asm-powerpc/reg.h”。

(1)创建/include/asm符号链接文件,使其指向/include/asm-arm文件夹

#
# Create link to architecture specific headers
#
if [ "$SRCTREE" != "$OBJTREE" ] ; then  #如果外部输出文件夹编译
	mkdir -p ${OBJTREE}/include
	mkdir -p ${OBJTREE}/include2
	cd ${OBJTREE}/include2
	rm -f asm
	ln -s ${SRCTREE}/include/asm-$2 asm
	LNPREFIX="../../include2/asm/"
	cd ../include
	rm -rf asm-$2
	rm -f asm
	mkdir asm-$2
	ln -s asm-$2 asm   #即${OBJTREE}/include/asm->${OBJTREE}/include/asm-$2

else #如果原地编译(一般我们选择这里)             
	cd ./include
	rm -f asm
	ln -s asm-$2 asm  #/include/asm -> /include/asm-arm 
fi
  • 本段代码功能是确定和汇编指令集相关的文件夹。
  • 首先判断是否使用了“外部输出文件夹编译”功能,如果未使用则进入/include目录,删除原本存在的符号链接asm。
  • 最后创建符号链接asm,使其链接到asm-arm文件夹。

(2)创建/include/asm-arm/arch、/include/regs.h链接文件,使其分别指向/include/asm-arm/arch-s5pc11x文件夹、/include/s5pc110.h文件

rm -f asm-$2/arch

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
  • 删除指令集文件夹下原本存在的符号链接arch。
  • 然后确定指令集文件夹下的架构文件夹。这段代码其实是历史遗留代码,是有问题的,真正的确定架构文件夹是在后面。
#这里省略了一堆和其他soc有关的代码,只保留了我们的s5pv210
#$1=x210_sd
#$2=arm
#$3=s5pc11x
#$4=x210
#$5=samsung
#$6=s5pc110

#注意,目前是在/include目录下

if [ "$3" = "s5pc11x" ] ; then
        rm -f regs.h
        ln -s $6.h regs.h   # /include/regs.h -> /include/s5pc110.h
        rm -f asm-$2/arch
        ln -s arch-$3 asm-$2/arch # /include/asm-arm/arch -> /include/arch-s5pc11x
fi
  • 本段代码旨在确定cpu的寄存器头文件,和确定指令集文件夹下的架构文件夹。
  • 首先判断第三个参数是不是s5pc11x,然后删除原本存在的符号链接/include/regs.h,再创建/include/regs.h链接到/include/s5pc110.h文件。
  • 最后删除原来的符号链接/include/asm-arm/arch,再新建符号链接/include/asm-arm/arch,使其链接到/include/arch-s5pc11x这个文件夹。

(3)创建/include/asm-arm/proc链接文件,使其指向/include/asm-arm/proc-armv文件夹

if [ "$2" = "arm" ] ; then
    rm -f asm-$2/proc 
    #/include/asm-arm/proc -> /include/asm-arm/proc-armv
    ln -s ${LNPREFIX}proc-armv asm-$2/proc 
fi
  • 本段代码旨在确定指令集文件夹下的proc文件夹。
  • 创建符号链接/include/asm-arm/proc,指向/include/asm-arm/proc-armv文件夹。

3、构建/include/config.mk文件 

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

(1)本段是构建/include/config.mk文件,由于之前所停留的目录一直是/include目录下,故config.mk将被创建在/include目录下。

(2)bash语法中的“>”,其功能是创建文件并填充内容,“>>”功能是额外添加内容,所以第2,3,4个参数都被添加到这个文件中去了。当5,5,6存在且不为0时,第5,6个参数才被添加。

(3)/include/config.mk文件的全部内容如下:

ARCH   = arm
CPU    = s5pc11x
BOARD  = x210
VENDOR = samsung
SOC    = s5pc110

(4)构建/include/config.mk文件是为了让/Makefile在第133行去包含的。 

4、构建/include/conifg.h文件 

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这个文件,这个.h文件内除了注释只有一句话,即#include “configs/x210_sd.h”。
  • 从某种意义上来说,/include/config.h这个文件的功能就是符号链接,它指向了真正的配置头文件include/configs/x210_sd.h。
  • APPEND变量是在本文件一开始的地方定义的,值默认是no,当本脚本文件被传参数-a时,它会被赋值yes。
  • 创建完config.h之后,再向其填充入内容,最后shell结束,返回值0(表示正常)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天糊土

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值