1. 程式人生 > >U-boot根目錄下的config.mk分析

U-boot根目錄下的config.mk分析

原文地址:http://blog.csdn.net/qq_28992301/article/details/51804180

U-boot根目錄下的config.mk分析

該config.mk位於uboot原始碼的根目錄下, 其包含了子目錄下許多同名的config.mk。所以千萬注意這些同名檔案的主次區別 
該檔案內容主要結構為:

1. 設定各種路徑 
2. 設定主機環境的編譯選項 
3. 確定各交叉編譯工具 
4. 確定各種級別的編譯選項 
5. 指定連結指令碼 
6. 獲得起始連結地址 
7. 設定標頭檔案搜尋路徑 
8. 使用起始連結地址

 
9. 設定自動推導規則

需要注意的是,結構順序並不一定代表程式碼執行順序,關於程式碼的執行順序以及推薦閱讀順序請移步 [ U-boot配置及編譯階段流程巨集觀分析 ]

1. 設定各種路徑

ifneq ($(OBJTREE),$(SRCTREE))
ifeq ($(CURDIR),$(SRCTREE))
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif

obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
src := $(if $(dir),$(SRCTREE
)/$(dir)/,$(SRCTREE)/) $(shell mkdir -p $(obj)) else obj := src := endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 本段程式碼還是在進行原地編譯和外部輸出編譯的一些路徑設定
  • 說到底,其實是把主Makefile中和路徑有關的變數匯入進來
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =

ifeq ($(ARCH),ppc)
ifeq ($(
CROSS_COMPILE)
,powerpc-netbsd-) PLATFORM_CPPFLAGS+= -D__PPC__ endif ifeq ($(CROSS_COMPILE),powerpc-openbsd-) PLATFORM_CPPFLAGS+= -D__PPC__ endif endif ifeq ($(ARCH),arm) ifeq ($(CROSS_COMPILE),powerpc-netbsd-) PLATFORM_CPPFLAGS+= -D__ARM__ endif ifeq ($(CROSS_COMPILE),powerpc-openbsd-) PLATFORM_CPPFLAGS+= -D__ARM__ endif endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 本段都是和powerpc有關的交叉編譯工具鏈的設定

2.設定主機環境的編譯選項(72至85行)

CONFIG_SHELL    := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
            else if [ -x /bin/bash ]; then echo /bin/bash; \
            else echo sh; fi ; fi)

ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc)
HOSTCC      = cc
else
HOSTCC      = gcc
endif
HOSTCFLAGS  = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTSTRIP   = strip
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • shell的一些配置過程,和主機編譯器的一些配置

3. 確定各交叉編譯工具

cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
        > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
  • 1
  • 2
  • 3
  • 本段是編譯連結的一些過程選項
AS  = $(CROSS_COMPILE)as
LD  = $(CROSS_COMPILE)ld
CC  = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR  = $(CROSS_COMPILE)ar
NM  = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP   = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB  = $(CROSS_COMPILE)RANLIB
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 確定了完整的各交叉編譯工具,通過頂層makefile中得到的CROSS_COMPILE變數(即工具鏈的字首),由此定義各工具的名稱

4. 確定各種級別的編譯選項

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 本段最開始包含了一個autoconf.mk檔案,此檔案也不是原始碼自帶的,其內容全部都是CONFIG_開頭的變數,makefile利用這些變數來指導編譯過程的走向(.c檔案條件編譯)
  • autoconf.mk其實是由頂層Makefile利用根目錄下include/configs/x210_sd.h生成的,其內容與x210_sd.h沒什麼區別,其生成方式在頂層makefile的470多行左右
  • uboot的可移植性很大程度來源於x210_sd.h檔案,它也是移植工作的關鍵所在
  • 後面幾行分別inlude了和ARCH、CPU、SOC、VENDOR、BOARD相關的子config.mk,也就是包含了各種級別的編譯屬性選項

5. 指定連結指令碼

ifneq (,$(findstring s,$(MAKEFLAGS)))
ARFLAGS = cr
else
ARFLAGS = crv
endif
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
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
endif
OBJCFLAGS += --gap-fill=0xff
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 本段最開始先配置了一些編譯選項
  • 隨後檢測是否定義過LDSCRIPT這個和連結指令碼有關的變數,如果沒有定義,則判斷CONFIG_NAND_U_BOOT(autoconf.mk中定義)這個值是否為y
  • 若未使用nandflash,則連結指令碼為指定路徑下的u-boot.lds。若使用了nandflash,則連結指令碼為指定路徑下的u-boot-nand.lds-

6. 獲得起始連結地址

gccincdir := $(shell $(CC) -print-file-name=include)

CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)       \
    -D__KERNEL__
ifneq ($(TEXT_BASE),)
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 本段最開始先配置了一些編譯選項,隨後做了一些和TEXT_BASE相關的工作
  • 在前面120多行左右include了一個board級別的config.mk檔案 ,這個.mk檔案原始碼中不存在,是在頂層makefile中由x210_sd_config建立的,並在ARCH、SOC等變數後面新增TEXT_BASE,展開後就獲得了一個TEXT_BASE變數
  • TEXT_BASE這個變數的含義是uboot將來被連結時的起始地址,是規定好的,但由於uboot使用虛擬地址對映,所以這個地址並不是真正的實體地址
  • 最後進行判斷,如果TEXT_BASE不為空,就將其設定到CPPFLAGS裡面去-

7. 設定標頭檔案搜尋路徑

ifneq ($(OBJTREE),$(SRCTREE))
CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
endif

CPPFLAGS += -I$(TOPDIR)/include
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc   \
    -isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 本段設定了標頭檔案的搜尋路徑,添加了頂層目錄下的include資料夾作為搜尋路徑。然後進行了一些其他設定(比如禁止標準的include路徑)
  • 這樣,編譯器在編譯的時候就能正確的讀取到include資料夾下的標頭檔案(其實是配置階段建立的符號連結)了

8.使用起始連結地址

LDFLAGS += -Bstatic -T $(LDSCRIPT) $(PLATFORM_LDFLAGS)
ifneq ($(TEXT_BASE),)
LDFLAGS += -Ttext $(TEXT_BASE)
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 本段是把TEXT_BASE用-Ttext傳給了連結指令碼,故連結指令碼將從TEXT_BASE開始連結

9. 設定自動推導規則

ifndef REMOTE_BUILD

%.s:    %.S
    $(CPP) $(AFLAGS) -o [email protected] $<
%.o:    %.S
    $(CC) $(AFLAGS) -c -o [email protected] $<
%.o:    %.c
    $(CC) $(CFLAGS) -c -o [email protected] $<

else

$(obj)%.s: %.S
    $(CPP) $(AFLAGS) -o [email protected] $<
$(obj)%.o: %.S
    $(CC) $(AFLAGS) -c -o [email protected] $<
$(obj)%.o: %.c
    $(CC) $(CFLAGS) -c -o [email protected] $<
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 本段是makefile的自動推導規則,和頂層Makefile內的規則配合使用,就能實現眾多檔案的編譯