1. 程式人生 > >u-boot的編譯及配置 mkconfig

u-boot的編譯及配置 mkconfig

原文連結http://blog.csdn.net/ghostyu/article/details/6961232

剛開始接觸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"

執行完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_”用來設定更細節的引數。