標籤:
先從bootloader開始,因為暫時目前這些都會是裸機程式相關!
本人這裡是VMwarm10.0上安裝的紅帽linux虛擬機器。從下面的中可以看出
裸機開發流程:
這裡先做第三步(第一步第二步已提供好),感受總結一下ARM裸機開發需要哪些工具,用到的時候再詳細介紹。
要做第三步,首先要安裝交叉編譯器!
找到安裝包,解壓到根目錄下(解壓後邊加上 -C /)
這裡交叉工具鏈會自動解壓到根目錄下的 /usr/local/arm/ 目錄下面
但是這時候還不能直接在任意目錄下使用arm-linux-gcc等工具(能不能用就看Tab鍵能不能自動補齊),這是因為這個工具軟體安裝在/usr/local/arm/4.3.2/這個目錄下,如果不跟上這個絕對路徑,我們的linux並不知道去哪找比如:arm-linux-gcc這個命令!那麼怎麼樣才能在任意目錄下不使用完整路徑也能使用這個工具軟體呢?
答:修改path環境變數
vi /root/.bashrc
然後執行source /root/.bashrc
通過上面的幾天命令可以看到安裝前後修改腳步前後使用arm-linux-gcc命令的變化!其實好多工具軟體的安裝都是大同小異,解壓到指定目錄下,然後修改環境變數!然後source修改的腳步使其生效!
首先一開始該目錄下有三個檔案. 其中led.lds是連結器腳步 ,led.S彙編檔案。
其中後邊使用的三條命令分別使用了交叉工具鏈、連結器腳步
然後我們先make clean 一下,讓其回到最初始只有三個檔案的時候make一下,發現效果是一樣的,這就是makefile工程管理
下一步,如何將我們的應用程式下載到開發板上的nandflash上去,一般都是通過norflash或者SD卡上的系統安裝輔助程式來幫我們燒寫(就是和PC機建立一個串連,然後把PC機上的程式下載到nandflash中)
下面再對上面使用的命令進行解析!
交叉工具鏈:
第一個是交叉工具,第二個是鏈。
常用交叉工具:
1. 交叉編譯器 arm-linux-gcc
2. 交叉連結器 arm-linux-ld
3. 交叉轉換器 arm-linux-readelf
4. 交叉ELF檔案工具 arm-linux-objdump
5. 交叉反組譯碼器 arm-linux-objcopy
使用arm-linux-gcc --help 可以看到
可以看到arm-linux-gcc -g -c led.S 中 -g 是靜態編譯, -c 是只編譯不連結!經過這一步產生led.o檔案!
然後第二步:arm-linux-ld -Tled.lds -o led.elf led.o 這裡當使用一個連結器指令碼的時候是使用的-T參數,這裡是將所有的.o檔案連結成.elf格式的目標檔案!led.elf是要連結成的目標檔案的名字, 這裡需要連結的只有一個led.o檔案。
使用命令arm-linux-readelf -a led.elf (這裡-a表示查看led.efl檔案的全部資訊)
從這裡可以看到一些非常有用的資訊,首先有一個固定的檔案頭!data那一行,可以看出這個檔案是運行在little endian 即小端模式下的。等等還有其他的一些很有用的資訊!
程式達不到預期結果一般情況下先檢查三個問題:
1. 是否是運行在ARM平台上, 用命令:file 目標檔案名 查看
2. 查看大小端是否對 arm-linux-readelf查看
3. 查看程式用到的某些庫是否對 使用命令:arm-linux-readelf -d 目標檔案名 (可以查看目標檔案在目標板上運行必須用到哪些庫,如果開發板上沒有該庫,則肯定是運行不了的)
ARM反組譯碼器:在底層編程中是非常有用的!能查看彙編代碼!(即如何將程式變成彙編版本)
命令方式:arm-linux-objdump -D -S 目標檔案 直接斷行符號就可以看到反組譯碼代碼,但是如果反組譯碼檔案比較長,可以
將反組譯碼輸出到一個檔案裡面去,方便查看!用法:arm-linux-objdump -D -S 目標檔案 >dump (這裡輸出到目前的目錄下的dump檔案下)查看反組譯碼代碼對分析問題非常有用!(使用arm-linux-gcc編譯的時候加上-g選項可以使分析反組譯碼檔案更容易一些)這裡就不做示範了!麻煩!而且這些操作基本都是用多了會很順手!分析起問題來是相當的給力!
檔案格式轉換器:arm-linux-objcopy 通過前面的例子可以看到,串連出來的檔案還有編譯出來的檔案可以看到都是elf格式的,elf格式的檔案是不能直接在arm板上啟動並執行!ARM板上能啟動並執行一定是一個二進位的檔案!而檔案轉換器就是將elf格式的檔案轉化為一個可以在ARM板上能啟動並執行二進位檔案!
用法: arm-linux-objcopy -O binary led.elf led.bin (arm-linux-objcopy -O選項表示表示輸出檔案 binary表示輸出檔案格式為二進位 led.elf代表要轉化的elf檔案, led.bin表示輸出的目標檔案的名字,一般檔案格式為.bin尾碼)
這裡最常用的5個常用工具就介紹完了!工作中編譯器的名字可能不一樣!但是後面的關鍵名字比如objcopy、ld等等用法都是一樣的!一般不熟悉用法的話工具名字 --help會告訴你怎麼用!總之多動手練!
下面來簡要介紹上面用到的Makefile工程管理:
使用GNU Make工具來管理程式是每個linux工程師必須掌握的技能。Make能夠使整個程式的編譯、連結只需要一個命令make就可以完成。
上面可以看到編譯一個程式可以一個命令一個命令的逐步編譯!也可以直接一個make就搞定!當需要編譯的源檔案很多的時候,一個一個的用命令來編譯將會是相當麻煩的!那麼Makefile工程管理就誕生了!
這裡粘貼一個網址,關於makefile的部落格寫的還是很不錯:http://blog.csdn.net/huiguixian/article/details/7049804
下面簡要看下上面的Makefile檔案裡面的內容:
其實這裡就是把上面單條使用的命令按照一定的規則綜合到一起!
Makeflie用途:Make的工作主要依賴一個叫Makefile的檔案,Makefile檔案描述了整個程式的編譯,連結等規則,其中包括:工程中的那些源檔案需要編譯以及如何編譯,如何最後產生我們想要的可執行檔。
Makeflie構成 ---規則
Makefile中最重要的組成部分是“規則”
規則:用於說明如何產生目標檔案,規則的格式如下:
targets: prerequistes
command
目標 依賴 命令
特別注意:命令需要使用TAB鍵空格
Makefile構成---偽目標
Makefile中把那些只包含命令,沒有任何依賴的目標稱為“偽目標”(phony targets)
.PHONY : clean
clean:
rm -f hello main.o ...
".PHONY"將“clean”目標聲明為偽目標
Makefile構成---最終目標
1. 當一個makeflie中有多條規則時,如何單獨執行某條規則?如果使用者沒有指定執行某一條規則,make會預設執行makefile中的第一條規則,而這條規則中的目標稱之為:最終目標
Makeflie規則---變數
在makelife中,使用者除了可以自己定義變數外,還可以使用存在系統已經定義好的預設變數。
$^:代表所有的依賴檔案
[email protected]:代表目標
$<: 代表第一個依賴檔案
比如使用前:
led.o : led.S
arm-linux-gcc -g -o led.o -c led.S
使用後:
arm-linux-gcc -g -o [email protected] -c $^
Makefile提示---去回顯
Makefile中 “#”字元後的內容被視作注釋
Makefile中“@”表示取消回顯
Makefile提示---檔案名稱
make命令預設在目前的目錄下尋找名字為makeflie或者Makefile的工程檔案,當名字不為這兩者之一時,可以使用如下方法指定:make -f 檔案名稱
連結器指令碼的神奇作用
在裸機程式 、在核心、 驅動、 還有uboot的學習中都會大量的接觸到連結器指令碼,所以非常重要!
下面再來簡要介紹一下上面用到的led.lds連結器指令碼,先來看下上面用到的led.lds指令碼真面目
下面再來逐步分析:
連結器指令碼---段
一個可執行程式通常是由:程式碼片段,資料區段,bss段構成的,同樣在用於連結這個程式的連結器指令碼中,就會反應出這幾個段的資訊。
一般編寫連結器指令碼分為以下幾個步驟:
1. 建立連結器指令碼--段資訊
2. 設定起始連結地址
3. 對齊設定
4. 使用變數
5. 設定程式碼片段首檔案
這個也不是很複雜!這裡就不逐步講解了!還是那句話!一定要動手多練!這方面的知識可以百度查查!看看別人寫的部落格!上面講的比較詳細!
Eclipse整合式開發環境的配置!這個主要是在PC機Linux上的一些配置!整過好幾次了,步驟稍微有點麻煩,而且在公司中也沒覺得多好用!自己還是用NotePad++寫C代碼方便!個人習慣!這裡就先不贅述了!不過有個線上調試模擬功能還是相當強大的,特別是在偵錯工具時簡直就是神器!
ARM開發工具軟體命令詳解---嵌入式迴歸第三篇