荣耀彩票代理

IT技术互动交流平台

GNUFreestanding(Naked)CARM交叉开发环境建与测试

来源:IT165收集  发布日期:2016-12-14 20:33:08

0 由来

在我的博文 GNU ARM交叉汇编环境的搭建与测试中,详细讲解了GNU ARM汇编环境的创建与使用方法。实际开发中,直接使用汇编语言写的代码往往很少,尽在系统启动和性能要求极其苛刻的时候才会用到汇编代码。在可读性、可移植性、逻辑表达能力方面,C语言的表现要比汇编强太多,正是C语言的这种优势造就了Unix世界,造就了Linux在多种平台上顺利编译运行的活泼场面。

荣耀彩票代理SUOYI,ZAIQIANRUSHIKAIFALINGYU,CYUYANSHIZHULIYUYAN。ZAISHIYONGKAIFAARMSHANGYUNXINGDECHENGXUZHIQIAN,BIXUGOUJIANYIGEHAOYONGDECJIAOCHABIANYIHUANJING。ZAIBOWENFreestanding CYUJIAOCHABIANYIQIDESHENGCHENGYUANLIFENXIZHONG,CHANSHULEFreestanding CDEGAINIANHEJIAOCHABIANYIQIGOUJIANDEYUANLI。GOUJIANYIGEWANZHENGDEHosted CJIAOCHABIANYIQISHIYIGEXIANGDANGFUZADEGUOCHENG,YOUQISHIDUIYUGCCLAISHUO,ZHEIGEGUOCHENGGENGSHICHONGMANJIANNANXIANZU。WEILEBIMIANCHUXUEZHESHOUCUO,WOMENCONGJIANDANKAISHI,XIANGOUJIANYIGEFreestanding DECJIAOCHABIANYIQI,RANHOUXIEYIGEJUTIDECXIANGMULAICESHI。

1 Freestanding C的构建

GCCXIANGMUZHUYAOYOULIANGDAGONGNENG,YISHITIGONGC,C++,FortranDENGDUOZHONGYUYANDEQIANDUAN(front end)BIANYIQI,YEJIUSHIFUZEBAGAOJIYUYANDAIMAFANYICHENGHUIBIANDAIMA;ERSHIZUOWEIZHENGGEKAIFAHUANJINGDEZONGRUKOU,FUZEDIAOYONGQITAHUIBIAN、LIANJIEGONGJU,LAIKONGZHIZHENGGEBIANYI–>HUIBIAN–>LIANJIEGUOCHENG。KEJIANGCCBENSHENBINGBUNENGDULIGONGZUO,BIXUYILAIYUWAIBUTIGONGDEHUIBIAN、LIANJIEDENGGONGJU,ERTIGONGZHEIXIEWAIBUGONGJUDEZUIZHUMINGRUANJIANJIUSHIbinutils。

荣耀彩票代理SUISHUOLILUNSHANGgccHEbinutilsDEANZHUANGMEIYOUXIANHOUDEBIYAOXING,DANSHIJISHANGgccBIANYIDEGUOCHENGZHONG,XUYAOYUNXINGbinutilsTIGONGDEGONGJULAIJINXINGCESHI,BINGGENJUCESHIJIEGUOLAIDONGTAIKONGZHIZISHENYUANMABIANYI。GUbinutilsBIXUXIANANZHUANG,ZHIHOUCAINENGBIANYIANZHUANGgcc。

1.1 使用binutils构建交叉汇编环境

binutilsDEBIANYIANZHUANGXIANGJIAN GNU ARMJIAOCHAHUIBIANHUANJINGDEDAJIANYUCESHI,BENWENBUZAIZHONGFUBIAOSHU。WEIBIANYUCANKAO,ZHIJICHUbinutilsDEPEIZHIMINGLING:

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

HOUMIANPEIZHIGCCSHI,XUYAOTIGONGYUZHIWANQUANYIZHIDEPEIZHICANSHUCAIXING。

1.2 使用GCC构建Freestanding C交叉编译环境

1.2.1官网下载GCC最新源码包

GCC的官网主页是http://www.gnu.org/software/gcc,这是GCC的大本营,也是整个GNU的核心部件。
截至今天(2016年12月13日)GCC的官方最新版本为gcc-6.2.0,下载的软件包名为gcc-6.2.0.tar.bz2。解压后得到文件夹gcc-6.2.0。
然后,进入gcc-6.2.0文件夹,执行./contrib/download_prerequisites脚本,这个脚本会自动下载编译GCC必须的库isl,mpc,gmp,mpfr等。不知道为啥GCC供下载的源码包里不直接附带这几个软件包,还非得让用户重新下载它。

其他的常规编译环境:本地GCC,GNU make,perl,awk,bash等等,就不在这里啰嗦了,一般的用于开发的Linux主机上都已经安装好了这些基本的开发环境。

1.2.2 配置安装

GCCXIANGMUYESHISHIYONGGNU autotools GUANLIBIANYIGUOCHENGDE,SUOYISHENGCHENGTADIYIBUBIXUSHIZHIXINGconfigureMINGLING。YUbinutilsYIYANG,gccYEJIANYIBAGOUJIANMULUHEYUANMAMULUFENLI,SUOYIXINJIANYIGEMULUMINGWEI build-gcc,RANHOUJINRUZHEIGEMULUJINXINGZHENGGEGOUJIANGUOCHENG。

mkdir build-gcc
cd build-gcc
../gcc-6.2.0/configure --prefix=/home/smstong/ARM         # 要与binutils配置时相同
                         --target=arm-linux-gnueabihf     # 要与binutils配置时相同
                         --enable-languages=c             # 只生成C编译器
                         --without-headers                # 不使用头文件
                         --disable-multilib               # 不生成多个库版本
make all-gcc            # 注意此处的目标是all-gcc,也就是freestanding C
make install-gcc        # 相应的安装的也只是GCC

荣耀彩票代理ANZHUANGWANCHENGYIHOU,HUIFAXIANXINSHENGCHENGDEJIAOCHABIANYIQI /home/smstong/ARM/bin/arm-linux-gnueabihf-gcc,TONGSHIHAIYOUYIGEYINGLIANJIEZAI/home/smstong/ARM/arm-linux-gnueabihf/bin/gcc。ZHIXINGRUXIAMINGLINGCESHI:

[smstong@centos192 bin]$ ./arm-linux-gnueabihf-gcc -v
使用内建 specs。
COLLECT_GCC=./arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/smstong/ARM/libexec/gcc/arm-linux-gnueabihf/6.2.0/lto-wrapper
目标:arm-linux-gnueabihf
配置为:../gcc-6.2.0/configure --prefix=/home/smstong/ARM/ --target=arm-linux-gnueabihf --enable-languages=c --without-headers --disable-multilib
线程模型:posix
gcc 版本 6.2.0 (GCC)

2 测试环境

目标机器环境:
(1)硬件平台TQ2440开发板,Soc CPU为三星2440, ARM920T核心。
(2)Norflash装有u-boot,可以通过tfgtp下载程序到指定物理内存地址并执行
(3)Nandflash装有Linux2.6系统,带有tftp客户端工具。
开发主机:
(1)Centos 7 PC机器
荣耀彩票代理 (2)装有tftp server,服务目录为/var/www/tftpboot/。

3 裸机环境下C程序测试实例

2.1 项目源码

YUANMAWENJIANJIEGOU:

.
├── 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);

    /* 熄灭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-gcc
LD = arm-linux-gnueabihf-ld
OBJCPY = arm-linux-gnueabihf-objcopy

all: 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: clean
clean:
    rm -rf *.o test test.bin

2.2 编译链接说明

荣耀彩票代理JIAOCHALIANJIEQIMORENDERUKOUDIANMINGCHENGWEI_start,MORENDEDAIMADUANJIDIZHIWEI0x00001074,SHENGCHENGDEKEZHIXINGWENJIANGESHIWEIelf。ERWOMENYAOXIANGRANGCHENGXUZAILUOJISHANGYUNXING,XUYAODAIMADUANJIDIZHIWEI0x30000000,WENJIANGESHIWEICHUNERJINZHIJINGXIANG。ZHEIDOUKEYITONGGUOLIANJIEJIAOBENQINGSONGWANCHENG。LINGWAIWOMENHAISHOUDONGZHIDINGLECHENGXURUKOUDIANWEIinitHANSHU。

TONGGUONorflashLIDEu-bootBASHENGCHENGDEtest.binJIAZAIDAOWULINEICUN0x30000000CHUBINGZHIXING,HUIFAXIANLED1DENGBEIXIMIE。ERQIEZHIXINGWANCHENGHOUZIDONGFANHUIDAOLEu-bootZHONG。YINWEIinit()HANSHUDEZUIHOUSHIreturnYUJU。

2.3 看看编译器生成的汇编代码

SHIYONGgcc test.c -c SHI,gccHUIBAZHONGJIANCHANSHENGDEHUIBIANDAIMAWENJIANYINZANG,WEILEKANDAOZHEIGEZHONGJIANWENJIAN,XUYAOTONGGUO-SXUANXIANGDIAOYONGgccLAISHENGCHENGHUIBIANDAIMAWENJIAN。

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

荣耀彩票代理SHANGSHUMINGLINGHUISHENGCHENGtest.sWENJIANRUXIA:

    .eabi_attribute 18, 4
    .file   'test.c'
    .text
    .align  2
    .global init
    .syntax unified
    .arm
    .fpu softvfp
    .type   init, %function
init:
    @ 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

荣耀彩票代理TONGGUOgccSHENGCHENGDEHUIBIANDAIMA,WOMENYEKEYIXUEXIGNU ARMHUIBIANDEJIBENYUFA。

4 Linux环境下Freestanding C程序测试实例

YOUYUSHIFreestanding CHUANJING,SUOYIJISHIZAILinuxXITONGXIA,RENGRANMEIYOUKEYONGDEBIAOZHUNCKU。ERCYUYANYOUBUNENGZHIJIEZHIXINGRUANZHONGDUANZHILINGDIAOYONGLinuxDEXITONGDIAOYONG,ZHEIJIUDAOZHICAOZUOXITONGTIGONGDEAPIWANQUANBUKEYONG!(HUIBIANYUYANFANERKEYIZHIJIETONGGUOswiZHILINGLAIDIAOYONGXITONGAPI)KEJIANZAICAOZUOXITONGXIA,RUGUOMEIYOUCKU,CYUYANGENBENWUFADUIYINGJIANJINXINGCAOZUO,YEJIUBUKENENGCAOKONGKAIFABANSHANGDELEDDENG,SHENZHIYEBUNENGDAYINJIANDANDEhello world,ZHEISHIHEDENGDEBEIAI!

为了便于测试,我们不得不借助汇编的帮助,采用C语言和汇编语言混合编程的方式。其中汇编语言提供一个打印字符串的函数和一个退出进程的函数,C语言调用之。
其实这就相当于自己用汇编语言实现了一个超级简化的POSIX系统调用C库。
C语言和汇编进行彼此调用,就必须要遵守相应的函数调用规范,及APCS(ARM Process Call Standard),请大家自行学习之。

4.1 项目源码

XIANGMUWENJIANJIEGOUTU:

.
├── api.h         # api 头文件说明
├── api.s         # api 实现
├── Makefile      
├── test.c
└── test.lds     # 链接脚本,指示程序入口

WENJIAN api.h

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

WENJIANapi.s

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

 */

.text
.global print
.global exit
print:
    swi #0x900004
    mov pc,lr

exit:
    swi #0x900001
    mov pc,lr
~

WENJIANtest.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);
}

WENJIANtest.lds

ENTRY(test)

WENJIANMakefile

CC = arm-linux-gnueabihf-gcc
AS = arm-linux-gnueabihf-as
LD = arm-linux-gnueabihf-ld
OBJCPY = arm-linux-gnueabihf-objcopy

all: 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: clean
clean:
    rm -rf *.o test

4.2 编译链接说明

荣耀彩票代理JIAOCHALIANJIEQIMORENSHENGCHENGelfGESHIWENJIAN,KEYIZHIJIEBEILinuxJIAZAIZHIXING。YINGWEISHIFreestanding C,XUYAOZAILIANJIEJIAOBENZHONGZHIDINGCHENGXURUKOUDIAN。

CHENGXUZHIXINGJIEGUO:

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

5 对Freestanding C的思考

ZAILUOJIXIA,Freetanding CSHANGKEYITONGGUOZHIZHENDEFANGSHIZHIJIECAOKONGBUFENYINGJIANZIYUAN;ZAIOSXIA,SUOYOUYINGJIANZIYUANSHOUDAOCAOZUOXITONGDEBAOHU(TONGGUOMMU),Freestanding CGENBENWUFADULICAOKONGRENHEYINGJIAN。

SUOYIZAISHIJIDEKAIFAZHONG:

如果是裸机项目,C库本来就不可用,Freestanding C是唯一可选C环境,而且能够完美完成任务; 如果是基于OS的项目,那么Freestanding C能力不足,必须要有完整的Hosted C环境才能胜任(当然,也可以自己用汇编写一个小型C库,但是有现成的GLIBC,为啥要重复造轮子呢?)。

6 小结

荣耀彩票代理DAOMUQIANWEIZHI,BOWEN GNU ARMJIAOCHAHUIBIANHUANJINGDEDAJIANYUCESHIWANCHENGLEARMHUIBIANHUANJINGDEDAJIAN,BENWENWANCHENGLEFreestanding C BIANYIHUANJINGDEDAJIAN,BINGJICHULEXIANGXIDEBUZHOUHEYINGYONGSHILI。

荣耀彩票代理XIAYIBU,JIUSHIZAIZHEILIANGGEHUANJINGXIADUODUOLIANXI,DENGSHULIANLE,ZAIKAISHIDAJIANZUIZHONGDEHosted CWANZHENGKAIFAHUANJING。

Tag标签:   
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规