Ubuntu搭建嵌入式开发(交叉编译)环境

摘要:
arm\n“);arm7d、arm966e-s、arm1026ej-s、arm10e、arm1136j-s、arm1156tf-s、arm1176jz-s、arm1176 jzf-s、cortex-a5、,

大家都比较熟悉gcc编译家族了,但是交叉编译到arm平台的代码是不直接使用gcc的,需要类似名字的一个程序。

1、首先写一个简单的c程序,helloArm.c, 如下:

 1 /*
 2  * =====================================================================================
 3  *
 4  *       Filename:  helloArm.c
 5  *
 6  *    Description:  
 7  *
 8  *        Version:  1.0
 9  *        Created:  10/23/2012 10:36:00 AM
10  *       Revision:  none
11  *       Compiler:  gcc
12  *
13  *         Author:  QuNengrong (QNR), Quner8@gmail.com
14  *        Company:  LordyWorkshop
15  *
16  * =====================================================================================
17  */
18 #include    <stdio.h>
19 int main(){
20     printf("hello, arm\n");
21     return 0;
22 }

2、查看gcc编译手册,进行初步编译尝试:

man gcc

       -mcpu=name
           This specifies the name of the target ARM processor.  GCC uses this name to determine what kind of instructions it can emit when
           generating assembly code.  Permissible names are: arm2, arm250, arm3, arm6, arm60, arm600, arm610, arm620, arm7, arm7m, arm7d,
           arm7dm, arm7di, arm7dmi, arm70, arm700, arm700i, arm710, arm710c, arm7100, arm720, arm7500, arm7500fe, arm7tdmi, arm7tdmi-s,
           arm710t, arm720t, arm740t, strongarm, strongarm110, strongarm1100, strongarm1110, arm8, arm810, arm9, arm9e, arm920, arm920t,
           arm922t, arm946e-s, arm966e-s, arm968e-s, arm926ej-s, arm940t, arm9tdmi, arm10tdmi, arm1020t, arm1026ej-s, arm10e, arm1020e,
           arm1022e, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1156t2-s, arm1156t2f-s, arm1176jz-s, arm1176jzf-s, cortex-a5,
           cortex-a7, cortex-a8, cortex-a9, cortex-a15, cortex-r4, cortex-r4f, cortex-r5, cortex-m4, cortex-m3, cortex-m1, cortex-m0,
           xscale, iwmmxt, iwmmxt2, ep9312, fa526, fa626, fa606te, fa626te, fmp626, fa726te.

           -mcpu=generic-arch is also permissible, and is equivalent to -march=arch -mtune=generic-arch.  See -mtune for more information.

           -mcpu=native causes the compiler to auto-detect the CPU of the build computer.  At present, this feature is only supported on
           Linux, and not all architectures are recognized.  If the auto-detect is unsuccessful the option has no effect.

       -mtune=name
           This option is very similar to the -mcpu= option, except that instead of specifying the actual target processor type, and hence
           restricting which instructions can be used, it specifies that GCC should tune the performance of the code as if the target were
           of the type specified in this option, but still choosing the instructions that it will generate based on the CPU specified by a
           -mcpu= option.  For some ARM implementations better performance can be obtained by using this option.

           -mtune=generic-arch specifies that GCC should tune the performance for a blend of processors within architecture arch.  The aim
           is to generate code that run well on the current most popular processors, balancing between optimizations that benefit some CPUs
           in the range, and avoiding performance pitfalls of other CPUs.  The effects of this option may change in future GCC versions as
           CPU models come and go.

           -mtune=native causes the compiler to auto-detect the CPU of the build computer.  At present, this feature is only supported on
           Linux, and not all architectures are recognized.  If the auto-detect is unsuccessful the option has no effect.

       -march=name
           This specifies the name of the target ARM architecture.  GCC uses this name to determine what kind of instructions it can emit
           when generating assembly code.  This option can be used in conjunction with or instead of the -mcpu= option.  Permissible names
           are: armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5e, armv5te, armv6, armv6j, armv6t2, armv6z, armv6zk,
           armv6-m, armv7, armv7-a, armv7-r, armv7-m, iwmmxt, iwmmxt2, ep9312.

主要的参数是 -march= ;尝试编译:

$gcc -march=armv6zk -S helloArm.c
helloArm.c:1:0: error: bad value (armv6zk) for -march= switch

出现错误了。。。 gcc手册中不是有着个参数么?怎么无法使用? 然后网上搜索交叉编译的软件,结果发现需要一个专用的gcc, 名为gcc-arm-linux-gnueabi。

在ubuntu下安装非常方便,如下:

$sudo apt-get install gcc-arm-linux-gnueabi

3、使用专用的gcc进行编译即可:

$arm-linux-gnueabi-gcc -S helloArm.c

使用-S只生成汇编文件,可用于分析;得到默认编译后的helloArm.s版本:

 1     .arch armv5t
 2     .fpu softvfp
 3     .eabi_attribute 20, 1
 4     .eabi_attribute 21, 1
 5     .eabi_attribute 23, 3
 6     .eabi_attribute 24, 1
 7     .eabi_attribute 25, 1
 8     .eabi_attribute 26, 2
 9     .eabi_attribute 30, 6
10     .eabi_attribute 34, 0
11     .eabi_attribute 18, 4
12     .file    "helloArm.c"
13     .section    .rodata
14     .align    2
15 .LC0:
16     .ascii    "hello, arm\000"
17     .text
18     .align    2
19     .global    main
20     .type    main, %function
21 main:
22     @ args = 0, pretend = 0, frame = 0
23     @ frame_needed = 1, uses_anonymous_args = 0
24     stmfd    sp!, {fp, lr}
25     add    fp, sp, #4
26     ldr    r0, .L3
27     bl    puts
28     mov    r3, #0
29     mov    r0, r3
30     ldmfd    sp!, {fp, pc}
31 .L4:
32     .align    2
33 .L3:
34     .word    .LC0
35     .size    main, .-main
36     .ident    "GCC: (Ubuntu/Linaro 4.7.2-1ubuntu1) 4.7.2"
37     .section    .note.GNU-stack,"",%progbits

看来默认是armv5t的平台,我买了一个开发板,是OK6410的,采用三星的S3C6410处理器,ARM1176JZF-S内核,主频533MHz/667MHz, 查看上一篇文章转载的各个arm体系对应的指令集,该处理器应该设置 -march=,编译如下:

$arm-linux-gnueabi-gcc -march=armv6zk -S helloArm.c

结果:

 1     .arch armv6zk               ;体系结构
 2     .fpu softvfp
 3     .eabi_attribute 20, 1
 4     .eabi_attribute 21, 1
 5     .eabi_attribute 23, 3
 6     .eabi_attribute 24, 1
 7     .eabi_attribute 25, 1
 8     .eabi_attribute 26, 2
 9     .eabi_attribute 30, 6
10     .eabi_attribute 34, 1
11     .eabi_attribute 18, 4
12     .file    "helloArm.c"
13     .section    .rodata
14     .align    2
15 .LC0:
16     .ascii    "hello, arm\000"
17     .text
18     .align    2
19     .global    main
20     .type    main, %function
21 main:
22     @ args = 0, pretend = 0, frame = 0
23     @ frame_needed = 1, uses_anonymous_args = 0
24     stmfd    sp!, {fp, lr}
25     add    fp, sp, #4
26     ldr    r0, .L3
27     bl    puts
28     mov    r3, #0
29     mov    r0, r3
30     ldmfd    sp!, {fp, pc}
31 .L4:
32     .align    2
33 .L3:
34     .word    .LC0
35     .size    main, .-main
36     .ident    "GCC: (Ubuntu/Linaro 4.7.2-1ubuntu1) 4.7.2"
37     .section    .note.GNU-stack,"",%progbits

到此,相应开发套件已经可用了,如果要生成对应二进制文件,跟使用常规的gcc一样,直接-o helloArm即可,如:

$arm-linux-gnueabi-gcc -o helloArm  helloArm.c

希望对大家有用;也欢迎大家多多指点和讨论;

 

免责声明:文章转载自《Ubuntu搭建嵌入式开发(交叉编译)环境》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇this.$alert 方法vue.config.json CopyWebpackPlugin 没有生效下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

交叉编译工具链(详解)

交叉编译工具链  1、嵌入式开发模型-交叉开发     在嵌入式开发过程中有宿主机和目标机的角色之分:宿主机是执行编译、链接嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。                在宿主机执行编译的流程如下:                   2、交叉编译工具链详解 参考: http://www.crifan.com/fi...

【C++11】准备:gcc 4.9.0编译安装

C++14都粗来了,现在才学C++11?是的,学习主动性太差了,我检讨。之前看过几眼,但没有机会应用到工作中,上家公司的环境是HP-UX,现在的开发环境还是古老的VS2008。所以一直没有用过,现在打算来练练手。 VS2013不知什么原因,每次新建项目点击完成以后就会崩溃,安装卸载了几个回合依然如此。所以放弃windows平台,安装虚拟机、ubuntu 1...

Qt5学习笔记(5)——列表框QListWidget类

QListWidget可以显示一个清单,清单中的每个项目是QListWidgetItem的一个实例,每个项目可以通过QListWidgetItem来操作。可以通过QListWidgetItem来设置每个项目的图像与文字。 常用方法和属性: (1)addItem void addItem ( const QString & label ) void...

纵横字谜的答案(Crossword Answers)

题目 输入一个r行c列(1<=r, c<=10)的网格,黑格用 * 表示,每个白格都填有一个字母。 如果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边界), 则称这个白格是一个起始格。 首先把所有起始格按照从上到下,从左到右的顺序编号为1,2,3,... ,如图  接下来要找出所有横向单词(Across)。这些单...

CentOS 多版本 GCC 共存

用于解决需要多个GCC版本的场景,可以自定义各版本GCC的名称 如何编译安装高版本GCC以及可能存在的动态链接库未替换问题参考以下两篇文章 https://zhuanlan.zhihu.com/p/33026927 https://itbilu.com/linux/management/NymXRUieg.html 首先可以在~/.bashrc文件里添加这...

工作问题解决

1.init  测试设计 选项 -e  telinit   -e init 测试选项 man 手册 正式。 2. 8.2 Linux源代码的目录结构8.2.1 Linux目录结构Linux的源代码全部在一个目录下,这里有很多文件夹,包含不同功能的源代码:├—init 内核初始化代码 ├—kernel 内核核心部分:进程,定时,程序执行,信号,模块... ├...