這裡是對uboot的Makefile做的一個比較詳細的分析

生成版本信息

VERSION = 1
...
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h

軟體都是有不同版本的,uboot也不例外,在makefile開頭幾行就定義了版本信息,並導出到一個頭文件中

導出架構信息

HOSTARCH := $(shell uname -m |
sed -e s/i.86/i386/
...

HOSTOS := $(shell uname -s | tr [:upper:] [:lower:] |
sed -e s/(cygwin).*/cygwin/)

export HOSTARCH HOSTOS

獲得當前主機的架構和系統,導出到環境變數備用

靜默安裝

靜默安裝原理很簡單,只不過是把echo替換成了:

靜默安裝時腳本就不會輸出那麼多沒用信息了

uboot鏈接文件產生位置

# U-boot build supports producing a object files to the separate external
# directory. Two use cases are supported:
...

和其他大型的項目類似,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

實現的過程

這部分看看腳本就會明白,這裡大概說一下

先判斷定義的是O還是直接定義的BUILDDIR,定義的是O的話就把O的值賦給BUILDDIR(非空)

接下來就定義並導出了OBJTREE(BUILD_DIR設置過來的鏈接文件的位置) SRCTREE(當前目錄設置來的源碼目錄) TOPDIR(當前目錄設置為頂層) LNDIR(OBJTREE保存為鏈接文件位置)

定義並導出MKCONFIG(SRCTREE下的mkconfig腳本,用於配置uboot)

如果OBJTREESRCTREE不等就定義並導出REMOTE_BUILD,並obj := $(OBJTREE) src := $(SRCTREE)

配置交叉編譯工具鏈

$(obj)include/config.mk導入ARCH CPU BOARD VENDOR SOC這幾個變數,config.mk這個文件是make x210_sd_config產生的,x210sdconfig在Makefile的最後一部分有定義,這是為了確保Makefile的通用性

x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

之後就是通過判斷ARCH的不同,使用不同的CROSS_COMPILE

然後就是導入$(TOPDIR)/config.mk中的其他配置

$(TOPDIR)/config.mk

大概看了下,這個文件提供了編譯選項和變數

導入make變數

定義的CROSS_COMPILE會在$(TOPDIR)/config.mk中使用

AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
...

導入自動生成配置

然後導入$(OBJTREE)/include/autoconf.mk,這是一個根據開發板自動生成(根據$(TOPDIR)/include/configs/x210_sd.h定義生成)的腳本,裡面定義了一些硬體相關的配置

CONFIG_CMD_FAT=y
CONFIG_USB_OHCI=y
CONFIG_SYS_CLK_FREQ=24000000
...

再根據ARCH等變數,導入對應的config腳本

編譯選項參數

這一部分定義了一堆的FLAGS

LDSCRIPT定義鏈接腳本是否使用nand版

ifndef LDSCRIPT
#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
else
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif

TEXT_BASE是在Makefile中定義的uboot鏈接地址,上面的配置交叉編譯工具鏈里就有寫

這裡的地址是虛擬地址,物理地址取決於uboot中的地址映射

uboot鏈接對象

# U-Boot objects....order is important (i.e. start must be first)

OBJS = cpu/$(CPU)/start.o
ifeq ($(CPU),i386)
OBJS += cpu/$(CPU)/start16.o
OBJS += cpu/$(CPU)/reset.o
...

這一部分是鏈接一些必要的庫和.o文件

ALL標籤

當我們在命令行使用make時,就會執行這一部分的腳本

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

all: $(ALL)
...

在make編譯後,我們也能看到這些對象

greedyhao@greedyhao-PC:.../qt_x210v3s_160307/uboot$ ls | grep u-boot
u-boot
u-boot.bin
u-boot.dis
u-boot.map
u-boot.srec

unconfig

unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk
...

注意到上面配置交叉編譯工具鏈中的x210sdconfig和這裡的unconfig有關,現在再對x210sdconfig的這段腳本做進一步的探討

$(@:config=)會把x210sdconfig匹配成x210sd,從而使得mkconfig得到了6個參數x210_sd arm s5pc11x x210 samsung s5pc110

mkconfig

接下來就進入到mkconfig

while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done

這段腳本的作用就是對傳入的第一個參數$1進行匹配,x210_sd只能匹配上*

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

這裡就將參數1的值賦給了BOARD_NAME

[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1

這裡是為了避免參數的數量不正確

之後就是為架構的指定頭文件創建符號鏈接,這是為了可移植性,通過判斷傳入的ARCH CPU BOARD這幾個參數,鏈接不同的頭文件

各種適配

再接下來的內容就是各種系統下的適配,配置交叉編譯工具鏈的腳本也是這部分的內容

make的其他選項

clean:
@rm -f $(obj)examples/82559_eeprom $(obj)examples/eepro100_eeprom
...
clobber: clean
...
distclean: clobber unconfig
...
backup:
...


個人博客

公眾號:greedyhao


推薦閱讀:
相关文章