u-boot分析(二) u-boot的编译及配置 mkconfig

来源:互联网 发布:淘宝不能卖pos 编辑:程序博客网 时间:2024/05/01 20:53

u-boot分析(二) u-boot的编译及配置 mkconfig

刚开始接触u-boot总是存在这样的疑问,../include/configs/mini2440.h是如何关联到../board/mini2440.c中的?显然他们并没有在源码中有直接的包含关系。

编译u-boot时,输入

make mini2440_config

make

u-boot就被成功创建了,这都归功于Makefile与mkconfig

在u-boot的顶层文件夹中的Readme中,有如下描述:

If the system board that you have is not listed,then you will need

to port U-Boot to your hardware platform. To dothis, follow these

steps:

1.  Add anew configuration option for your board to the toplevel "Makefile"and to the "MAKEALL" script, using the existing entries as examples.Note that here and at many other places boards and other names are listed inalphabetical sort order. Please keep this order.

2.  Create anew directory to hold your board specific code. Add any files you need. In yourboard directory, you will need at least the "Makefile", a"<board>.c", "flash.c" and "u-boot.lds".

3.  Create anew configuration file "include/configs/<board>.h" for yourboard

3.  Ifyou're porting U-Boot to a new CPU, then also create a new directory to holdyour CPU specific code. Add any files you need.

4.  Run"make <board>_config" with your new name.

5.  Type"make", and you should get a working "u-boot.srec" file tobe installed on your target system.

6.  Debugand solve any problems that might arise.[Of course, this last step is muchharder than it sounds.]

向u-boot源码树种添加自己的硬件平台需要做上述6条,以添加mini2440为例

第一向顶层Makefile中添加新的configuration option,按照已有的硬件平台为格式添加mini2440

mini2440_config    :      unconfig

       @$(MKCONFIG)$(@:_config=) arm arm920t mini2440 NULL s3c24x0

第二在../board文件夹中新建合适的文件夹,用来存放新添加的板级文件:

新建文件夹mini2440,并添加mini2440.c,config.mk,lowlevel_init.S,Makefile,nand_read.c,flash.c

第三步创建新的配置文件"include/configs/mini2440.h"

第四步 make mini2440_config

第五步 make

最后debug

现在开始分析他们是如何建立起连接关系的

在顶层Makefile中可以看到如下代码

SRCTREE             :=$(CURDIR)

TOPDIR         :=$(SRCTREE)

export     TOPDIRSRCTREE OBJTREE

 

MKCONFIG   :=$(SRCTREE)/mkconfig

……

mini2440_config    :      unconfig

       @$(MKCONFIG)$(@:_config=) arm arm920t mini2440 NULL s3c24x0

……

TOPDIR就是SRCTREE,也就是u-boot源码的顶层目录,则其中的MKCONFIG就是根目录下的mkconfig,$(@:_config=)的结果就是将“mini2440_config”中的“_config”去掉,结果为“mini2440”。所以“make mini2440_config”实际上就是执行如下命令:

./mkconfig mini2440 arm arm920t mini2440NULL s3c24x0

mkconfig是一个shell脚本,在mkconfig文件开头第6行给出了它的用法

06 # Parameters: Target Architecture CPUBoard [VENDOR] [SOC]

所以Makefile调用了它并给它传递了6个参数,分别是:【注】shell中用$n代表第n个参数

$1= mini2440

$2= arm

$3= arm920t

$4= mini2440

$5= NULL

$6= s3c24x0

现在分步骤分析mkconfig的作用

(1)     确定开发板的BOARD_NAME

01 APPEND=no     # Default: Create new config file

02 BOARD_NAME=""  # Name to print in make output

03 TARGETS=""

04 while [ $# -gt 0 ] ; do

05   case"$1" in

06   --)shift ; break ;;

07   -a)shift ; APPEND=yes ;;

08   -n)shift ; BOARD_NAME="${1%%_config}" ; shift ;;

09   -t)shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;

10   *)  break ;;

11   esac

12 done

[ "${BOARD_NAME}" ] ||BOARD_NAME="$1"

对于./mkconfigmini2440 arm arm920t mini2440 NULL s3c24x0这条命令没有”—“,”-a”等参数,所以4~12行没有做任何事情,第一第二行的变量保持

执行完12行BOARD_NAME==$1== mini2440

(2)     创建到开发板相关头文件的链接

略过mkconfig文件中的一些没有起作用的行

#

# Create link to architecture specificheaders

#

01 if [ "$SRCTREE" !="$OBJTREE" ] ; then

02   mkdir-p ${OBJTREE}/include

03   mkdir-p ${OBJTREE}/include2

04   cd${OBJTREE}/include2

05   rm-f asm

06   ln-s ${SRCTREE}/include/asm-$2 asm

07   LNPREFIX="../../include2/asm/"

08   cd../include

09   rm-rf asm-$2

10   rm-f asm

11   mkdirasm-$2

12   ln-s asm-$2 asm

13 else

14   cd./include

15   rm-f asm

16   ln-s asm-$2 asm

17 fi

第一行判断源代码目录和目标文件目录是否一样,是可以选择在其他目录下编译u-boot,这样可以令源代码目录保持干净,可以同时使用不同的配置进行编译,不过一般是在代码目录下进行编译,所以第1行条件不满足,跳转到else执行,进入include目录,删除asm文件(这是上一次配置时建立的链接文件),然后再次建立asm文件,并令它链接向asm-$2目录,即asm-arm。

继续看代码

01 rm -f asm-$2/arch

02

03 if [ -z "$6" -o "$6"= "NULL" ] ; then

04   ln-s ${LNPREFIX}arch-$3 asm-$2/arch

05 else

06   ln-s ${LNPREFIX}arch-$6 asm-$2/arch

07 fi

08

09 if [ "$2" = "arm" ]; then

10   rm-f asm-$2/proc

11   ln-s ${LNPREFIX}proc-armv asm-$2/proc

12 fi

第1行删除asm-$2/arch目录,即asm-arm/arch。

$6== s3c24x0,所以03行不满足执行06行,LNPREFIX为空,所以这个命令实际上就是:ln -s arch-$6asm-$2/arch,即:ln -sarch-s3c24x0 asm-arm/arch。第10、11行重新建立asm-arm/proc文件,并让它链接向proc-armv目录。

(3)      创建顶层Makefile包含的文件include/config.mk

01 #

02 # Create include file for Make

03 #

04 echo "ARCH   = $2" >  config.mk

05 echo "CPU    = $3" >> config.mk

06 echo "BOARD  = $4" >> config.mk

07

08 [ "$5" ] && ["$5" != "NULL" ] && echo "VENDOR = $5">> config.mk

09

10 [ "$6" ] && ["$6" != "NULL" ] && echo "SOC    = $6" >> config.mk

对于./mkconfig mini2440arm arm920t mini2440 NULL s3c24x0命令,上面几行代码创建的config.mk文件内容如下:

ARCH = arm

CPU = arm920t

BOARD = mini2440

SOC = s3c24x0

(4)      创建开发板相关的头文件include/config.h。

01 #

02 # Create board specific header file

03 #

04 if [ "$APPEND" ="yes" ]       # Append toexisting config file

05 then

06   echo>> config.h

07 else

08   >config.h             # Create new configfile

09 fi

10 echo "/* Automatically generated -do not edit */" >>config.h

11

12 for i in ${TARGETS} ; do

13   echo"#define CONFIG_MK_${i} 1" >>config.h ;

14 done

15

16 cat << EOF >> config.h

17 #define CONFIG_BOARDDIR board/$BOARDDIR

18 #include <config_defaults.h>

19 #include <configs/$1.h>

20 #include <asm/config.h>

21 EOF

22 exit 0

前面说过,APPEND维持原值“no”,所以config.h被重新建立,它的内容如下:

/* Automatically generated - do not edit */

#include <configs/mini2440.h>"

这样mini2440就被间接包含了进来,现在再对照readme中的步骤,是不是豁然开朗了?

U-Boot还没有类似Linux一样的可视化配置界面(比如使用make menuconfig来配置),要手动修改配置文件include/config/<board_name>.h来裁减、设置U-Boot。

配置文件中有两类宏:

(1)一类是选项(Options),前缀为“CONFIG_”,它们用于选择CPU、SOC、开发板类型,设置系统时钟、选择设备驱动等。比如:

#define CONFIG_ARM920T1/* This is anARM920T Core*/

#defineCONFIG_S3C24101/* in a SAMSUNG S3C2410 SoC */

#define CONFIG_SMDK24101/* on a SAMSUNGSMDK2410 Board */

#define CONFIG_SYS_CLK_FREQ12000000/* theSMDK2410 has 12MHz input clock */

#define CONFIG_DRIVER_CS89001/* we have aCS8900 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 loadaddress*/

#define PHYS_FLASH_10x00000000 /* FlashBank #1 */

从下面的编译、连接过程可知,U-Boot中几乎每个文件都被编译和连接,但是这些文件是否包含有效的代码,则由宏开关来设置。比如对于网卡驱动drivers/cs8900.c,它的格式为:

#include <common.h>/* 将包含配置文件include/config/<board_name>.h*/

……

#ifdef CONFIG_DRIVER_CS8900

/* 实际的代码 */

……

#endif/* CONFIG_DRIVER_CS8900 */

如果定义了宏CONFIG_DRIVER_CS8900,则文件中包含有效的代码;否则,文件被注释为空。

可以这样粗糙地认为,“CONFIG_”除了设置一些参数外,主要用来设置U-Boot的功能、选择使用文件中的哪一部分;而“CFG_”用来设置更细节的参数。


原创粉丝点击