linux-arm-gcc工具,常用交叉編譯工具整理(arm-linux-gcc)

一、arm-linux-gcc

1. 編譯部分:

-o : 后面接的是輸出文件名(arm-linux-gcc -o hello hello.c)

-v : 可以觀看編譯細節         (arm-linux-gcc -v -o hello hello.c)

-c : 預編譯,編譯和匯編源文件,不做連接 [裸板程序一般先不做連接,最后一起做鏈接](arm-linux-gcc -o hello.o -c hello.c)

-S : 編譯后停止,不進行匯編(arm-linux-gcc -S -o hello.s hello.c)

-E : 預編譯后即頂着,不進行編譯(arm-linux-gcc -E hello.c)

-g  : 產生調試信息

-Wall : 打開所有需要注意的警告信息

2. 優化部分

(注可以指定多個"-O"選項,不管帶不帶數字,生效的是最后一個)

-O or -O1 : 不使用-O/-O1時,可以減少編譯的開銷,使編譯結果能夠調試,語句是獨立的,只有聲明了register的變量才分配使用寄存器;

使用-O/-O1時,編譯器試圖減少目標碼的大小和執行時間。

-O2          : 多優化一些,除了涉及空間和速度交換的優化選項,執行幾乎所有優化工作,例如不進行循環展開和函數內嵌;

-O3          : 優化的更多,除了-O2, 還打開"-finline-functions"

-O0          : 不作優化

3.  鏈接部分

-llibrary_name  :  鏈接名為library的庫文件,真正的名字為liblibrary.a,如要鏈接libtest.a or libtest.so ,則寫成-ltest,如果有動態庫,則會優先鏈接動態庫。

-Llibpath            : 指定鏈接庫搜索路徑,如庫都放在/prj/libs/下面,則-L/prj/libs

-nostartfiles         : 不連接系統標准啟動文件,標准庫文件仍然正常使用(編譯bootloader,kernel時用到)

-nostdlib             : 不連接系統標准啟動文件和標准庫文件,只把指定的文件傳遞給連接器(編譯bootloader,kernel時用到)

[與-nostartfiles的區別是,-nostartfiles只是不包含啟動文件]

-static                 : 在支持dynamic linking的系統上阻止連接共享庫[默認情況下會優先選擇連接動態庫,使用了static會直接連接靜態庫] (gcc-static -o main main.c func.c)

-shared:生成共享OBJ文件(gcc -shared -o libfunc.so -c func.c; gcc -o main main.c -lfunc -L.)

-fPIC:編譯成位置無關,當編譯多個文件為動態庫是,必須使用這個選項

(gcc-shared -fPIC -o libfunc.so func1.c func2.c func3.c)

-Xlinkeroption    : 把選項option傳遞給連接器,如果要帶參數,必須使用兩次"-Xlinker"  (-Xlinker -assert -Xliner definitions)

-Wl,option           : 把選項option傳遞給連接器,如果option有逗號,則傳遞多個選項。常見有(-Wl,--start-group  ... -Wl, --end-group)

4.  目錄部分

-Iinclude_dir : 在頭文件中搜索路徑列表中添加include_dir

-Llibpath        : 指定鏈接庫搜索路徑,如庫都放在/prj/libs/下面,則-L/prj/libs

二、arm-linux-ld

-T : 用於指定代碼段,數據段,bss段的起始地址 or 指定一個連接腳本

1.   用於指定代碼段,數據段,bss段的起始地址

-Ttext startaddr               //text 指的是代碼段, startaddr指的是起始地址

-Tdata startaddr             //data指的是數據段

-Tbss startaddr              //bss通常指全局未初始化變量

如下:指定代碼段的運行地址為0x00000000,沒有定義數據段,bss段的起始地址,被依次放在代碼段后面

arm-linux-ld-Ttext 0x00000000 -g led_on.o -o led_on.elf     注:位置無關碼和位置相關碼

bootloader,kernel剛開始執行時所處的位置通常不等於運行地址, 在程序開頭使用b,bl,mov等"位置無關"指令

將代碼從Flash中copy到sdram中,然后再用位置相關碼ldr pc, =addr跳轉到相應位置執行。

2. 指定一個連接腳本

arm-linux-ld -Tlink.lds  -o led_on.elf len_on.S

link.lds:

/*

*OUTPUT_FORMAT 指定輸出格式,elf32-littlearm的意思是指定輸出可執行文件是elf格式,32位ARM指令,小端

*OUTPUI_ARCH 指定輸出可執行文件的平台為ARM

*ENTRY 指定程序入口地址

*_start 等於SECTIONS里面.=0x30000000, 即目標代碼的起始地址

*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS{

.= 0x30000000;

.text: { *(.text) }

.rodata ALIGN(4) : { *(.rodata) }

.data ALIGN(4) : { *(.data) }

.bss ALIGN(4) : { *(.bss) *(COMMON) }

}

section格式為:

SECTIONS{

...

secname start ALIGN(align) (NOLOAD) : AT(ldadr)

{ contexts } > region : phdr = fill

}secname       : 用來命名這個段; 如 .bss

contexts         : 用來確定什么部分放在這個段;

start                : 重定位地址,運行地址,如果代碼中有位置無關指令,程序在運行時,這個段必須放在這個地址上

ALGIN(align) : 雖然start指定運行地址,但是仍然可以指定對齊要求,對齊后的才是真正運行地址

NOLOAD       : 用來告訴加載器,在運行時不用加載這個段,只有在操作系統的情況下才有意義

AT(ldadr)       : 編譯出來映像文件中的地址-加載地址load address, 如果不使用這個選項,

加載地址等於運行地址。A段放在A處,B段放在B處,運行前再把A,B讀出來組裝成一個完整的執行程序

在代碼中指定某個section:

格式:__attribute__((unused,section (".section-name")))

如:

C語言中:__attribute__((unused,section (".u_boot_cmd")))

link-ds中:

.= .;

__u_boot_cmd_start= .;

.u_boot_cmd: { *(.u_boot_cmd) }

__u_boot_cmd_end= .;

三、arm-linux-objcopy

1. input-file, out-file

: 表示輸入目標文件(源目標文件)和輸出目標文件(目的目標文件)

2. -I bfdname or --input-target=bfdname

:  input-file文件BFD庫中描述的標准格式名,如果不指定,則arm-linux-objcopy自己去分析源文件的格式

3. -Obfdname or --output-target=bdfname

:  輸出格式

4. -F bfdname or --target=bfdname

: 源目標文件是什么格式,目標文件就是什么格式,只復制不做格式轉換

5.-R sectionname or--remove-section=sectionname

: 從輸出文件中刪掉所有名為sectionname的段

6.-S or --strip-all

: 不從源文件中復制重定位信息和符號信息到目標文件中去(bootloader,kernel等裸板程序用到)

7.-g or --strip-debug

: 不從源文件中復制調試符號到目標文件中去

在編譯bootloader, kernel時,常用arm-linux-objcopy將ELF格式生成結果轉化為二進制文件:

// binary表示輸出格式為二進制文件

// file.elf表示ELF格式文件名

// file.bin表示二進制文件名

#arm-linux-objcopy -O binary -S file.elf file.bin

bfdname 有以下幾個格式:ELF文件格式(elf32-littlearm, elf32-bigarm)、S-record文件格式(srec)、HEX文件格式(ihex)、bin文件格式(binary)

BIN文件格式(binary): 原始的二進制格式,內部沒地址標記,直接照二進制格式下載,並且照絕對地址燒寫到Flash中,

就可以啟動了,而如果下載運行,則下載到編譯時的地址即可。

ELF文件格式 : 是Linux系統下的一種常用、可移植目標文件(objectfile)格式

S-Record文件格式

HEX文件格式

四、 arm-linux-objdump (反匯編代碼)

1. -b bfdname or --target=bfdname   : 指定目標碼格式,

2. --infoor -i                                        : 查看目標碼格式列表

3. --disassemble or -d                       : 反匯編可執行段(executablesections)

4. -D or --disassemble-all                  : 反匯編所有段

5. --file-headers or -f                          : 顯示文件的整體頭部摘要信息

6. --section-headers, --headers or -h : 顯示目標文件各個段頭部摘要信息

7. --section=nameor -j name              : 僅顯示指定section的信息

//將ELF格式的文件轉換成為反匯編文件,arm-linux-objdump默認格式elf

#arm-linux-objdump -D file.elf > file.dis

//將二進制文件轉換成反匯編文件

#arm-linux-objdump -D -b binary -m arm file.bin > file.bin

五、arm-linux-readelf  (查看當前文件or庫是由什么編譯器所編譯 )

#arm-linux-readelf–h libxxx.so

六、arm-linux-ar (生成.a  or 把.a拆分成.o)

1. -x : 把.a拆分成.o

#arm-linux-ar -x libfunc.a

2.生成靜態庫.a文件

-c : 創建一個文檔

-s : 在文檔中添加索引

-r :  插入文件成員

/* libfunc.a一定在.o文件前面 */

#arm-linux-ar -rcs libfun.a fun1.o fun2.o fun3.o

七、arm-linux-strip (去掉其中的調試信息,執行文件大小or動態庫將小的多)

arm-linux-strip libfunc.so

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值