uboot移植準備工作二

第一部分
2.3.1uboot配置編譯實踐
1)源頭的源代碼時uboot官網下載的。這個下載的源代碼可能沒有你當前使用的開發板的移植,甚至找不到當前開發板使用的SoC對應的移植版本。
2)SoC廠商在退出一款SoC後,廠商的工程師會去uboot官網下載一個uboot,根據自己Soc進行第一步移植,移植的目標是廠商推出的開發板。(譬如三星的S5PV210芯片廠商出的開發板就叫SMDKV210),所以三星的工程師移植的uboot是根據他們自己的SMDKV210開發板移植的。
3)具體的開發板提供商(譬如X210的生產商深圳市九鼎科技)首先購買三星的SMDKV210開發板,然後進行裁剪(把一些無用的接口功能裁剪去,配置降低一下,某些配置會被替換)。硬件替換和裁剪之後生成的新的開發板和三星官方的SMDKV210有所不同,因此uboot也不同,但是因爲SoC是相同的,所有相似度至少60%以上,所有具體開發板供應商會以三星SMDK210中移植的uboot爲藍本來移植的到自己的開發板的一個uboot移植。我們買x210開發板時廠商光盤中帶的BSP中的uboot源碼就是他移植過的。

1. tq210移植過的uboot開發板光盤的BSP中。BSP就是board support package(板級支持包,一般由開發板供應商提供),裏面的內容就是這個開發板的所有相關的源代碼,文檔,教程等。
2. 將整個BSP打包文件弄到linux的原生目錄中取解壓分析,不要在windows中的共享文件夾中解壓打開。
3. 我們在linux下維持一份uboot,在windows下也維持一份uboot,在我們沒有開始任何工作之前,這兩份uboot內容一樣,都是天嵌官方uboot內容,我們這樣做的目的;在linux中進行編譯,在windows下進行代碼分析和觀看。(windows下有sourceinsight等很好的工具輔助我們看代碼,編輯代碼,在linux下編譯和看代碼都很麻煩。)
4. 配置 uboot和linux kernel等複雜項目都不能直接編譯,都要先配置,然後編譯。 Uboot也要先配置,方法:首先cd進入源碼的根目錄,配置的原因,uboot支持很多開發板,但編譯後的鏡像只能用在某一個開發板上,所有需要配置。一般配置的文件在Makefile中搜索開發板的名字。在根目錄下執行make TQ210_config 配置命令。一般會出現 Configuring for TQ210 board…. 接下來就是編譯,一定要檢查arm-linux-gcc 對不對,檢查分兩步,1.檢查當前編譯環境中有沒有安裝合適的arm-linux-gcc。2.檢查當前目錄下(uboot根目錄)的makefile中編譯器的設置是否正確。在工程的總的makefile中會設置交叉編譯工具鏈的路徑和名字,必須確保這個路徑和名字和我們自己裝的一致,否則會編譯出錯。確保以上2點,即可進行編譯,編譯很簡單,直接make,或者make -j4

1. uboot的源碼目錄分析1
天嵌官方uboot和三星原版uboot對比,以天嵌官方爲藍本來學習的,以三星官方的這份爲對照。不同版本的uboot或者同一版本不同人移植的uboot,可能目錄結構和文件內容都有所不同。將來大家懂了之後大家可以自己添加,更改,刪除uboot。天嵌在以三星的uboot爲原材料進行移植時,把三星版本的uboot中很多不必要的文件夾,文件給刪掉了。這個刪掉把很多用不到的刪掉。

2. 各個文件介紹:
1. .gitignore git工具的文件,git是一個版本管理工具。(類似的還有個svn),這個文件和git有關,和uboot本身無關,不用去管。
2. arm_config.mk 後綴是.mk,是一個Makefile文件,將來在某個makefile中會調用它。
3. 三個changelog文件,修改記錄文件,該文件記錄了這個uboot項目的版本變遷及每個版本較上個版本修改的記錄。正式的項目都有這些記錄的。主要是給維護uboot的工程師用的。
4. Config.mk 和arm_config.mk差不多的性質
5. COPYING.版權聲明,uboot本身是GPL許可證的。
6. CREDITS. 鳴謝。裏面記錄了對uboot有貢獻的人。
7. Image_split。一個腳本,看說明是用來分割uboot.bin到BL1,暫時用不到,先不管。
8. MAINTAINERS 維護者,就是當前參與維護uboot源碼的社區工作者。
9. MAKEALL.一個腳本,應該是幫助編譯uboot的。
10. Makefile.這個很重要,是uboot源代碼的主makefile,將來整個uboot被編譯時就用這個makefile管理編譯的,所以我們在下個課程中研究uboot配置編譯過程就要分析這個makefile 。
11. Mkconfig 這個很重要,是uboot配置階段的主要配置腳本。Uboot的可移植性很大程度就是靠這個配置腳本在維護的。我們在下個課程中研究uboot配置編譯過程就要分析這個配置腳本。
12. Mkmovi。 一個腳本,和Inand、sd卡啓動有關。
13. Readme。所有的軟件都有reandme,一般拿到一個東西先讀readme,這個東西就是一個簡單的說明書。
14. Rules.mk 這個文件是我們uboot的makefile使用的規則,本身很非常重要,但是我們不去分析,不去看到
以上這些文件。對我們比較重要的,需要認真看的2個,mkconfig和makefile。一個負責uboot的配置,一個負責編譯。需要詳細解釋。


Uboot源碼目錄分析:
1. API: 硬件無關的功能函數的API.uboot移植時基本不用管,這些函數是uboot本身使用的。
2. Api_examples: api相關測試實例代碼。
3. Board :board是板的意思,板就是開發板,board文件夾下每個文件代表一個開發板。這個文件夾下面放的文件就是用來描述這一個開發板的信息的。Board目錄下有多少個文件夾,就表示當前這個uboot已經被移植到多少個開發板上(當前的uboot支持多少個開發板)。問題一;思考uboot如何支持多套開發板,如何具有可移植性。 問題二:board下那麼多文件夾,究竟如何確定具體使用的是哪一個?uboot在配置階段會有一些手段幫我們來確定具體使用的是board目錄下的哪一個文件夾。問題三:開發板越來越多,board目錄下文件夾越來越多,不方便管控。於是乎uboot就新增了一種機制,可以在board目錄下不直接放開發板目錄,而是在board下放廠家目錄(vendor目錄,以具體芯片廠商名字命名),然後將這個IC廠商的所有芯片開發板都丟到這個vendor目錄下面去。所以大家會發現我們TQ210對應的開發板目錄在/board/Samsung/EmbedSky/TQ210.多了這層目錄會影響配置階段,在uboot的配置階段要注意時的路徑深度和實際存放要對應,不然配置後編譯時找不到文件編譯就會失敗。注意一個細節就是歷史原因造成的兼容性麻煩。最開始board目錄下就是開發板名字,後來才改成廠商名字。但是因爲要向前兼容,同一個廠商原來還在外面的開發板並沒有挪用到廠商名字下。
注意:強調一下,uboot的配置階段(其實就是根目錄下面的mkconfig腳本和Makefile中配置有關的部分)主要解決的問題就是在可移植性領域能夠幫助我們確定具體的文件夾路徑,然後編譯時可以應該找到的文件,才能編譯成功。因此board目錄下的不同會造成配置時的不同。如果移植沒注意這裏,肯定會失敗。
4. Common : common是普遍的普通的。這個文件夾下放的一些與具體硬件無關的普通使用的一些代碼。譬如控制檯實現,crc校驗。但是更多的主要是兩類:一類是cmd開頭的,是用來實現uboot的命令系統的;另一類是env開頭的,是用來實現環境變量的。
5. Cpu:這個目錄是Soc相關的,裏面存放的代碼都是soc相關初始化和控制代碼(譬如cpu的,中斷的,串口等soc內部外設的,包括起始代碼start.S也在裏面。) 裏面很多子文件夾,每一個子文件夾就是一個soc系列。這個文件夾是嚴格和硬件相關的,因此一直也要注意。但是因爲這個文件夾內都是soc有關的。我們自己的開發板和三星的開發板雖然板子設計不同但是soc都是同一個,一般不需要怎麼改。
6. Disk。磁盤有關的,沒研究過,沒用過。
7. Doc。文檔目錄,裏面存放了很多uboot相關文檔,這些文檔可以幫我們理解uboot代碼。但是純英文
8. Drivers。顧名思義,驅動,這裏面放的就是從linux源代碼中扣出來的原封不動的linux設備驅動,主要是開發板上必須用到的一些驅動,如網卡驅動,inand/sd卡 nand flash等驅動。要知道:uboot中的驅動其實就是linux中的驅動,uboot在一定程度上移植了linux驅動給自己用。但是linux是操作系統而uboot是個裸機程序,因此這種移植會有不同,讓我說,uboot中的驅動其實是linux中驅動的一部分。
9. Example:實例代碼。沒用過
10. Fs:文件系統0 filesystem.這個也是從linux源代碼中移植過來的。用來管理flash等資源
11. Include:頭文件的目錄,uboot和linux kernel在管理頭文件時都採用同一個思路,就是把所有頭文件全部集中存放在include目錄下,而不是頭文件跟着自己對應c文件。所有在uboot中頭文件包含時路徑結構要在這裏去找。
12. Lib_開頭的一些 (典型的lib_arm和lib_generic)架構相關的庫文件。譬如lib_arm裏面就是arm架構使用的一些庫文件。Lib_generic裏面所有架構通用的庫文件。這類文件夾中的內容移植時基本不用管。
13. Libfdt。設備樹有關的。Linux內核在3.4左右的版本的時候更改了啓動傳參的機制,改用設備樹進行啓動傳參,進行硬件信息的描述了。
14. Nand_spl nand相關的。
15. Net 。網絡相關的。譬如uboot中的tftp nfs ping 命令,都是在這裏實現的。
16. Onenand開頭的。是onenand相關代碼,是三星加的。標準uboot中應該沒有的。
17. Post。沒關注過。
18. Sd_fusing。這裏面代碼實現了燒錄uboot鏡像到SD卡的代碼。後面要仔細研究的。
19. Tools:裏面是一些工具類代碼。譬如mkimage.

總結:會用的到的 board common cpu drivers include lib_arm sd_fusing lib_generic

第四部分:uboot主Makefile分析1
1.1 uboot version確定 (Makefile 24-29行) U_BOOT_VERSION “1.3.4xyz”
1)uboot版本號分爲4個級別:
VERSION : 主板號
PATCHLEVEL : 次版本號
SUBLEVEL : 再次版本號
EXTRAVERSION : 另外附加的版本信息
這4個用 . 分隔開共同構成了最終的版本號。
2)makefile中版本號最終生成一個變量U_BOOT_VERSION,這個變量記錄了Makefile中配置的版本號。 Include/version_autogenerated.h文件是編譯過程中自動生成的一個文件,所有源目錄中沒有,但是編譯過後的uboot中就有了。它裏面的內容是一個宏定義,宏定義的值就是我們在Makefile中配置的uboot版本號。
3)驗證方法:自己修改主makefile中幾個version有關的變量,然後編譯uboot,然後燒錄到SD卡中,從SD卡中啓動,然後去看啓動時uboot打印出來的版本信息,看看變化是不是和自己的分析一致。


2.1 HOSTARCH和HOSTOS
1. 直接在shell中執行uname -m得到i686,得到的值其實是你當前執行這個命令的電腦的cpu的版本號。
2. shell中的|叫管道,管道的作用就是把管道前面一個運算式的輸出作爲後面一個的輸入再去做處理,最終的輸出纔是我們整個式子的輸出。
3. HOSTARCH這個名字:HOST主機,就是當前在做開發用的這臺電腦就叫主機;ARCH是architecture(架構),表示cpu的架構,所有HOSTARCH就主機cpu的架構。 這兩個環境變量是主機的操作系統和主機的cpu架構,得出後保存,後面能用到。
2.3 靜默編譯問題:(50-54)
1. 平時默認編譯時命令行會打印出來很多編譯信息,但是有時候我們不希望看到這些編譯信息,就後臺編譯即可。這就是靜默編譯。 使用方法就是編譯時make -s , -s會作爲MAKEFLAGS傳給Makefile,在50-54行這段代碼作用下XECHO變量就會被變成空。於是實現了靜默編譯。

2.4 2中編譯方法(原地編譯和單獨輸出文件夾編譯)

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
1.編譯複雜項目,Makefile提供了2中編譯管理方法。默認情況下是當前文件夾中.c文件,編譯出來的.o文件會放在同一文件夾下,這種方式叫做原地編譯。原地編譯的好處就是處理起來簡單。 原地編譯有一些壞處:第一,污染了源文件目錄。第二缺陷是一套源代碼只能按照一種配置和編譯方法進行處理,無法同時維護2個或2個以上的配置編譯方式。
2.爲了解決以上2中缺陷,uboot支持單獨輸出文件夾方式的編譯(linux kernel也支持),而且uboot這種技術就是從linux kernel學習來的。基本思路就是在編譯時另外指定一個輸出目錄,將來所有的編譯生成.o文件或生成的其他文件全部丟到那個輸出目錄下。源代碼目錄不做任何污染,這樣輸出目錄就承載了本次配置編譯的所有結果。 具體用法:默認的就是原地編譯,如果需要指定具體的輸出目錄編譯則有2中方式來指定輸出目錄:(56-76註釋內容)
1) make O=輸出目錄
2) 第二種: export BUILD_DIR=輸出目錄 然後再make
如果兩個都指定了,(既有BUILD_DIR環境變量存在,又有O=xx),則O=xx優先級高。

兩種編譯的實現代碼在Makefile 78-123
2.4 OBJTREE SRCTREE TOPDIR
OBJTREE:編譯出的.o文件存放的目錄的根目錄。在默認編譯下,OBJTREE等於當前目錄;在O=xx編譯下,OBJTREE就等於我們設置的那個輸出目錄。
SRCTREE:源碼目錄,其實就是源代碼的根目錄,也就是當前目錄。 總結:在默認編譯下,OBJTREE 和 SRCTREE相等。在O=xx編譯下OBJTREE和SRCTREE不相等。Makefile中定義這兩個變量,其實就是爲了記錄編譯後.o文件往哪裏放。就是爲了實現O=xx的這種編譯方式。 MKCONFIG 在makefile中定義的一個變量,在這裏定義,在後面使用,它的值就是我們源碼根目錄下的mkconfig,它就是一個配置腳本。這個腳本就是uboot配置階段的配置腳本。後面要用至少3節課詳細講這個配置腳本的工作。
MKCONFIG := $(SRCTREE)/mkconfig (Makefile 101)
export MKCONFIG

2.4.3.3 include $(obj)include/config.mk (133行)
(1)include/config.mk 不是源碼自帶的,(你在沒有編譯過的源碼目錄下是找不到這個文件的),要在配置過程(make TQ210_config)中才會生成這個文件。因此這個文件的值和我們配置過程有關,是由配置過程根據我們的配置自動生成的。
(2)我們TQ210在iNAND情況下配置生成的config.mk內容的:
ARCH = arm
CPU = s5pv210
BOARD = TQ210
VENDOR = EmbedSky
SOC = s5pv210
(3)我們在下一行就是(134)export導出了這5個變量作爲環境變量。所以着兩行加起來其實就是爲當前makefile定義了5個環境變量而已。之所以不直接給出這5個環境變量,是因爲我們希望這5個值是可以被人很容易的,集中的配置的。
(4)這裏的配置值來自2596行那裏的配置項。如果我們要更改這裏的某個配置值要到2596行調用MKCONFIG腳本傳參時的參數。
(5)ARCH CROSS_COMPILE
接下來有2個重要的環境變量。一個是ARCH,上面導出的,值來自於我們的配置過程,它的值會影響後面的CROSS_COMPILE環境變量的值,ARCH的意義定義當前編譯的目標CPU的架構。CROSS_COMPILE是定義交叉編譯工具的前綴的。定義這些前綴是爲了在後面用(用前綴加上後綴來定義編譯過程中用到的各種工具鏈中的工具)。我們把前綴和後綴分開還有一個原因是:在不同cpu架構上的交叉編譯工具鏈,只是前綴不一樣,後綴都是一樣的。因此定義時把前綴和後綴分開,只需要在定義前綴時區分各種架構即可實現移植。CROSS_COMPILE在136-142中定義的。CROSS_COMPILE是被ARCH所確定的,只要配置了ARCH=arm,那麼我們就只能在ARM的那個分支去設置CROSS_COMPILE的值。這個設置值只要能保證找到那個交叉編譯工具鏈即可,不一定非得是全路徑的,相對路徑也可以。(如果已經將工具鏈導出到環境變量,並且設置了符號鏈接,這樣CROSS_COMPILE=arm-linux-就可以)。實際運行時,我們可以在Makefile中更改設置CROSS_COMPILE的值,也可以在編譯時make CROSS_COMPILE=xxx 來設置,而且編譯時傳參的方法可以覆蓋Makefile裏面的設置。

2.4.4 include $(TOPDIR)/config.mk 189行
1.編譯工具的定義:在config.mk 97 – 107
2. 包含開發板配置項目(config.mk,112行)
Autoconfig.mk文件不是源碼提供的,是配置過程自動生成的。 這個文件的作用就是用來指導整個uboot的編譯過程,這個文件內容其實就是很多CONFIG_開頭的宏。(可以理解爲變量)。這些宏或者變量會影響我們uboot編譯過程的走向(原理就是條件編譯)。在uboot代碼中有很多地方使用條件編譯進行編寫,這個條件編譯就用來實現可移植性的。(可以說uboot的源代碼在很大程度上說是拼湊起來的,同一個代碼包含了各種不同開發板的適用代碼,用條件編譯進行區別)。
這個文件不是憑空產生的,配置過程也是需要原材料來產生這個文件的,原材料在源碼的目錄是:include/configs/xxxx.h頭文件。(x210開發板中爲include/configs/TQ210.h)。這個h頭文件裏面全是宏定義,這些宏定義就是我們對當前開發板的移植。每個開發板的移植都對應這個目錄下的一個頭文件,這個頭文件裏每一個宏定義都很重要,這些配置的宏定義就是我們移植uboot的關鍵所在。

2.4.5.1 鏈接器腳本(config.mk) 144-147
1.如果定義了CONFIG_NAND_U_BOOT宏,則鏈接器腳本叫u-boot-nand.lds,如果未定義這個宏則鏈接器腳本叫u-boot.lds。
2.從字面意思分析,即可知:CONFIG_NAND_U_BOOT是在Nand
版本情況下才使用的,我們使用TQ210都是iNand版本,因此這個宏沒有的。
2. 實際在board\EmbedSky\TQ210\u-boot.lds,這個就是鏈接器腳本。我們在分析uboot的編譯連接過程時要考慮這個鏈接腳本。
2.4.5.2 TEXT_BASE (config.mk )
1.Makefile中配置TQ210開發板時,在board\EmbedSky\TQ210\目錄下生成了一個文件config.mk其中的內容就是 : TEXT_BASE = 0xC3E00000。
2.TEXT_BASE是將來我們整個uboot鏈接時指定的鏈接地址。因爲uboot中啓用了虛擬地址映射,因此這個C3E00000地址就等於0x23e00000(也可能是33e00000具體地址要取決於uboot中做的虛擬地址映射關係)。
3.回顧裸機中講的鏈接地址的問題,再想想dnw方式先下載TQ210_usb.bin,然後再下載uboot.bin時爲什麼第二個地址是23E0000.

2.4.5.3.自動推導規則(config.mk 239-256)
我們在講Makefile 是提到過自動推導規則,具體理解可以參考(跟我一起學Makefile)。


Uboot主Makefile分析:
1.291行出現了整個主Makefile中第一個目標all(也就是默認目標,我們在uboot根目錄下make其實就等於make all,就等於make這個目標)
2.目標中有一些比較重要的。譬如:u-boot是最終編譯鏈接生成的elf格式的可執行文件。
3.unconfig字面意思來理解就是未配置。這個符號用來做爲我們各個開發板配置目標的依賴。目標是當我們已經配置過一個開發板後再次去配置時還可以配置。
4.我們配置開發板時使用;make TQ210_config,因此分析TQ210_config肯定是主Makefile中的一個目標。

2.4.7 uboot配置過程詳解1
1. Mkconfig腳本的6個參數。TQ210_config : unconfig
$(MKCONFIG) $(@:_config=) arm s5pv210 TQ210 EmbedSky s5pv210
TQ210_config裏面的_config部分用空替換,得到:TQ210,這就是第一個參數,所以:
$1: TQ210
$2: arm
$3: s5pv210
$4: TQ210
$5: EmbedSky
$6: s5pv210
所以$# = 6
3. 第23行,其實就是看BOARD_NAME變量是否有值,沒有就賦值。結果BOARD_NAME=TQ210
4. 第25行,如果$#小於4,則 exit 1 (mkconfig腳本返回1)。
5. 第26行,如果$#大於6,則 exit 1
所以:mkconfig腳本傳參只能是4,5,6.其他值都不行。

LINUX符號鏈接:從33-118行結束。這些符號鏈接就是配置的核心,這些符號鏈接文件(文件夾)的主要作用是,給頭文件包含等過程提供指向性連接。根本目的是讓uboot具有可移植性。
Uboot可移植性的實現原理:在uboot中很多彼此平行的代碼,各自屬於各自不同的架構/cpu/開發板,我們在具體到一個開發板的編譯時用符號鏈接的方式提供一個具體名字的文件夾供編譯時使用。這樣就可以在配置過程中通過不同的配置使用不同的文件,就可以正確包含正確的文件。
(6)創建的符號鏈接:
第一個:在include目錄下創建asm文件,指向asm-arm(46-48行)
第二個:在include/asm-arm下創建一個arch文件,指向include/asm-arm/arch-s5pv210
第三個:在include目錄下創建一個regs.h文件,指向include/s5pv210.h
刪除第二個。
第四個:在include/asm-arm下創建一個arch文件,指向include/asm-arm/arch-s5pv210
第五個:在include/asm-arm下創建一個proc文件,指向include/asm-arm/proc-arm
總結:一共創建了4個符號鏈接。這4個符號鏈接將來寫代碼過程中,頭文件包含非常有用。譬如一個頭文件包含可能是:#include<asm/xx.h>

2.4.8 uboot配置詳解第二部分:
(1)創建include/config.mk文件(mkconfig文件12-129)
(2)創建include/config.mk文件是爲了讓主Makefile在第133行

思考:uboot的配置和編譯過程的配合。編譯的時候需要ARCH=arm CPU=xx 等這些變量來指導編譯,配置的時候就是爲編譯階段提供這些變量。那爲什麼不在Makefile中直接定義這些變量去使用,而要在mkconfig腳本中創建config.mk文件,然後又在Makefile中include這些文件呢?

理解這些腳本,需要時刻注意自己的路徑。
(5)創建(默認情況)/追加(make -a時追加)include/config.h文件(mkconfig文件的134-141)
(6)這個文件裏面的內容就一行#include <configs/TQ210.h>這個頭文件時我們移植TQ210開發板時,對開發板的宏定義配置文件,這個文件是我們移植TQ210時最主要的文件。
(7)TQ210.h文件會被用來生成一個autoconfig.mk文件,這個文件會被主Makefile引入,指導整個編譯過程,這裏面的這些宏定義會影響我們對uboot中大部分.c文件中一些條件編譯的選擇。從而實現最終的可移植性。

注意uboot的整個配置過程,很多文件之間是由關聯的(有時候這個文件是在哪個文件創建出來,有時候這個文件被哪個文件包含進去;有時候這個文件是由哪個文件的內容生成的決定的)
Uboot中配置和編譯過程,所有的文件或者全局變量都是字符串形式(不是指c語言字符串的概念,指的是字符組成的序列)。這意味着我們整個uboot的配置過程都是字符串匹配的,所以一定要細節,注意大小寫,要注意不要輸錯字符,因爲一旦錯一個最後會出現一些默默奇妙的錯誤,很難排查,這個是uboot移植過程中新手來說最難的地方。
2.4.9 uboot的連接腳本
1.uboot的連接腳本和我們之前裸機中的鏈接腳本並沒有本質區別,難度高點,文件多一些,使用技巧多一些。
2.ENTRY(_start)用來指定整個程序的入口地址,所謂入口地址就是整個程序的開頭地址。可以認爲就是整個程序的第一句指令。有點像c語言中的main。
3.之前在裸機中告訴大家,指定程序的鏈接地址有2中方法:一種是在Makefile中ld的flags用-Ttext
0x20000000來指定:第二種是在鏈接腳本的SECTIONS開頭用.=0x20000000來指定。兩種都可以實現相同效果。其實,這兩種技巧是可以共同配合使用的。兩個都指定以後以-Ttext指定爲準。
5. uboot的最終鏈接起始地址就是在Makefile中用-Ttext來指定,注意TEXT_BASE變量。最終來源是Makefile中配置對應的命令中,在make xxx_config時得到的。
6. 在代碼段中注意文件排列的順序。指定必須放在前面部分的那些文件就是那些必須安排在前16kb內的文件,這些文件中的函數在前16kb會被調用。在後面第二部分中調用的程序,前後順序就無所謂了。
7. 鏈接腳本中除了.text .data .rodata .bss段等編譯工具自帶的段之外,編譯工具還允許我們自定義段。譬如uboot中的 .u_boot_cmd段就是自定義段。自定義段很重要。


1.5.1 start.S引入
u-boot.lds中找到start.S入口
1. c語言中整個項目的入口就是main函數(這是c語言規定的),所以譬如說一個有10000個.c文件的項目,第一個要分析的文件就是包含了main函數的那個文件。
2. 在uboot中因爲有彙編階段參與,因此不能直接找main.c。整個程序入口取決於鏈接器腳本中ENTRY聲明的地方。ENTRY(_start)因此_start符號所在的文件就是整個程序的起始文件,_start所在處的代碼就是整個程序的起始代碼。
3. 利用SI工具搜索共_start,然後分析那個是我們所需要的文件。然後進入start.S文件中,然後進入76,77行,就是_start標號的定義處,我們就找到了整個uboot的入口代碼。
4. 我們開始從start.S文件分析uboot的第一階段代碼。
5. 在SI中,如果我們知道我們要找的文件的名字,但是我們又不知道它在哪個目錄下,我們要怎樣找到並打開這個文件?方法是在SI中先打開右邊的工程項目管理欄目,然後點擊最左邊那個(這個是以文件未單位來瀏覽的),然後再上面輸入欄中輸入要找的文件名字。我們在輸入時,SI在不斷幫我們進行匹配,即使你不記得文件名只能記得大概名字,也能幫你找到你要的文件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章