標籤:使用 io 檔案 資料 ar cti 代碼 log linux
一、構建嵌入式開發環境
1、編譯bootloader並燒寫到板子中---uboot, 可以自己定製bootloader and logo
2、編譯file system 並燒寫--內嵌APP
3、編譯linux kernel----定製drivers and logo
4、編譯APP
5、編譯file system 備份---內嵌APP
6、安裝交叉編譯工具
7、安裝調試工具
二、嵌入式編程基礎知識
一般的c/c++檔案要變成可執行檔需要經過預先處理、編譯、彙編、和串連等4個步驟
1)預先處理
以#開頭的為預先處理命令,如包含命令#include、宏定義#define、條件編譯#if #ifdef,預先處理的目的是將所有include檔案插入到源檔案中、將宏定義展開、
條件編譯成立的選擇使用的代碼,最後將所有代碼輸入到.i檔案中等待處理,預先處理需要用到arm-linux-cpp工具
2)編譯
把所有c/c++代碼(上面的.i檔案)翻譯成彙編代碼,用到工具為ccl
3)彙編
將前面的彙編代碼翻譯成一定格式的機器碼,Linux上一般為ELF目標檔案,用到工具為arm-linux-as
4)串連
串連就是將上面產生的obj檔案和系統庫的obj檔案、庫檔案串連起來,最終產生在平台上可執行檔,用到工具為arm-linux-ld
arm-linux-gcc選項
1)-c
預先處理、編譯和彙編源檔案,不做串連,編譯器產生obj檔案,gcc通過.o替換.c .i .s等
2)-S
編譯後即停止,不進行彙編,gcc用.s替換.c .i等
3)-E
預先處理後停止,不進行編譯,預先處理代碼到標準輸出
4)-o file
指定輸出file檔案
5)-v
顯示gcc版本,編譯細節
6)-Wall
開啟警告選項
7)-g
開啟調試選項,可用gdb調試
8)-llibrary
串連名為library的庫檔案,真正名字為liblibrary.a
9)-static
靜態編譯
10)-shared
產生共用obj檔案
11)-Idir
指定dir為標頭檔搜尋目錄
12)-Ldir.
指定dir為庫檔案搜尋目錄
arm-linux-ld選項
1)-T
指定程式碼片段(-Ttext),資料區段(-Tdate),bss段(-Tbss)的起始地址
使用串連指令碼(-Txxx.lds)
例:
SECTIONS {
. = 0×30000000;
.text : { *(.text)}
.rodata ALIGN(4) : { *(.rodate) }
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
第二行表示當前運行地址為0×30000000,第三行定義了.text段,內容為*(.text),表示所有輸入檔案的程式碼片段,起始運行地址為0×30000000
第四行定義了.rodata段,代碼緊挨.text,ALIGN(4)表示起始地址4位元組對齊如果.text為0×30000000-0x300003f1,則.rodata地址為0x300003f4
arm-linux-objcopy選項,此命令用來複製一個目標檔案內容到另一個檔案中,可進行格式轉換
例:將ELF格式轉換成二進位檔案
arm-linux-objcopy -O binary -S elf_file bin_file
arm-linux-objdump選項, 常用來查看反組譯碼代碼
ELF轉反組譯碼
arm-linux-objdump -D elf_file > dis_file
二進位轉反組譯碼
arm-linux-objdump -D -b binary -m arm bin_file > dis_file
三、 Makefile 編譯檔案------以後補充
Makefile介紹
1)格式:
目標 : 依賴
<tab>命令
例:
hello: hello.c
gcc -o hello hello.c
clean:
rm -f hello
2)賦值方法
延時變數:使用時才展開
var = value
var ?= value(變數未定義才有效,即定義第一次出現的延時變數)
立即變數:定義時值就確定
var := value
對於 var += value 右邊變數如果前面使用:=定義為立即變數,則它是立即變數,否則為延時變數
3)Makefile常用函數
函數調用以“$”開頭,以圓括弧或花括弧把函數名和參數括起。感覺很像一個變數,是不是?函數中的參數可以使用變數,
為了風格的統一,函數和變數的括弧
嵌入式Linux基礎知識