IT技術互動交流平jiao)/h4>

幸运pk10官网

來源︰IT165收集(ji)  發布日期︰2020-02-27 16:41:08

幸运pk10官网

在(zai)我ye)牟bo)文(wen) GNU ARM交叉(cha)匯編環境(jing)的搭建與(yu)測(ce)試中,詳細講bu)飭NU ARM匯編環境(jing)的創建與(yu)使(shi)用(yong)方法。實際開發中,直接(jie)使(shi)用(yong)匯編語言寫的代碼往往很少,盡在(zai)系(xi)統啟動和性能要求(qiu)極其苛刻的時(shi)候才(cai)會(hui)用(yong)到匯編代碼。在(zai)可(ke)讀性、可(ke)移植性、邏輯表達能力方面(mian),C語言的表現要比(bi)匯編強(qiang)太多,正是C語言的這種優勢造(zao)就了Unix世界(jie),造(zao)就了Linux在(zai)多種平jiao)ㄉ縴忱嘁yi)運行的活潑場面(mian)。

所(suo)以,在(zai)嵌入式開發領域,C語言是主力語言。在(zai)使(shi)用(yong)開發ARM上運行的程序(xu)之(zhi)前,必(bi)須構建一個好(hao)用(yong)的C交叉(cha)編譯(yi)環境(jing)。在(zai)博(bo)文(wen)Freestanding C與(yu)交叉(cha)編譯(yi)器的生成原(yuan)理分析中,闡(chan)述(shu)了Freestanding C的概念和交叉(cha)編譯(yi)器構建的原(yuan)理。構建一個完整(zheng)的Hosted C交叉(cha)編譯(yi)器是qie)桓魷嗟備(bei)叢za)的過程,尤其是對(dui)于GCC來說,這個過程更是充滿艱難險(xian)阻。為了避免(mian)初學者受挫,我們從簡(jian)單開始,先(xian)構建一個Freestanding 的C交叉(cha)編譯(yi)器,然後(hou)寫一個具體的C項目來測(ce)試。

幸运pk10官网

GCC項目主要有(you)兩大功能,一是提供C,C++,Fortran等多種語言的前端(front end)編譯(yi)器,也就是負責(ze)把高級語言代碼翻(fan)譯(yi)成匯編代碼;二是作為整(zheng)個開發環境(jing)的總入口,負責(ze)調用(yong)其他匯編、鏈接(jie)工具,來chun)?普zheng)個編譯(yi)–>匯編–>鏈接(jie)過程。可(ke)見GCC本身並(bing)不能獨立工作,必(bi)須依(yi)賴(lai)于外部提供的匯編、鏈接(jie)等工具,而提供這些外部工具的最著(zhu)名(ming)軟(ruan)件就是binutils。

雖(sui)說理論(lun)上gcc和binutils的安裝沒有(you)先(xian)後(hou)的必(bi)要性,但實際上gcc編譯(yi)的過程中,需要運行binutils提供的工具來進(jin)行測(ce)試,並(bing)根據測(ce)試結果(guo)來動態控制自身源碼編譯(yi)。故binutils必(bi)須先(xian)安裝,之(zhi)後(hou)才(cai)能編譯(yi)安裝gcc。

1.1 使(shi)用(yong)binutils構建交叉(cha)匯編環境(jing)

binutils的編譯(yi)安裝詳見 GNU ARM交叉(cha)匯編環境(jing)的搭建與(yu)測(ce)試,本文(wen)不再重復表述(shu)。為便于參考,只給出(chu)binutils的配(pei)置命令(ling)︰

../binutils-2.27/configure --prefix=/home/smstong/ARM --target=arm-linux-gnueabihf

後(hou)面(mian)配(pei)置GCC時(shi),需要提供與(yu)之(zhi)完全一致的配(pei)置參數才(cai)行。

1.2 使(shi)用(yong)GCC構建Freestanding C交叉(cha)編譯(yi)環境(jing)

幸运pk10官网

GCC的官網主頁是http://www.gnu.org/software/gcc,這是GCC的大本營(ying),也是整(zheng)個GNU的核心部件。
截(jie)至今天(2020年02月27日)GCC的官方最新版(ban)本為gcc-6.2.0,下載的軟(ruan)件包名(ming)為gcc-6.2.0.tar.bz2。解壓後(hou)得到文(wen)件夾gcc-6.2.0。
然後(hou),進(jin)入gcc-6.2.0文(wen)件夾,執行./contrib/download_prerequisites腳本,這個腳本會(hui)自動下載編譯(yi)GCC必(bi)須的庫isl,mpc,gmp,mpfr等。不知道為啥GCC供下載的源碼包里不直接(jie)附帶這幾個軟(ruan)件包,還非得讓用(yong)戶(hu)重新下載它。

其他的常規編譯(yi)環境(jing)︰本地GCC,GNU make,perl,awk,bash等等,就不在(zai)這里? 鋁耍 話愕撓yong)于開發的Linux主機上都已經安裝好(hao)了這些基本的開發環境(jing)。

幸运pk10官网

GCC項目也是使(shi)用(yong)GNU autotools 管理編譯(yi)過程的,所(suo)以生成它第一步(bu)必(bi)須是執行configure命令(ling)。與(yu)binutils一樣,gcc也bu)ㄒ 壓菇 柯己馱綽 柯擠擲耄 suo)以新建一個目錄名(ming)為 build-gcc,然後(hou)進(jin)入這個目錄進(jin)行整(zheng)個構建過程。

mkdir build-gcccd build-gcc../gcc-6.2.0/configure --prefix=/home/smstong/ARM  # 要與(yu)binutils配(pei)置時(shi)相同    --target=arm-linux-gnueabihf # 要與(yu)binutils配(pei)置時(shi)相同    --enable-languages=c  # 只生成C編譯(yi)器    --without-headers  # 不使(shi)用(yong)頭文(wen)件    --disable-multilib  # 不生成多個庫版(ban)本make all-gcc  # 注意此處的目標(biao)是all-gcc,也就是freestanding Cmake install-gcc # 相應的安裝的也只是GCC

安裝完成以後(hou),會(hui)發現新生成的交叉(cha)編譯(yi)器 /home/smstong/ARM/bin/arm-linux-gnueabihf-gcc,同時(shi)還有(you)一個硬鏈接(jie)在(zai)/home/smstong/ARM/arm-linux-gnueabihf/bin/gcc。執行如下命令(ling)測(ce)試︰

[smstong@centos192 bin]$ ./arm-linux-gnueabihf-gcc -v使(shi)用(yong)內建 specs。COLLECT_GCC=./arm-linux-gnueabihf-gccCOLLECT_LTO_WRAPPER=/home/smstong/ARM/libexec/gcc/arm-linux-gnueabihf/6.2.0/lto-wrapper目標(biao)︰arm-linux-gnueabihf配(pei)置為︰../gcc-6.2.0/configure --prefix=/home/smstong/ARM/ --target=arm-linux-gnueabihf --enable-languages=c --without-headers --disable-multilib線程模型(xing)︰posixgcc 版(ban)本 6.2.0 (GCC)

幸运pk10官网

目標(biao)機器環境(jing)︰
(1)硬件平jiao)Q2440開發板,Soc CPU為三星2440, ARM920T核心。
(2)Norflash裝有(you)u-boot,可(ke)以通過tfgtp下載程序(xu)到指定(ding)物理內存(cun)地址並(bing)執行
(3)Nandflash裝有(you)Linux2.6系(xi)統,帶有(you)tftp客戶(hu)端工具。
開發主機︰
(1)Centos 7 PC機器
(2)裝有(you)tftp server,服務目錄為/var/www/tftpboot/。

幸运pk10官网

2.1 項目源碼

源碼文(wen)件結構︰

.├── Makefile├── test.c├── test.lds└── test.s

test.c

#define rGPBCON (*(volatile unsigned*)0x56000010)#define rGPBDAT (*(volatile unsigned*)0x56000014)#define rGPBUP (*(volatile unsigned*)0x56000018)void init(){ /* 初始化led1 */ rGPBCON &= ~(3<<10); rGPBCON = (1<<10); rGPBUP &= ~(1<<5); /* 熄滅(mie)led1 */ rGPBDAT = (1<<5); return;}

test.lds

ENTRY(init)SECTIONS { . = 0x30000000; .text : { *(.text) *(.rodata) } .data ALIGN(4): { *(.data) } .bss ALIGN(4): { *(.bss) }}

Makefile

CC = arm-linux-gnueabihf-gccLD = arm-linux-gnueabihf-ldOBJCPY = arm-linux-gnueabihf-objcopyall: test.bin sudo cp test.bin /var/lib/tftpboot/test.bin: test $(OBJCPY) -O binary $< $@test: test.o $(LD) --script=test.lds -o $@ $<test.o: test.c $(CC) -c $<.PHONY: cleanclean: rm -rf *.o test test.bin

2.2 編譯(yi)鏈接(jie)說明

交叉(cha)連(lian)接(jie)器默認xi)娜 詰忝ming)稱為_start,默認xi)拇?duan)基地址為0x00001074,生成的可(ke)執行文(wen)件格式為elf。而我們qie) 肴貿絛xu)在(zai)裸(luo)機上運行,需要代碼段(duan)基地址為0x30000000,文(wen)件格式為純(chun)二進(jin)制鏡像。這都可(ke)以通過鏈接(jie)腳本輕松(song)完成。另(ling)外我們還手動指定(ding)了程序(xu)入口點為init函數。

通過Norflash里的u-boot把生成的test.bin加(jia)載到物理內存(cun)0x30000000處並(bing)執行,會(hui)發現LED1燈被熄滅(mie)。而且(qie)執行xing)瓿珊hou)自動返(fan)回(hui)到了u-boot中。因為init()函數的最後(hou)是return語句。

2.3 看chun)幢嘁yi)器生成的匯編代碼

使(shi)用(yong)gcc test.c -c 時(shi),gcc會(hui)把中間產生的匯編代碼文(wen)件隱(yin)藏,為了看到這個中間文(wen)件,需要通過-S選項調用(yong)gcc來生成匯編代碼文(wen)件。

arm-linux-gnueabihf-gcc -S test.c

上述(shu)命令(ling)會(hui)生成test.s文(wen)件如下︰

 .eabi_attribute 18, 4 .file 'test.c' .text .align 2 .global init .syntax unified .arm .fpu softvfp .type init, %functioninit: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 @ link register save eliminated. str fp, [sp, #-4]! add fp, sp, #0 ldr r2, .L2 ldr r3, .L2 ldr r3, [r3] bic r3, r3, #3072 str r3, [r2] ldr r2, .L2 ldr r3, .L2 ldr r3, [r3] orr r3, r3, #1024 str r3, [r2] ldr r2, .L2+4 ldr r3, .L2+4 ldr r3, [r3] bic r3, r3, #32 str r3, [r2] ldr r2, .L2+8 ldr r3, .L2+8 ldr r3, [r3] orr r3, r3, #32 str r3, [r2] nop sub sp, fp, #0 @ sp needed ldr fp, [sp], #4 bx lr.L3: .align 2.L2: .word 1442840592 .word 1442840600 .word 1442840596 .size init, .-init .ident 'GCC: (GNU) 6.2.0' .section .note.GNU-stack,'',%progbits

通過gcc生成的匯編代碼,我們qie)部ke)以學習GNU ARM匯編的基本語法。

幸运pk10官网

由于是Freestanding C環境(jing),所(suo)以即(ji)使(shi)在(zai)Linux系(xi)統下,仍然沒有(you)可(ke)用(yong)的標(biao)準(zhun)C庫。而C語言za)植荒苤苯jie)執行軟(ruan)中斷指令(ling)調用(yong)Linux的系(xi)統調用(yong),這就導致操作系(xi)統提供的API完全不可(ke)用(yong)!(匯編語言反而可(ke)以直接(jie)通過swi指令(ling)來調用(yong)系(xi)統API)可(ke)見在(zai)操作系(xi)統下,如果(guo)沒有(you)C庫,C語言根本無(wu)法對(dui)硬件進(jin)行操作,也就不可(ke)能操控開發板上xi)ED燈,甚至也不能打(da)印簡(jian)單的hello world,這是何等的悲哀!

為了便于測(ce)試,我們不得不借助匯編的幫助,采用(yong)C語言和匯編語言混合編程的方式。其中匯編語言提供一個打(da)印字(zi)符串(chuan)的函數和一個退出(chu)進(jin)程的函數,C語言調用(yong)之(zhi)。
其實這就相當于自己用(yong)匯編語言實現了一個超級簡(jian)化的POSIX系(xi)統調用(yong)C庫。
C語言和匯編進(jin)行彼此調用(yong),就必(bi)須要遵守相應的函數調用(yong)規範,及APCS(ARM Process Call Standard),請大家自行學習之(zhi)。

4.1 項目源碼

項目文(wen)件結構圖︰

.├── api.h  # api 頭文(wen)件說明├── api.s  # api 實現├── Makefile ├── test.c└── test.lds # 鏈接(jie)腳本,指示jing)絛xu)入口

文(wen)件 api.h

void print(int fd, char* msg, int len);int exit(int code);

文(wen)件api.s

/* void print(int fd, char* msg, int len); int exit(int code); */.text.global print.global exitprint: swi #0x900004 mov pc,lrexit: swi #0x900001 mov pc,lr~

文(wen)件test.c

#include 'api.h'void test(){ char* msg = 'hello, freestanding C'; int i; for (i = 0; i < 10; i++) { print(1, msg, 22); } exit(0);}

文(wen)件test.lds

ENTRY(test)

文(wen)件Makefile

CC = arm-linux-gnueabihf-gccAS = arm-linux-gnueabihf-asLD = arm-linux-gnueabihf-ldOBJCPY = arm-linux-gnueabihf-objcopyall: test sudo cp test /var/lib/tftpboot/test: test.o api.o $(LD) --script=test.lds -o $@ $^test.o: test.c api.h $(CC) -c $<api.o: api.s $(AS) -o $@ $<.PHONY: cleanclean: rm -rf *.o test

4.2 編譯(yi)鏈接(jie)說明

交叉(cha)鏈接(jie)器默認生成elf格式文(wen)件,可(ke)以直接(jie)被Linux加(jia)載執行。應為是Freestanding C,需要在(zai)鏈接(jie)腳本中指定(ding)程序(xu)入口點。

程序(xu)執行結果(guo)︰

[root@EmbedSky /]# tftp -g -r test 172.16.35.188[root@EmbedSky /]# ./testhello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding Chello, freestanding C

幸运pk10官网

在(zai)裸(luo)機下,Freetanding C尚可(ke)以通過指針的方式直接(jie)操控部分硬件資源;在(zai)OS下,所(suo)有(you)硬件資源受到操作系(xi)統的保護(通過MMU),Freestanding C根本無(wu)法獨立操控任何硬件。

所(suo)以在(zai)實際的開發中︰

如果(guo)是裸(luo)機項目,C庫本來就不可(ke)用(yong),Freestanding C是唯(wei)一可(ke)選C環境(jing),而且(qie)能夠完美(mei)完成任務; 如果(guo)是基于OS的項目,那麼Freestanding C能力不足,必(bi)須要有(you)完整(zheng)的Hosted C環境(jing)才(cai)能勝(sheng)任(當bi)唬 部ke)以自己用(yong)匯編寫一個小型(xing)C庫,但是有(you)現成的GLIBC,為啥要重復造(zao)輪子(zi)呢(ne)?)。

幸运pk10官网

到目前為止,博(bo)文(wen) GNU ARM交叉(cha)匯編環境(jing)的搭建與(yu)測(ce)試完成了ARM匯編環境(jing)的搭建,本文(wen)完成了Freestanding C 編譯(yi)環境(jing)的搭建,並(bing)給出(chu)了詳細的步(bu)驟和應用(yong)實例。

下一步(bu),就是在(zai)這兩個環境(jing)下多多練習,等熟練了,再開始ji) ㄗ鈧zhong)的Hosted C完整(zheng)開發環境(jing)。

Tag標(biao)簽︰環境(jing)  
  • 幸运pk10官网

About IT165 - 廣告服務 - 隱(yin)私聲明 - 版(ban)權(quan)申明 - 免(mian)責(ze)條款 - 網站(zhan)地圖 - 網友投稿 - 聯(lian)系(xi)方式
本站(zhan)內容來自za)諢?lian)網,僅(jin)供用(yong)于網絡技術學習,學習中請遵循相關法律法規
幸运pk10官网 | 下一页