您好,登錄后才能下訂單哦!
uboot為用戶提供兩種編譯方式,一種是在uboot當前目錄下進行編譯,第二種方式就是將編譯生成的文件輸出到指定的目錄下。
1) Add O= to the make command line
# 'make O=/tmp/build all'
#
# 2) Set environement variable BUILD_DIR to point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
#
# The second approach can also be used with a MAKEALL script
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
# Command line 'O=' setting overrides BUILD_DIR environent variable.
在這個注釋中可以看出uboot的開發者是通過O來指定一個輸出目錄的,第二種方法又包含兩種操作方法
(1)在命令行中添加O=/tmp/build all指定文件輸出的位置
這里要注意的是在配置和編譯時都要加上O=/tmp/build all來指定目錄
路徑
(2)先設置環境變量 export BUILD_DIR=/tmp/build(路徑可根據自己需要確定),然后make或者在設置完環境變量之后執行MAKEALL腳本./MAKEALL
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
27~37行代碼主要就是針對上述的兩種編譯方法設計的,當O被我們定義為一個目錄時命令$(origin O)會返回"command line",這時BUILD_DIR就
指向我們由O定義的那個目錄,如果我們指定的O不是通過" "指定,那么
就由saved-output來指向$(BUILD_DIR)
37行當${BUILD_DIR}目錄不存在時,就會建立一個目錄,之后進入剛剛創建的目錄下,并且顯示當前路徑,如果返回值為真,則不顯示任何信息,否則打印出*** output directory "" does not exist. Stop.這樣的信息。
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
定義OBJTREE、SRCTREE、TOPDIR、LNDIR四個變量
如果$(BUILD_DIR)返回值為真,則OBJTREE為$(BUILD_DIR)(我們在開始時指定的那個目錄),否則為$(CURDIR)(我們的當前目錄,即使uboot根目錄),TOPDIR、LNDIR就順理成章了
MKCONFIG := $(SRCTREE)/mkconfig
定義變量MKCONFIG,它所指向的就是uboot目錄下的mkconfig腳本
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
$(obj) and $(src)是在config.mk下定義的兩個變量,但是在主Makefile下的一些目標也需要它們,所以就在這里定義它們兩個
在進行配置時我們沒有指定輸出目錄,所以這里$(OBJTREE)和$(SRCTREE)相同,故$(obj)和$(src)都為空
ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
當$(obj)include/config.mk按字節展開和$(obj)include/config.mk相同時,包含uboot/include/config.mk
ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE =
else
ifeq ($(ARCH),arm)
#CROSS_COMPILE = arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.4.1-eabi-cortex-a8/usr/bin/arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
CROSS_COMPILE = /usr/local/ARM/arm-2009q3/bin/arm-none-linux-gnueabi-
endif
開始定義交叉編譯工具鏈,因為我們是編譯的ARM架構的代碼,所以使用ARM的交叉編譯工具。
# load other configuration
include $(TOPDIR)/config.mk
如注釋所寫,我們需要引入一些其他的配置,所以通過include來包含這些文件,這個文件就是uboot根目錄下的config.mk文件
所以下面我們就要轉向分析這個config.mk文件,之后再回來分析主Makefile。
#Load generated board configuration
sinclude $(OBJTREE)/include/autoconf.mk
ifdef ARCH
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
endif
ifdef CPU
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
endif
ifdef SOC
sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules
endif
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
89~108引入已經生成的與開發板相關的配置文件
在進行相關配置make x210_sd_config操作時,ARCH、CPU、SOC、VENDOR、BOARD的相關信息
通過@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110這條語句使用uboot下的mkconfig腳本到處到uboot/include/config.mk中,所以這些變量都是已經定義了的將上面代碼提及的相關目錄下的config.mk文件用sinclude(相當于include)包含起來。
LDFLAGS += -Ttext $(TEXT_BASE) 進行重定位,鏈接到鏈接地址
ifndef REMOTE_BUILD
%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
else
$(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif
進行Makefile隱式規則推導
現在回到主Makkefile下繼續分析:
LIBS += cpu/ixp/npe/libnpe.a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/ext4/libext4fs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += drivers/bios_emulator/libatibiosemu.a
LIBS += drivers/block/libblock.a
LIBS += drivers/dma/libdma.a
LIBS += drivers/hwmon/libhwmon.a
LIBS += drivers/i2c/libi2c.a
LIBS += drivers/input/libinput.a
LIBS += drivers/misc/libmisc.a
LIBS += drivers/mmc/libmmc.a
LIBS += drivers/mtd/libmtd.a
LIBS += drivers/mtd/nand/libnand.a
LIBS += drivers/mtd/nand_legacy/libnand_legacy.a
LIBS += drivers/mtd/onenand/libonenand.a
LIBS += drivers/mtd/ubi/libubi.a
LIBS += drivers/mtd/spi/libspi_flash.a
上面是類似代碼的一小部分,添加相關庫文件
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) $(obj)u-boot.dis
ifeq ($(ARCH),blackfin)
ALL += $(obj)u-boot.ldr
endif
添加make操作的原料,通過執行make命令生成u-boot.srec、u-boot.bin、System.map、u-boot.dis、u-boot.ldr等文件
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep \
$(obj)board/$(VENDOR)/$(BOARD)/config.mk
上述代碼需要結合下面的代碼分析:
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
當執行make x210_sd_config時,unconfig作為依賴先被執行,而unconfig又同時是一個目標,作用和我們寫簡單Makefile中的clean作用相同的,就是刪除已經生成的相關的配置文件,這樣即使是在已經配置后仍可以在進行配置,因為在進行真正的配置操作時,上次的配置生成的文件已經被刪除
在執行配置命令時引入了$(MKCONFIG)這個就是uboot下的mkconfig腳本
$(@:_config=) arm s5pc11x x210 samsung s5pc110 這些是傳入mkconfig的參數
這里$(@:_config=)需要解釋:這條命令的意思就是將目標字符串中的_config用空字節代替,所以,傳入mkconfig中的6個參數為:
x210_sd arm s5pc11x x210 samsung s5pc110
$1 $2 $3 $4 $5 $6
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
$# 表示參數的個數,所以$#=6
匹配$1的結果是匹配到*)跳出while;
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
判斷${BOARD_NAME}返回值是否為真,若為假,則BOARD_NAME=$1
在這里BOARD_NAME="" 所以BOARD_NAME=x210_sd
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
說明傳入mkconfig的參數個數為4~6個才能正確執行,否則,會發生錯誤
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -rf asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -rf asm
mkdir asm-$2
ln -s asm-$2 asm
else
cd ./include
rm -rf asm
ln -s asm-$2 asm
fi
建立一個符號鏈接 asm -> asm-arm
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
我們的$6既不是空也不是“NULL”,所以會建立一個鏈接
asm-arm -> arch-s5pc110
# create link for s5pc11x SoC
if [ "$3" = "s5pc11x" ] ; then
rm -f regs.h
ln -s $6.h regs.h
rm -rf asm-$2/arch
ln -s arch-$3 asm-$2/arch
fi
開始創建與SOC相關的鏈接 regs.h -> s5pc110.h和
arch -> arch-s5pc11x
# Create include file for Make
#
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
導出 ARCH = arm
CPU = s5pc11x
BOARD = x210
VENDOR = samsung
SOC = s5pc110
到include下的config.mk文件中,注意的是原來在include下是不存在
config.mk文件的,這個文件是由echo創建并傳入內容的
Create board specific header file
#
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
$APPEND在定義時為no,所以會創建一個新的config.h文件
這個 文件的內容為
/* Automatically generated - do not edit */
#include <configs/x210_sd.h>
這里的configs目錄下的x210_sd.h為具體開發板所需要的宏定義,譬如:
#define CONFIG_SECURE_ROOTFS_SIZE 0x0013D000
#endif
#define BOOT_ONENAND 0x1
#define BOOT_NAND 0x2
#define BOOT_MMCSD 0x3
#define BOOT_NOR 0x4
#define BOOT_SEC_DEV 0x5
#define AT070TN92 1
#define VGA_800X600 2
#define VGA_1024X768 3
#define TRULY043 4
#define VGA_1440X900 5
#define VGA_1280X1024 6
#define DISP_MODE AT070TN92
//#define DISP_MODE VGA_800X600
//#define DISP_MODE VGA_1024X768
//#define DISP_MODE VGA_1440X900
//#define DISP_MODE TRULY043
//#define DISP_MODE VGA_1280X1024
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。