u-boot原理分析第一課-------Makefile分析
本節課使用的u-boot是百問網的u-boot,編譯此u-boot,有兩步:1.配置:make 100ask24x0_config; 2.make編譯。
我們先看到配置的部分:100ask24x0_config:
我們看到它所執行的命令:@$(MKCONFIG)$(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0,對於變數MKCONFIG,我們可以查詢它的值:
首先,我們看到這個命令前面有個@,表示執行此命令時不打印出來(一般都會預設打印出來)。然後MKCONFIG的值是$(SRCTREE)/mkconfig,我們從字面意思不難發現SRCTREE是源目錄的意思,所以它應該是指源目錄下的mkconfig檔案。為了驗證一下我們再Linux搜尋一下看看是否有這個檔案:
我們看到,這個檔案是真實存在的。我們繼續看這條命令後面的部分,後面是:$(@:_config=),這是一種替換引用的用法(語法是:$(var : a = b)或${var : a = b}它的含義是把變數var的值中的每一個字結尾的a用b替換)。所以這裡是指100ask24x0_config去掉_config,也就是100ask24x0。這樣我們就把整個命令解析出來了:mkconfig100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0,mkconfig後的這些字元都是這個命令的引數。
那麼,mkconfig這個命令裡又是什麼呢?我們開啟看一下:
這是第一段程式碼,它的意思是,如果引數的個數大於0的話,就執行do後面的語句。後面的語句是一個case 結構語句,表示式是第2個引數的值,是否是--,-a,-n或者是其它的。這裡我們把之前的命令再次列出來然後對引數進行標記:
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULLs3c24x0
$0 $1 $2 $3 $4 $5 $6
顯然,這裡直接就break。我們繼續看後面的程式碼:
後面是一個表示式,BOARD_NAME的值為””,所以第一個條件不成立,因此BOARD_NAME=” 100ask24x0”,意思是我們的板子的名稱是100ask24x0。
我們接著看:
這兩句程式碼,如果引數的個數小於4個,滿足條件,後面的exit1得以執行;如果大於六個,滿足條件,後面的exit1得以執行。這裡的意思是,執行該命令的引數不能大於六個,也不能小於四個。(我們這裡共有六個引數,$0不算,它表示shell指令碼的名字)
這裡是列印Configuring for100ask24x0 board….這句話。
接著看:
這是一個if結構,條件是”$SRCTREE”!=”$OBJTREE”,我們去Makefile這裡看看這兩個變數的值是多少:
我們看到,這兩個變數的值都是CURDIR。所以,條件不成立,直接執行else的程式碼:
首先,進入到當前目錄裡的include目錄,然後刪掉asm檔案,然後建立一個asm的軟連結,指向asm-arm(檔案/目錄)(軟連結可以理解為一個快捷方式)
接著看:
首先,先刪掉asm-arm的arch目錄。接下來是一個if結構,條件是如果$6的字串為空或者$6的值為”NULL”的話就執行then後面的操作,這裡$6並不為空也不為”NULL”,所以會執行else後的語句:ln –s ${LNPREFIX}arch-$6asm-$2/arch,LNPREFIX這個變數並沒有定義,所以這裡命令是:
Ln –s arch-s3c24x0asm-arm/arch
也就是建立一個軟連結,其指向arch-s3c24x0這個目錄。後面又是一條if結構,條件是$2=arm,的確等於,所以會執行後面的語句:首先,刪掉asm-arm/proc這個目錄,然後再建立一個proc的軟連結,指向proc-armv這個目錄。
接著看:
首先,建立一個檔案:config.mk,其內容為“ARCH = $arm”。然後”CPU = $ arm920t”追加到config.mk,然後”BOARD = 100ask24x0”追加到config.mk。
接著看:
首先,$5是有值的,所以可以執行下個條件,$5等於”NULL”,所以後面的條件不能執行。下一個條件,$6是有值的,$6不等於”NULL” ,所以後面的條件可以執行:”SOC =s3c24x0”追加到檔案config.mk中。
接著看:
這又是一條if結構,條件是$APPEND等於yes,但APPEND的值是””,所以我們直接執行else後面的語句,建立config.h檔案。
最後兩句是把相關內容追加到config.h中。
最後,我再總結一下在這個config檔案裡一共做了些什麼事情: 1.確定開發板的名稱BOARD_NAME
2.建立到平臺/開發板相關的標頭檔案
3.建立頂層Makefile包含的檔案include/config.mk
4.建立開發板相關的標頭檔案include/config.h
接下來,我們看一下編譯後的過程,也就是make後的過程:
變數obj的值為: ,而OBJTREE的值為CURDIR。所以,$(obj)u-boot.hex則表示$(CURDIR)/u-boot.hex,下面的相同。這裡我們直接看到最後的
這句。這裡我們直接make一下,看看這一句顯示出來是什麼:
(該圖來自魚樹筆記,非本作者,若有侵權,請聯絡,立馬刪除)
cd /work/arm920t/sourceCode/u_boot/u-boot-1.1.6&& 這是進入$(LNDIR);
arm-linux-ld -Bstatic -T/work/arm920t/sourceCode/u_boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000。這是連結, -T,連結了連結指令碼 u-boot.lds還連結了個程式碼段的基地址-Ttext0x33F80000。接下來,我們看一下連結指令碼的內容:
我們可以看到,在這個連結腳本里,它的當前的地址從0開始, 而程式碼段則放在0x33F80000的地方。在程式碼段裡,最開始的程式碼則是cpu/arm920t/start.o.從這裡我們可以看到,對於一個64M的SDRAM,有512K是用來放置u-boot的。(3400000-33f80000):
在u-boot裡,第一段執行的程式碼是start.o。