在顶层Makefile中可以看到如下代码:
SRCTREE:= $(CURDIR)
……
MKCONFIG:= $(SRCTREE)/mkconfig
……
smdk2410_config:unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
假定我们在u-boot-1.1.6的根目录下编译,则其中的MKCONFIG就是根目录下的mkconfig文件。$(@:_config=)的结果就是将“smdk2410_config”中的“_config”去掉,结果为“smdk2410”。所以“make smdk2410_config”实际上就是执行如下命令:
./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0
再来看看mkconfig的作用,在mkconfig文件开头第6行给出了它的用法:
06 # Parameters: Target Architecture CPU Board [VENDOR] [SOC]
这里解释一下概念,对于S3C2410、S3C2440,它们被称为SoC(System on Chip),上面除CPU外,还集成了包括UART、USB控制器、NAND Flash控制器等等设备(称为片内外设)。S3C2410/S3C2440中的CPU为arm920t。
以下,分步骤分析mkconfig的作用:
(1)确定开发板名称BOARD_NAME。
11 APPEND="no#" Default: Create new config file
12 BOARD_NAME=""# Name to print in make output
13
14 while [ $# -gt 0 ] ; do
15 case "$1" in
16 --) shift ; break ;;
17 -a) shift ; APPEND="yes" ;;
18 -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
19 *) break ;;
20 esac
21 done
22
23 [ "${BOARD_NAME}" ] || BOARD_NAME="$1"
对于“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令,其中没有“--”、“-a”、“-n”等符号,所以第14~22行没做任何事情。第11、12行两个变量仍维持原来的值。
执行完第23行后,BOARD_NAME的值等于第1个参数,即“smdk2410”。
(2)创建到平台/开发板相关的头文件的链接。
略过mkconfig文件中的一些没有起作用的行:
30 #
31 # Create link to architecture specific headers
32 #
33 if [ "$SRCTREE" != "$OBJTREE" ] ; then
……
45 else
46 cd ./include
47 rm -f asm
48 ln -s asm-$2 asm
49 fi
50
第33行判断源代码目录和目标文件目录是否一样,可以选择在其他目录下编译U-Boot,这可以令源代码目录保持干净,可以同时使用不同的配置进行编译。不过本书直接在源代码目录下编译的,第33行的条件不满足,将执行else分支的代码。
第46~48行进入include目录,删除asm文件(这是上一次配置时建立的链接文件),然后再次建立asm文件,并令它链接向asm-$2目录,即asm-arm。
继续往下看代码:
51 rm -f asm-$2/arch
52
53 if [ -z "$6" -o "$6" = "NULL" ] ; then
54 ln -s ${LNPREFIX}arch-$3 asm-$2/arch
55 else
56 ln -s ${LNPREFIX}arch-$6 asm-$2/arch
57 fi
58
59 if [ "$2" = "arm" ] ; then
60 rm -f asm-$2/proc
61 ln -s ${LNPREFIX}proc-armv asm-$2/proc
62 fi
63
第51行删除asm-$2/arch目录,即asm-arm/arch。
对于“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令,$6为“s3c24x0”,不为空,也不是“NULL”,所以第53行的条件不满足,将执行else分支。
第56行中,LNPREFIX为空,所以这个命令实际上就是:ln -s arch-$6 asm-$2/arch,即:ln -s arch-s3c24x0 asm-arm/arch。
第60、61行重新建立asm-arm/proc文件,并让它链接向proc-armv目录。
(3)创建顶层Makefile包含的文件include/config.mk。
64 #
65 # Create include file for Make
66 #
67 echo "ARCH = $2" > config.mk
68 echo "CPU = $3" >> config.mk
69 echo "BOARD = $4" >> config.mk
70
71 [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
72
73 [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
74
对于“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令,上面几行代码创建的config.mk文件内容如下:
ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0
(4)创建开发板相关的头文件include/config.h。
75 #
76 # Create board specific header file
77 #
78 if [ "$APPEND" = "yes" ]# Append to existing config file
79 then
80 echo >> config.h
81 else
82 > config.h# Create new config file
83 fi
84 echo "/* Automatically generated - do not edit */" >>config.h
85 echo "#include " >>config.h
86
前面说过,APPEND维持原值“no”,所以config.h被重新建立,它的内容如下:
/* Automatically generated - do not edit */
#include "
现在总结一下,配置命令“make smdk2410_config”,实际的作用就是执行“./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0”命令。假设执行“./mkconfig $1 $2 $3 $4 $5 $6”命令,则将产生如下结果:
(1)开发板名称BOARD_NAME等于$1;
(2)创建到平台/开发板相关的头文件的链接:
ln -s asm-$2 asm
ln -s arch-$6 asm-$2/arch
ln -s proc-armv asm-$2/proc# 如果$2不是arm的话,此行没有
(3) 创建顶层Makefile包含的文件include/config.mk。
ARCH = $2
CPU = $3
BOARD = $4
VENDOR = $5# $5为空,或者是NULL的话,此行没有
SOC = $6# $6为空,或者是NULL的话,此行没有
(4)创建开发板相关的头文件include/config.h。
/* Automatically generated - do not edit */
#include "
从这4个结果可以知道,如果要在board目录下新建一个开发板的目录,则在include/config目录下也要建立一个文件.h,里面存放的就是开发板的配置信息。
U-Boot还没有类似Linux一样的可视化配置界面(比如使用make menuconfig来配置),要手动修改配置文件include/config/.h来裁减、设置U-Boot。
配置文件中有两类宏:
(1)一类是选项(Options),前缀为“CONFIG_”,它们用于选择CPU、SOC、开发板类型,设置系统时钟、选择设备驱动等。比如:
#define CONFIG_ARM920T1/* This is an ARM920T Core*/
#defineCONFIG_S3C24101/* in a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK24101/* on a SAMSUNG SMDK2410 Board */
#define CONFIG_SYS_CLK_FREQ12000000/* the SMDK2410 has 12MHz input clock */
#define CONFIG_DRIVER_CS89001/* we have a CS8900 on-board */
(2)另一类是参数(Setting),前缀为“CFG_”,它们用于设置malloc缓冲池的大小、U-Boot的提示符、U-Boot下载文件时的默认加载地址、Flash的起始地址等。比如:
#define CFG_MALLOC_LEN(CFG_ENV_SIZE + 128*1024)
#defineCFG_PROMPT"100ASK> "/* Monitor Command Prompt*/
#defineCFG_LOAD_ADDR0x33000000/* default load address*/
#define PHYS_FLASH_10x00000000 /* Flash Bank #1 */
从下面的编译、连接过程可知,U-Boot中几乎每个文件都被编译和连接,但是这些文件是否包含有效的代码,则由宏开关来设置。比如对于网卡驱动drivers/cs8900.c,它的格式为:
#include /* 将包含配置文件include/config/.h */
……
#ifdef CONFIG_DRIVER_CS8900
/* 实际的代码 */
……
#endif/* CONFIG_DRIVER_CS8900 */
如果定义了宏CONFIG_DRIVER_CS8900,则文件中包含有效的代码;否则,文件被注释为空。
可以这样粗糙地认为,“CONFIG_”除了设置一些参数外,主要用来设置U-Boot的功能、选择使用文件中的哪一部分;而“CFG_”用来设置更细节的参数。
转自http://blog.cechina.cn/zhiy66/213215/message.aspx