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