Ubuntu交叉编译器的安装和代码的编译过程(此为裸机编译)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

一、交叉编译器的安装

1复制交叉编译器软件到Ubuntu系统中

在Ubuntu系统中新建个tool目录用来存放交叉编译器。
在这里插入图片描述

2解压交叉编译器

sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

等待解压完成,解压完成以后会生成一个名为“gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf”的文件夹,这个文件夹里面就是我们的交叉编译工具链。
在这里插入图片描述

3修改环境变量

修改/etc/profile 文件,在profile中添加编译器bin的目录,输入指令如下

pwd

在这里插入图片描述

sudo vi /etc/profile

在文档最后添加如下目录
在这里插入图片描述

4安装交叉编译器所需要的C库

输入指令如下

sudo apt-get install lsb-core lib32stdc++6

5重启系统,验证交叉编译器

输入指令如下,查看交叉编译器版本

arm-linux-gnueabihf-gcc -v

在这里插入图片描述

二、代码的编译过程

1编译指令

代码如下:

arm-linux-gnueabihf-gcc -g -c led.s -o led.o
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
arm-linux-gnueabihf-objdump -D led.elf > led.dis

💦第一条指令
💦源文件都会通过编译器被编译成对于的.o文件,在STM32中也一样的,MDK编译后也会生成对于的.o文件如下图所示,一个工程中所有的 C文件和汇编文件都会编译生成一个对应的.o 文件,我们需要将这.o 文件链接起来组合成可执行文件
💦STM32编译过程对应的.o文件。
在这里插入图片描述

💦第二条指令
💦arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置。在SMT32 中没有“链接”的这个概念,我们一般用 MDK 编写好代码,然后点击“编译”,MDK 就会自动帮我们编译好整个工程,最后再点击“下载”就可以将代码下载到开发板中。这是因为链接这个操作 MDK 或者 IAR 已经帮你做好了,下面这个图左侧的IROM1 是设置 STM32 芯片的 ROM 起始地址和大小的,右边的 IRAM1 是设置 STM32 芯片的 RAM 起始地址和大小的。其中 0X08000000 就是 STM32 内部 ROM 的起始地址,编译出来的指令肯定是要从 0X08000000 这个地址开始存放的。
在这里插入图片描述
💦对于STM32 来说 0X08000000 就是它的链接地址,这些.o 文件就是这个链接地址开始依次存放,最终生成一个可以下载的 hex 或者 bin 文件,我们可以打开.map 文件查看一下这些文件的链接地址

在这里插入图片描述

💦从可以看出 STM32 的各个.o 文件所处的位置,起始位置是 0X08000000。由此可以得知,我们用 MDK 开发 STM32 的时候也是有链接的,只是这些工作 MDK 都帮我们全部做好了。
💦因此在Linux中,我们在烧录程序前要确认可执行文件的运行起始地址,也就是链接地址。这里我们要区分“存储地址”和“运行地址”这两个概念,存储地址就是可执行文件存储在哪里,可执行文件的存储地址可以随意选择。运行地址就是代码运行的时候所处的地址,这个我们在链接的时候就已经确定好了,代码要运行,那就必须处于运行地址处,否则代码肯定运行出错。比如 I.MX6U 支持 SD 卡、EMMC、NAND 启动,因此代码可以存储到 SD 卡、EMMC 或者 NAND 中,但是要运行的话就必须将代码从 SD 卡、EMMC 或者NAND 中复制到运行地址(链接地址)处,“存储地址”和“运行地址”可以一样,比如STM32 的存储起始地址和运行起始地址都是 0X08000000。
💦对于I.MX6U的程序,可以烧录到 SD 卡中,上电以后 I.MX6U 的内部 boot rom 程序会将可执行文件拷贝到链接地址处,这个链接地址可以在 I.MX6U 的内部 128KB RAM 中(0X900000~0X91FFFF),也可以在外部的 DDR 中。在 DDR中,链接起始地址为 0X87800000。I.MX6U-ALPHA 开发板的 DDR 容量有两种:512MB 和256MB,起始地址都为 0X80000000,只不过 512MB 的终止地址为 0X9FFFFFFF,而 256MB 容量的终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为 Uboot 其链接地址就是 0X87800000,这样方便统一使用 0X87800000 这个链接地址。确定了链接地址以后就可以使用 arm-linux-gnueabihf-ld 来将前面编译出来的 led.o 文件接到 0X87800000 这个地址,使用如下命令生成.elf文件

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

💦DDR起始地址:DDR通过MMDC控制,MMDC在内存中的映射地址如下图所示,与STM32的静态存储访问器FSMC一样原理,DDR大小由DDR芯片决定。
在这里插入图片描述
💦第三条指令
💦led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还需要将 led.elf 文件转换为.bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具。

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

💦上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出,选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试
信息。上述命令执行完成以后,生成.bin文件。
💦第四条指令
💦大多数情况下我们都是用 C 语言写程序,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令

arm-linux-gnueabihf-objdump -D led.elf > led.dis

上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一个名为 led.dis 文件。打开.dis文件内容就包括链接地址。
在这里插入图片描述

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值