前言
我们是要编译出在 ARM 开发板上运行的可执行文件,所以要使用交叉编译器 arm-linux-gnueabihf-gcc 来编译。
交叉编译链的安装参考另外一篇博文:交叉编译链的安装
编译代码
本试验就一个 leds.s 源文件,所以编译比较简单。
源文件代码(leds.s):
.global _start @全局标号
_start:
/*使能所有外设时钟 */
LDR R0 , =0x020c4068 @CCGR0
LDR R1 , =0xffffffff @要想CCGR0写入的数据
STR R1 , [R0] @将R1的值写入到R0中
LDR R0 , =0x020c406c @CCGR1
STR R1 ,[R0]
LDR R0 , =0x020c4070 @CCGR1
STR R1 ,[R0]
LDR R0 , =0x020c4074 @CCGR1
STR R1 ,[R0]
LDR R0 , =0x020c4078 @CCGR1
STR R1 ,[R0]
LDR R0 , =0x020c407c @CCGR1
STR R1 ,[R0]
LDR R0 , =0x020c4080 @CCGR1
STR R1 ,[R0]
/*配置 GPIO_I003 PIN的复用为GPIO
* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0101 =5
* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器的地址为0x020E_0068
*/
LDR R0 , =0x020E0068 @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
LDR R1 , =0x5 @要写入的数据
STR R1 , [R0] @将5写入IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
/*配置 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的电器属性
* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址时0x020E_02F4
* bit0 : 0 低速率
* bit5-3: 110 R0/6 驱动能力
* bit7-6: 10 100MHz速度
* bit11: 0 关闭开路输出
* bit12: 1 使能pull/keeper
* bit15-14: 00 100K下拉
* bit16: 0 关闭hys
* 向寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03写入 0x10b0
*/
LDR R0 , = 0x020E02F4
LDR R1 , = 0x10b0
STR R1 ,[R0]
/*设置GPIO功能
*设置GPIO1_GDIR寄存器 设置GPIO1_GPIO03为输出
*寄存器GPIO_GDIR的地址是 0x0209C004
* 设置GPIO1_GDIR寄存器bit3为1也就是GPIO1_GPIO03为输出
*/
LDR R0 , = 0x0209C004
LDR R1 , = 0x8
STR R1 ,[R0]
/*打开LED,也就是设置GPIO1_GPIO03为0
*GPIO1_DR 寄存器地址为0x0209C000
*/
LDR R0 , = 0x0209C000
LDR R1 , =0
STR R1 ,[R0]
loop:
b loop
1.把 .s 文件编译成 .o文件
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
其中“-g”选项是产生调试信息,GDB 能够使用这些调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文件名字,这里我们指定 led.s 编译完成以后的文件名字为 leds.o。执行上述命令以后就会编译生成一个 leds.o 文件
2.把 .o文件编译成连接文件 .elf
arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置。
代码要运行,那就必须处于运行地址处,否则代码肯定运行出错。比如 I.MX6U 支持 SD 卡、EMMC、NAND 启动,因此代码可以存储到 SD 卡、EMMC 或者 NAND 中,但是要运行的话就必须将代码从 SD 卡、EMMC 或者NAND 中拷贝到其运行地址(链接地址)处,“存储地址”和“运行地址”可以一样
裸机例程都是烧写到 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 这个地址,使用如下命令:
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
上述命令中-Ttext 就是指定链接地址,“-o”选项指定链接生成的 elf 文件名,这里我们命名为 led.elf。上述命令执行完以后就会在工程目录下多一个 led.elf 文件
led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还需要将 led.elf 文件转换为.bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具了。
3.arm-linux-gnueabihf-objcopy 格式转换生成bin文件
arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为
led.bin 文件,命令如下:
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出,选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息。上述命令执行完成以后,工程目录如图
至此我们终于等到了想要的东西—led.bin 文件。
4.arm-linux-gnueabihf-objdump 反汇编
大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:
arm-linux-gnueabihf-objdump -D led.elf > led.dis
上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一个名为 led.dis 文件
可以看出 led.dis 里面是汇编代码,而且还可以看到内存分配情况。在0X87800000 处就是全局标号_start,也就是程序开始的地方。通过 led.dis 这个反汇编文件可以明显的看出到我们的代码已经链接到了以 0X87800000 为起始地址的区域。
这些命令一条条的敲太麻烦了,我们把它整理成一个Makefile文件
5.整理成makefile文件
是用“touch”命令在工程根目录下创建一个名为“Makefile”的文件,如图
创建好 Makefile 文件以后就需要根据 Makefile 语法编写 Makefile 文件了:
led.bin:led.s
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
clean:
rm -rf *.o led.bin led.elf led.dis
注意: Makefile 命令前一定要是tab键形成的四个空格
创建好 Makefile 以后我们就只需要执行一次“make”命令即可完成编译
上一篇:Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin文件到SD卡运行
下一篇:Linux之ARM(IMX6U)裸机汇编LED驱动实验--驱动编写
推荐阅读最新更新时间:2024-11-12 17:34
设计资源 培训 开发板 精华推荐
- 使用 MaxLinear, Inc 的 SPX2951 的参考设计
- 使用 Analog Devices 的 LTC1149 的参考设计
- 电蚊香
- VNH5050A评估板:适用于直流电动机的驱动,应用于双清洗泵和阀座调节
- 用于按钮控制电源排序的 LTC2953IDD-2 电压监控器的典型应用电路
- TCR4S15WBG、200mA、1.5V 输出电压 CMOS 低压降稳压器的典型应用
- LTC3252 的典型应用 - 双路、低噪声、无电感器降压型 DC/DC 转换器
- 使用 Analog Devices 的 LT1317BCS8 的参考设计
- 基于HDMI2C1-14HD的HDMI接口演示套件(主板加子板)
- 使用 Infineon Technologies AG 的 IRVRM2PBF 的参考设计
- Nothing融资5000万美元 并宣布和高通达成合作
- 全新Switch:支持DLSS技术、4K输出
- Bose推便携式蓝牙音箱SoundLink Flex:支持防尘防水
- Redmi K50渲染图揭秘:骁龙898性价神机外形大升级
- 魅族17、18、18s系列与18X将于11月推送Flyme 9.2
- vivo T系列首款机型T1x上架电商,或近期发布
- 谷歌发Android 12 CCD兼容性定义文档:后摄12MP起,最小6GB内
- 摩托罗拉Moto E40海外发布:虎贲T700芯片/90Hz屏,价格812元
- 华为nova 9/Pro手机鸿蒙HarmonyOS 2.0.1版本推送
- 红米Redmi 9A手机获得适老化认证证书,搭MIUI 12.5