真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

04-ARM裸機(jī)開發(fā)的命令行工具

一、交叉編譯工具的使用

?在進(jìn)行嵌入式開發(fā)時(shí),通常有宿主機(jī)與目標(biāo)機(jī)的角色之分,宿主機(jī)是執(zhí)行編譯、鏈接嵌入式軟件的計(jì)算機(jī),而目標(biāo)機(jī)是運(yùn)行嵌入式軟件的硬件平臺(tái)。而這兩者之間有時(shí)硬件/軟件平臺(tái)可能不同,在宿主機(jī)上直接使用編譯器的程序在目標(biāo)機(jī)上無法運(yùn)行,因此就出現(xiàn)了交叉編譯工具。在針對ARM架構(gòu)上運(yùn)行的Linux目標(biāo)機(jī)來說,其專用的交叉編譯工具為arm-linux-gcc、arm-linux-ld等。

創(chuàng)新互聯(lián)公司是專業(yè)的安順網(wǎng)站建設(shè)公司,安順接單;提供網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行安順網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

04-ARM裸機(jī)開發(fā)的命令行工具
一個(gè) C/C++文件要經(jīng)過預(yù)處理(preprocessing)、編譯(compilation)、匯編(assembly)和連接(linking)等 4 步才能變成可執(zhí)行文件。其每一步的作用在下表中進(jìn)行了說明:

步驟說明
預(yù)處理 C/C++源文件中,以“ #”開頭的命令被稱為預(yù)處理命令,如包含命令“ #include”、宏定義命令“ #define”、條件編譯命令“ #if”、“ #ifdef”等。預(yù)處理就是將要包含(include)的文件插入原文件中、將宏定義展開、根據(jù)條件編譯命令選擇要使用的代碼,最后將這些東西輸出到一個(gè)“ .i”文件中等待進(jìn)一步處理。
編譯 編譯就是把 C/C++代碼(比如上述的“ .i”文件)“ 翻譯” 成匯編代碼。
匯編 匯編就是將第二步輸出的匯編代碼翻譯成符合一定格式的機(jī)器代碼,在 Linux 系統(tǒng)上一般表現(xiàn)為 ELF 目標(biāo)文件(OBJ 文件)。
鏈接 鏈接就是將上步生成的 OBJ 文件和系統(tǒng)庫的 OBJ 文件、 庫文件連接起來,最終生成了可以在特定平臺(tái)運(yùn)行的可執(zhí)行文件。

?編譯器利用上述四個(gè)步驟中的一個(gè)或多個(gè)來處理輸入文件,源文件的后綴表示源文件所用的語言,后綴控制編譯器的缺省動(dòng)作。

后綴名語言種類
.c C源程序
.i 預(yù)處理后的c文件
.s或.S 匯編語言源程序
.h 頭文件
.o 匯編后對象文件,包含了對各個(gè)函數(shù)的入口標(biāo)記,描述,當(dāng)程序要執(zhí)行時(shí)還需要鏈接(link).鏈接就是把多個(gè).o文件鏈成一個(gè)可執(zhí)行文件

?在交叉編譯工具里經(jīng)常用到的命令有:

命令介紹
arm-linux-gcc 編譯器
arm-linux-ld 鏈接器
arm-linux-objdump 反匯編工具
arm-linux-readelf elf文件查看器
arm-linux-objcopy 文件轉(zhuǎn)換工具

1.arm-linux-gcc
常用選項(xiàng):

 -E:讓編譯器在預(yù)處理后停止編譯過程
 -o file:指定輸出文件為 file
 -S:只進(jìn)行編譯而不進(jìn)行匯編,生成匯編代碼
 -c:將匯編代碼轉(zhuǎn)化為“.o”的二進(jìn)制目標(biāo)代碼(-c可以一次性完成前三部工作)

2.arm-linux-ld
用于將多個(gè)目標(biāo)文件、庫文件連接成可執(zhí)行文件,常用選項(xiàng):

 object-file-name:默認(rèn)是是OBJ 文件或庫文件(根據(jù)文件內(nèi)容,連接器能夠區(qū)分 OBJ 文件和庫文件)。如果 GCC 執(zhí)行連接操作,這些 OBJ 文件將成為連接器的輸入文件。
 -llibrary:連接名為 library 的庫文件。
 -nostdlib:不連接系統(tǒng)標(biāo)準(zhǔn)啟動(dòng)文件和標(biāo)準(zhǔn)庫文件,只把指定的文件傳遞給連接器。這個(gè)選項(xiàng)常用于編譯內(nèi)核、 bootloader 等程序,它們不需要啟動(dòng)文件、標(biāo)準(zhǔn)庫文件。
 -static:在支持動(dòng)態(tài)連接(dynamic linking)的系統(tǒng)上,阻止連接共享庫。
 -shared:生成一個(gè)共享 OBJ 文件,它可以和其他 OBJ 文件連接產(chǎn)生可執(zhí)行文件。只有部分系統(tǒng)支持該選項(xiàng)。
 -T:只在連接 Bootloader、內(nèi)核等沒有底層軟件支持的軟件;連接運(yùn)行于操作系統(tǒng)之上的應(yīng)用程序時(shí), 無需指定-T。

3.arm-linux-objcopy
被用來拷貝一個(gè)目標(biāo)文件的內(nèi)容到另一個(gè)文件中, 可以使用不同于源文件的格式來輸出目的文件,即可以進(jìn)行格式轉(zhuǎn)換。

 input-file、outfile:分別表示輸入目標(biāo)文件(源目標(biāo)文件)和輸出目標(biāo)文件(目的目標(biāo)文件)
 -I bfdname:用來指明源文件的格式, bfdname 是 BFD 庫中描述的標(biāo)準(zhǔn)格式名
 -O bfdname :使用指定的格式來輸出文件, bfdname 是 BFD 庫中描述的標(biāo)準(zhǔn)格式名
 -F bfdname :同時(shí)指明源文件、目的文件的格式
 -R sectionname:從輸出文件中刪掉所有名為 sectionname 的段。
 -S :不從源文件中拷貝重定位信息和符號(hào)信息到目標(biāo)文件中去
 -g :不從源文件中拷貝調(diào)試符號(hào)到目標(biāo)文件中去

在編譯 bootloader、 內(nèi)核時(shí),常用 arm-linux-objcopy 命令將 ELF 格式的生成結(jié)果轉(zhuǎn)換為二進(jìn)制文件,比如:
$ arm-linux-objcopy -O binary -S elf_file bin_file
4.arm-linux-objdump
用于顯示二進(jìn)制文件信息。

 -b bfdname :指定目標(biāo)碼格式??梢允褂谩?arm-linux-objdump –i”命令查看支持的目標(biāo)碼格式列表。
 -disassemble :反匯編可執(zhí)行段(executable sections)。
 -disassemble-all :與-d 類似,反匯編所有段。
 -EB :指定字節(jié)序。
 --file-headers :顯示文件的整體頭部摘要信息。
 --section-headers:顯示目標(biāo)文件各個(gè)段的頭部摘要信息。
 -info :顯示支持的目標(biāo)文件格式和 CPU 架構(gòu),它們在“ -b”、“ -m”選項(xiàng)中用到。
 --section=name :僅僅顯示指定 section 的信息。
 --architecture=machine :指定反匯編目標(biāo)文件時(shí)使用的架構(gòu),當(dāng)待反匯編文件本身沒有描述架構(gòu)信息的時(shí)候(比如S-records),這個(gè)選項(xiàng)很有用。

5.arm-linux-readelf

-a 應(yīng)用程序    可查看文件運(yùn)行架構(gòu)、大小端、共享庫等信息。針對編譯時(shí)加上"-static"選項(xiàng)的應(yīng)用程序。
-d 應(yīng)用程序    可查看應(yīng)用程序的動(dòng)態(tài)鏈接庫

二、Makefile工程管理器

?當(dāng)一個(gè)項(xiàng)目有上百個(gè)文件的代碼構(gòu)成的項(xiàng)目,如果其中只有一個(gè)或少數(shù)幾個(gè)文件進(jìn)行了修改,使用Gcc 編譯工具,就不得不把這所有的文件重新編譯一遍,因?yàn)榫幾g器并不知道哪些文件是最近更新的,只有全部重新才能得到可執(zhí)行文件。
但是編譯過程是分為編譯、匯編、鏈接不同階段的,其中編譯階段僅檢查語法錯(cuò)誤以及函數(shù)與變量的聲明是否正確聲明了,在鏈接階段則主要完成是函數(shù)鏈接和全局變量的鏈接。因此,那些沒有改動(dòng)的源代碼根本不需要重新編譯,而只要把它們重新鏈接進(jìn)去就可以了。而Make工程管理器能夠自動(dòng)識(shí)別更新了的文件代碼,同時(shí)又不需要重復(fù)輸入冗長的命令行。
Make 工程管理器也就是個(gè)“自動(dòng)編譯管理器” ,它能夠根據(jù)文件時(shí)間戳自動(dòng)發(fā)現(xiàn)更新過的文件而減少編譯的工作量,同時(shí),它通過讀入 Makefile 文件的內(nèi)容來執(zhí)行大量的編譯工作。
1.Makefile的構(gòu)成
Makefile 是 Make 讀入的惟一配置文件,在一個(gè) Makefile 中通常包含如下內(nèi)容:
· 需要由 make 工具創(chuàng)建的目標(biāo)體(target) ,通常是目標(biāo)文件或可執(zhí)行文件;
· 要?jiǎng)?chuàng)建的目標(biāo)體所依賴的文件(dependency_file) ;
· 創(chuàng)建每個(gè)目標(biāo)體時(shí)需要運(yùn)行的命令(command) 。

target: dependency_files
    command
如:
hello.o: hello.c hello.h
    gcc –c hello.c –o hello.o

2.Makefile的變量
變量是在 Makefile 中定義的名字,用來代替一個(gè)文本字符串,該文本字符串稱為該變量的值。在具體要求下,這些值可以代替目標(biāo)體、依賴文件、命令以及 makefile 文件中其他部分。在Makefile 中的變量定義有兩種方式:一種是遞歸展開方式,另一種是簡單方式。
遞歸展開方式定義的變量是在引用在該變量時(shí)進(jìn)行替換的,即如果該變量包含了對其他變量的應(yīng)用,則在引用該變量時(shí)一次性將內(nèi)嵌的變量全部展開,缺點(diǎn)是不能在變量后追加內(nèi)容(因?yàn)檎Z句:CFLAGS = $(CFLAGS) -O 在變量擴(kuò)展過程中可能導(dǎo)致無窮循環(huán)) 。簡單擴(kuò)展型變量的值在定義處展開,并且只展開一次,因此它不包含任何對其他變量的引用,從而消除變量的嵌套引用。
遞歸展開方式的定義格式為:VAR=var。
簡單擴(kuò)展方式的定義格式為:VAR:=var。
Make 中的變量使用均使用格式為:$(VAR)。
預(yù)定義變量包含了常見編譯器、匯編器的名稱及其編譯選項(xiàng):

命令格式含義
AR 庫文件維護(hù)程序的名稱,默認(rèn)值為 ar
AS 匯編程序的名稱,默認(rèn)值為 as
CC C 編譯器的名稱,默認(rèn)值為 cc
CPP C 預(yù)編譯器的名稱,默認(rèn)值為$(CC) –E
CXX C++編譯器的名稱,默認(rèn)值為 g++
FC FORTRAN 編譯器的名稱,默認(rèn)值為 f77
RM 文件刪除程序的名稱,默認(rèn)值為 rm –f
ARFLAGS 庫文件維護(hù)程序的選項(xiàng),無默認(rèn)值
ASFLAGS 匯編程序的選項(xiàng),無默認(rèn)值
CFLAGS C 編譯器的選項(xiàng),無默認(rèn)值
CPPFLAGS C 預(yù)編譯的選項(xiàng),無默認(rèn)值
CXXFLAGS C++編譯器的選項(xiàng),無默認(rèn)值
FFLAGS FORTRAN 編譯器的選項(xiàng),無默認(rèn)值

Makefile 中常見自動(dòng)變量

命 令 格 式含 義
$* 不包含擴(kuò)展名的目標(biāo)文件名稱
$+ 所有的依賴文件,以空格分開,并以出現(xiàn)的先后為序,可能包含重復(fù)的依賴文件
$< 第一個(gè)依賴文件的名稱
$@ 目標(biāo)文件的完整名稱
$^ 所有不重復(fù)的依賴文件,以空格分開
$% 如果目標(biāo)是歸檔成員,則該變量表示目標(biāo)的歸檔成員名稱
$? 所有時(shí)間戳比目標(biāo)文件晚的依賴文件,并以空格分開

3.Makefile 規(guī)則
Makefile 的規(guī)則是 Make 進(jìn)行處理的依據(jù),它包括了目標(biāo)體、依賴文件及其之間的命令語句。一般的,Makefile 中的一條語句就是一個(gè)規(guī)則。但為了簡化 Makefile 的編寫,make 還定義了隱式規(guī)則和模式規(guī)則。
隱含規(guī)則能夠告訴 make 怎樣使用傳統(tǒng)的技術(shù)完成任務(wù),這樣,當(dāng)用戶使用它們時(shí)就不必詳細(xì)指定編譯的具體細(xì)節(jié),而只需把目標(biāo)文件列出即可。下面的Makefile中kang.o與yul.o的生成過程即可以省略。

OBJS = kang.o yul.o
CC = Gcc
CFLAGS = -Wall -O -g
sunq : $(OBJS)
    $(CC) $^ -o $@

Makefile 中常見隱式規(guī)則目錄

對應(yīng)語言后綴名規(guī) 則
C 編譯:.c 變?yōu)?o $(CC) –c $(CPPFLAGS) $(CFLAGS)
C++編譯:.cc 或.C 變?yōu)?o $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
Pascal 編譯:.p 變?yōu)?o $(PC) -c $(PFLAGS)
Fortran 編譯:.r 變?yōu)?o $(FC) -c $(FFLAGS)

?模式規(guī)則是用來定義相同處理規(guī)則的多個(gè)文件的。它不同于隱式規(guī)則,隱式規(guī)則僅僅能夠用 make 默認(rèn)的變量來進(jìn)行操作,而模式規(guī)則還能引入用戶自定義變量,為多個(gè)文件建立相同的規(guī)則,從而簡化 Makefile 的編寫。模式規(guī)則的格式類似于普通規(guī)則,這個(gè)規(guī)則中的相關(guān)文件前必須用“%”標(biāo)明。

OBJS = kang.o yul.o
CC = Gcc
CFLAGS = -Wall -O -g
sunq : $(OBJS)
    $(CC) $^ -o $@
%.o : %.c
    $(CC) $(CFLAGS) -c $< -o $@

4.Make 管理器的使用
make 有豐富的命令行選項(xiàng),可以完成各種不同的功能。

命 令 格 式含 義
-C dir 讀入指定目錄下的 Makefile
-f file 讀入當(dāng)前目錄下的 file 文件作為 Makefile
-i 忽略所有的命令執(zhí)行錯(cuò)誤
-I dir 指定被包含的 Makefile 所在目錄
-n 只打印要執(zhí)行的命令,但不執(zhí)行這些命令
-p 顯示 make 變量數(shù)據(jù)庫和隱含規(guī)則
-s 在執(zhí)行命令時(shí)不顯示命令
-w 如果 make 在執(zhí)行過程中改變目錄,則打印當(dāng)前目錄名

5.makefile中常用函數(shù)
函數(shù)調(diào)用的格式為:$(function arguments)
這里function 是函數(shù)名, arguments是該函數(shù)的參數(shù)。參數(shù)和函數(shù)名之間是用空格或 Tab 隔開,如果有多個(gè)參數(shù),它們之間用逗號(hào)隔開。這些空格和逗號(hào)不是參數(shù)值的一部分。
字符串替換和分析函數(shù):

函數(shù)含義
$(subst from,to,text) 在文本text中使用to 替換每一處from.
$(patsubst pattern,replacement,text) 尋找text中符合格式pattern的字,用replacement替換它們.pattern和replacement 中可以使用通配符。
$(strip string) 去掉前導(dǎo)和結(jié)尾空格,并將中間的多個(gè)空格壓縮為單個(gè)空格。
$(findstring find,in) 在字符串in 中搜尋find,如果找到,則返回值是find ,否則返回值為空。
$(filter pattern...,text) 返 回 在 text 中 由 空 格 隔 開 且 匹 配 格 式 pattern... 的 字 , 去 除 不 符 合 格 式pattern... 的字。
$(filter-out pattern...,text) 返 回 在 text中 由 空 格 隔 開 且 不 匹 配 格 式 pattern...的 字 , 去 除 符 合 格 式pattern... 的字。
$(sort list) 將 list中的字按字母順序排序,并去掉重復(fù)的字。輸出由單個(gè)空格隔開的字的列表。

文件名函數(shù):

函數(shù)含義
$(dir names...) 抽取names...中每一個(gè)文件名的路徑部分,文件名的路徑部分包括從文件名的首字符到最后一個(gè)斜杠(含斜杠)之前的一切字符。
$(notdir names...) 抽取names...中每一個(gè)文件名中除路徑部分外一切字符(真正的文件名)。
$(suffix names...) 抽取names...中每一個(gè)文件名的后綴。
$(basename names...) 抽取names...中每一個(gè)文件名中除后綴外一切字符。
$(addsuffix suffix,names...) 參數(shù)names...是一系列的文件名,文件名之間用空格隔開; suffix 是一個(gè)后綴名。將 suffix(后綴)的值附加在每一個(gè)獨(dú)立文件名的后面,完成后將文件名串聯(lián)起來,它們之間用單個(gè)空格隔開。
$(addprefix prefix,names...) 參數(shù) names是一系列的文件名,文件名之間用空格隔開; prefix 是一個(gè)前綴名。將preffix(前綴)的值附加在每一個(gè)獨(dú)立文件名的前面,完成后將文件名串聯(lián)起來,它們之間用單個(gè)空格隔開。
$(wildcard pattern) 參數(shù)pattern是一個(gè)文件名格式,包含有通配符(通配符和 shell 中的用法一樣)。函數(shù) wildcard 的結(jié)果是一列和格式匹配的且真實(shí)存在的文件的名稱,文件名之間用一個(gè)空格隔開。

6.使用 autotools
編寫 Makefile 不是一件輕松的事,尤其對于一個(gè)較大的項(xiàng)目而言更是如此。autotools 系列工具只需用戶輸入簡單的目標(biāo)文件、依賴文件、文件目錄等就可以輕松地生成 Makefile 。另外,這些工具還可以完成系統(tǒng)配置信息的收集,從而可以方便地處理各種移植性的問題。autotools 是系列工具主要包含:aclocal、autoscan、autoconf、autoheader、automake。
使用 autotools 主要就是利用各個(gè)工具的腳本文件以生成最后的 Makefile。其總體流程是:
· 使用 aclocal 生成一個(gè)“aclocal.m4”文件,該文件主要處理本地的宏定義;
· 改寫“configure.scan”文件,并將其重命名為“configure.in” ,并使用 autoconf 文件生成 configure 文件。

命令執(zhí)行過程
autoscan 它會(huì)在給定目錄及其子目錄樹中檢查源文件,若沒有給出目錄,就在當(dāng)前目錄及其子目錄樹中進(jìn)行檢查。它會(huì)搜索源文件以尋找一般的移植性問題并創(chuàng)建一個(gè)文件“configure.scan” 。
autoconf configure.in 是 autoconf 的腳本配置文件,它的原型文件“configure.scan”。
autoheader 接著使用 autoheader 命令,它負(fù)責(zé)生成 config.h.in 文件。
automake automake 要用的腳本配置文件是 Makefile.am,用戶需要自己創(chuàng)建相應(yīng)的文件。之后,automake 工具轉(zhuǎn)換成Makefile.in。
configure 在這一步中,通過運(yùn)行自動(dòng)配置設(shè)置文件 configure,把 Makefile.in 變成了最終的Makefile。

04-ARM裸機(jī)開發(fā)的命令行工具

三、鏈接器器腳本

?鏈接器主要有兩個(gè)作用,一是將若干輸入文件(.o文件)根據(jù)一定規(guī)則合并為一個(gè)輸出文件(例如ELF格式的可執(zhí)行文件);二是將符號(hào)與地址綁定(當(dāng)然加載器也要完成這一部分工作)。
如果沒有為程序提供一個(gè)鏈接器腳本,鏈接器將會(huì)使用默認(rèn)的編譯在鏈接器執(zhí)行文件內(nèi)部的腳本。可以使用命令’–verbose’顯示默認(rèn)的鏈接腳本。通過在命令行使用’-T’命令使用自己的腳本。如果使用此命令,你的鏈接腳本將會(huì)替代默認(rèn)鏈接腳本。
一個(gè)可執(zhí)行的程序通常是由:代碼段,數(shù)據(jù)段,bss段構(gòu)成的。同樣,在用于鏈接這個(gè)程序的連接器腳本中,就會(huì)反映出這幾個(gè)段的信息。最簡單的可能的腳本只有一個(gè)命令:’SECTIONS’。

SECTIONS {
    . = 0x30000000;           //起始鏈接地址
    .text :                            //代碼段
    {
        head.o(.text)              //保證head.o首先被鏈接,也就是程序執(zhí)行的時(shí)候先執(zhí)行這部代碼  
        init.o(.text)
        nand.o(.text)
        *(.text) 
    }
    .rodata ALIGN(4) :      //只讀數(shù)據(jù)段,字節(jié)對齊
        {*(.rodata*)} 
    .data   ALIGN(4) :        //可讀寫且需要初始化數(shù)據(jù),字節(jié)對齊
        { *(.data) }
    __bss_start = .;          //把當(dāng)前地址存入bss_start這個(gè)變量中,可讀寫的置零初始化數(shù)據(jù)bss段
        .bss ALIGN(4)  :
        { *(.bss)  *(COMMON) }
    __bss_end = .;           //把當(dāng)前地址存入bss_end這個(gè)變量中
}

參考文獻(xiàn):
嵌入式Linux系統(tǒng)開發(fā)完全手冊_基于4412_上冊
Linux下的C編程基礎(chǔ)
LD說明文檔--3.LD鏈接腳本


文章題目:04-ARM裸機(jī)開發(fā)的命令行工具
URL分享:http://weahome.cn/article/johcsd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部