uboot主編譯腳本分析
這裡是對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)
如果OBJTREE和SRCTREE不等就定義並導出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
推薦閱讀: