uboot和系統移植擴充套件--主Makefile分析
uboot version確定(Makefile的24-29行)
(1)uboot的版本號分3個級別:
- VERSION:主機板本號
- PATCHLEVEL:次版本號
- SUBLEVEL:再次版本號
- EXTRAVERSION:另外附加的版本資訊
(2)這4個用.分隔開共同構成了最終的版本號。
(3)Makefile中版本號最終生成了一個變數U_BOOT_VERSION,這個變數記錄了Makefile中配置的版本號。
(4)include/version_autogenerated.h檔案是編譯過程中自動生成的一個檔案,所以源目錄中沒有,但是編譯過後的uboot中就有了。它裡面的內容是一個巨集定義,巨集定義的值內容就是我們在Makefile中配置的uboot的版本號。
VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h
HOSTARCH和HOSTOS
(1)直接在shell中執行uname -m得到i686,得到的值其實你當前執行這個命令的電腦的CPU的版本號。(2)shell中的|叫做管道,管道的作用就是把管道前面一個運算式的輸出作為後面一個的輸入再去做處理,最終的輸出才是我們整個式子的輸出。
(3)HOSTARCH這個名字:HOST是主機,就是當前在做開發用的這臺電腦就叫主機;ARCH是architecture(架構)的縮寫,表示CPU的架構。所以HOSTARCH就表示主機的CPU的架構。
(4)這兩個環境變數是主機的作業系統和主機的CPU架構,得出後儲存備用,後面自然會用到。
HOSTARCH := $(shell uname -m | \ sed -e s/i.86/i386/ \ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ \ -e s/sa110/arm/ \ -e s/powerpc/ppc/ \ -e s/ppc64/ppc/ \ -e s/macppc/ppc/) HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ sed -e 's/\(cygwin\).*/cygwin/') export HOSTARCH HOSTOS
靜默編譯(50-54行)
(1)平時預設編譯時命令列會列印出來很多編譯資訊。但是有時候我們不希望看到這些編譯資訊,就後臺編譯即可。這就叫靜默編譯。
(2)使用方法就是編譯時make -s,-s會作為MAKEFLAGS傳給Makefile,在50-54行這段程式碼作用下XECHO變數就會被變成空(預設等於echo),於是實現了靜默編譯。
ifeq (,$(findstring s,$(MAKEFLAGS))) XECHO = echo else XECHO = : endif
2種編譯方法(原地編譯和單獨輸出資料夾編譯)(78-123)
(1)Makefile提供2種編譯管理方法。預設情況下是當前資料夾中的.c檔案,編譯出來的.o檔案會放在同一資料夾下。這種方式叫原地編譯。原地編譯的好處就是處理起來簡單。
(2)原地編譯有一些壞處:第一,汙染了原始檔目錄。第二的缺陷就是一套原始碼只能按照一種配置和編譯方法進行處理,無法同時維護2個或2個以上的配置編譯方式。
(3)為了解決以上2種缺陷,uboot支援單獨輸出資料夾方式的編譯(linux kernel也支援,而且uboot的這種技術就是從linux kernel學習來的)。就是在編譯時另外指定一個輸出目錄,將來所有的編譯生成的.o檔案或生成的其他檔案全部丟到那個輸出目錄下去。原始碼目錄不做任何汙染,這樣輸出目錄就承載了本次配置編譯的所有結果。
(4)具體用法:預設的就是原地編譯。如果需要指定具體的輸出目錄編譯則有2種方式來指定輸出目錄。(具體參考Makefile 56-76行註釋內容)
第一種:make O=輸出目錄
第二種:export BUILD_DIR=輸出目錄 然後再make
如果兩個都指定了(既有BUILD_DIR環境變數存在,又有O=xx),則O=xx具有更高優先順序,聽他的。(5)在Makefile中$(CURDIR)表示當前路徑
(6)OBJTREE:編譯出的.o檔案存放的目錄的根目錄。在預設編譯下,OBJTREE等於當前目錄;在O=xx編譯下,OBJTREE就等於我們設定的那個輸出目錄即BUILD_DIR。
(7)SRCTREE: 原始碼目錄,其實就是原始碼的根目錄,也就是當前目錄。
總結:在預設編譯下,OBJTREE和SRCTREE相等;在O=xx這種編譯下OBJTREE和SRCTREE不相等。Makefile中定義這兩個變數,其實就是為了記錄編譯後的.o檔案往哪裡放,就是為了實現O=xx的這種編譯方式的。(8)MKCONFIG在這裡定義,在後面使用,它的值就是我們原始碼根目錄下面的mkconfig。這個mkconfig是一個指令碼,這個指令碼就是uboot配置階段的配置指令碼。
######################################################################### # # U-boot build supports producing a object files to the separate external # directory. Two use cases are supported: # # 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. # # When none of the above methods is used the local build is performed and # the object files are placed in the source directory. # 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}) # Verify if it was successful. BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd) $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist)) endif # ifneq ($(BUILD_DIR),) OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) SRCTREE := $(CURDIR) TOPDIR := $(SRCTREE) LNDIR := $(OBJTREE) export TOPDIR SRCTREE OBJTREE MKCONFIG := $(SRCTREE)/mkconfig export MKCONFIG ifneq ($(OBJTREE),$(SRCTREE)) REMOTE_BUILD := 1 export REMOTE_BUILD endif # $(obj) and (src) are defined in config.mk but here in main Makefile # we also need them before config.mk is included which is the case for # some targets like unconfig, clean, clobber, distclean, etc. ifneq ($(OBJTREE),$(SRCTREE)) obj := $(OBJTREE)/ src := $(SRCTREE)/ else obj := src := endif export obj src # Make sure CDPATH settings don't interfere unexport CDPATH
include $(obj)include/config.mk(133行)
(1)include/config.mk不是原始碼自帶的,要在配置過程(make x210_sd_config)中才會生成這個檔案。因此這個檔案的值和我們配置過程有關,是由配置過程根據我們的配置自動生成的。
(2)我們X210在iNand情況下配置生成的config.mk內容為:
ARCH = arm
CPU = s5pc11x
BOARD = x210
VENDOR = samsung
SOC = s5pc110(3)我們在下一行(134行)export匯出了這5個變數作為環境變數。所以著兩行加起來其實就是為當前makefile定義了5個環境變數而已。之所以不直接給出這5個環境變數的值,是因為我們希望這5個值是可以被人很容易的、集中的配置的。
(4)這裡的配置值來自於2589行那裡的配置項。如果我們要更改這裡的某個配置值要到2589行那裡呼叫MKCONFIG指令碼傳參時的引數。
include $(obj)include/config.mk export ARCH CPU BOARD VENDOR SOC
x210_sd_config : unconfig @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110 @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
CROSS_COMPILE(136-182)
(1)CROSS_COMPILE是定義交叉編譯工具鏈的字首的。定義這些字首是為了在後面用。我們把字首和字尾分開還有一個原因就是:在不同CPU架構上的交叉編譯工具鏈,只是字首不一樣,字尾都是一樣的。因此定義時把字首和字尾分開,只需要在定義字首時區分各種架構即可實現可移植性。
(2)CROSS_COMPILE是被ARCH所確定的,只要配置了ARCH=arm,那麼我們就只能在ARM的那個分支去設定CROSS_COMPILE的值。這個設定值只要能保證找到那個交叉編譯工具鏈即可,不一定非得是全路徑的,相對路徑也可以。(如果已經將工具鏈匯出到環境變數,並且設定了符號連結,這樣CROSS_COMPILE = arm-linux-就可以)
(3)實際運用時,我們可以在Makefile中去更改設定CROSS_COMPILE的值,也可以在編譯時用make CROSS_COMPILE=xxxx來設定,而且編譯時傳參的方法可以覆蓋Makefile裡面的設定。
ifndef CROSS_COMPILE ifeq ($(HOSTARCH),$(ARCH)) CROSS_COMPILE = else ifeq ($(ARCH),ppc) CROSS_COMPILE = ppc_8xx- endif 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 ifeq ($(ARCH),i386) CROSS_COMPILE = i386-linux- endif ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif ifeq ($(ARCH),nios) CROSS_COMPILE = nios-elf- endif ifeq ($(ARCH),nios2) CROSS_COMPILE = nios2-elf- endif ifeq ($(ARCH),m68k) CROSS_COMPILE = m68k-elf- endif ifeq ($(ARCH),microblaze) CROSS_COMPILE = mb- endif ifeq ($(ARCH),blackfin) CROSS_COMPILE = bfin-uclinux- endif ifeq ($(ARCH),avr32) CROSS_COMPILE = avr32-linux- endif ifeq ($(ARCH),sh) CROSS_COMPILE = sh4-linux- endif ifeq ($(ARCH),sparc) CROSS_COMPILE = sparc-elf- endif # sparc endif # HOSTARCH,ARCH endif # CROSS_COMPILE export CROSS_COMPILE
相關文章
- [外掛擴充套件]系統主題管理套件
- 系統移植——uboot常用命令boot
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- windows系統磁碟擴容/擴充套件Windows套件
- Linux 檔案系統擴充套件Linux套件
- PHP 系統樹圖擴充套件元件PHP套件元件
- LVM : 擴充套件檔案系統的容量LVM套件
- 擴充套件.Django-許可權系統套件Django
- 2.12.uboot的移植2-從uboot官方標準uboot開始移植boot
- 讀構建可擴充套件分散式系統:方法與實踐15可擴充套件系統的基本要素套件分散式
- CentOS 系統下 PHP 怎麼新增擴充套件?CentOSPHP套件
- 乾貨丨如何水平擴充套件和垂直擴充套件DolphinDB叢集?套件
- 虛擬主機支援哪些擴充套件功能套件
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- uboot1: 啟動流程和移植框架boot框架
- linux系統掛載邏輯卷和擴充套件邏輯卷組Linux套件
- 未來系統擴充套件,報表怎麼辦?套件
- Sentinel 原理-如何為系統設定擴充套件點套件
- ubuntu24.04系統gnome46用到擴充套件Ubuntu套件
- 【SpringBoot】分析 SpringBoot 中的擴充套件點Spring Boot套件
- Bundler和Minifier Visual Studio擴充套件Nifi套件
- 安裝Swoole框架和擴充套件框架套件
- 擴充套件工具套件
- Sanic 擴充套件套件
- Mybatis擴充套件MyBatis套件
- SpringMVC 擴充套件SpringMVC套件
- ORACLE 擴充套件Oracle套件
- 工業和消費者HMI系統中的擴充套件記憶體套件記憶體
- 管理系統中風險是系統可用性和可擴充套件性的關鍵套件
- 使用Kotlin擴充套件函式擴充套件Spring Data案例Kotlin套件函式Spring
- JMeter 擴充套件開發:擴充套件 TCP 取樣器JMeter套件TCP
- Laravel 檔案系統擴充套件(支援 OSS+ 七牛)Laravel套件
- 如何重構CRM系統,滿足擴充套件的需求套件
- [外掛擴充套件]騰訊分析外掛套件
- 讀構建可擴充套件分散式系統:方法與實踐09可擴充套件資料庫基礎套件分散式資料庫
- 聊聊Spring擴充套件點BeanPostProcessor和BeanFactoryPostProcessorSpring套件Bean
- [外掛擴充套件]OneThink後臺自制主題,BigMan套件
- ?用Chrome擴充套件管理器, 管理你的擴充套件Chrome套件