x86_64编译ARM交叉编译LED汇编程序
x86_64搭建ARM交叉编译工具链 |
我们是要编译出在ARM开发板上运行的可执行文件,所以要使用交叉编译器arm-linux-gnueabihf-gcc来编译。因此本试验就一个led.s源文件,所以编译比较简单。先将led.s编译为对应的.o文件,在终端中输入如下命令:
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
这里编写了一个leds.s文件,参考IMX6ULL开发板手册
.global _start /* 全局标号 */
/*
* 描述:_start函数,程序从此函数开始执行此函数完成时钟使能、
* GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
*/
_start:
/* 例程代码 */
/* 1、使能所有时钟 */
ldr r0, =0X020C4068 /* CCGR0 */
ldr r1, =0XFFFFFFFF
str r1, [r0]
ldr r0, =0X020C406C /* CCGR1 */
str r1, [r0]
ldr r0, =0X020C4070 /* CCGR2 */
str r1, [r0]
ldr r0, =0X020C4074 /* CCGR3 */
str r1, [r0]
ldr r0, =0X020C4078 /* CCGR4 */
str r1, [r0]
ldr r0, =0X020C407C /* CCGR5 */
str r1, [r0]
ldr r0, =0X020C4080 /* CCGR6 */
str r1, [r0]
/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */
ldr r0, =0X020E0068 /* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */
ldr r1, =0X5 /* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */
str r1,[r0]
/* 3、配置GPIO1_IO03的IO属性
*bit 16:0 HYS关闭
*bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper功能
*bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度100Mhz
*bit [5:3]: 110 R0/6驱动能力
*bit [0]: 0 低转换率
*/
ldr r0, =0X020E02F4 /*寄存器SW_PAD_GPIO1_IO03_BASE */
ldr r1, =0X10B0
str r1,[r0]
/* 4、设置GPIO1_IO03为输出 */
ldr r0, =0X0209C004 /*寄存器GPIO1_GDIR */
ldr r1, =0X0000008
str r1,[r0]
/* 5、打开LED0
* 设置GPIO1_IO03输出低电平
*/
ldr r0, =0X0209C000 /*寄存器GPIO1_DR */
ldr r1, =0
str r1,[r0]
/*
* 描述:loop死循环
*/
loop:
b loop
裸机例程都是烧写到SD卡中,上电以后I.MX6U的内部boot rom程序会将可执行文件拷贝到链接地址处,这个链接地址可以在I.MX6U的内部 128KB RAM中(OX900000~OX91FFFF),也可以在外部的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
裸机代码的链接起始地址为0X87800000。要使用DDR,那么必须要初始化DDR,对于I.MX来说bin文件不能直接运行,需要添加一个头部,这个头部信息包含了DDR的初始化参数,I.MX系列SOC内部boot rom会从SD卡,EMMC等外置存储中读取头部信息,然后初始化DDR,并且将bin文件拷贝到指定的地方。
Bin的运行地址一定要和链接起始地址一致。位置无关代码除外。
生成led.bin
反汇编
I.MX6ULL支持SD卡、EMMC、NAND、nor、SPI flash等等启动。裸机例程选择烧写到SD卡里面。
在ubuntu下向SD卡烧写裸机bin文件。烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡绝对地址上。而且对于I.MX而言,不能直接烧写bin文件,比如先在bin文件前面添加头部。
在ubuntu下向SD卡烧写裸机bin文件。烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡绝对地址上。而且对于I.MX而言,不能直接烧写bin文件,比如先在bin文件前面添加头部。完成这个工作,需要使用正点原子提供的imxdownload 软件。Imxdownload使用方法,确定要烧写的SD卡文件,我的是/dev/sdf。给予imxdownload
可执行权限:
Chmod 777 imxdownload
烧写:
./imxdownload led.bin /dev/sdf
Imxdownlaod会向led.bin添加一个头部,生成新的load.imx文件,这个load.imx文件就是最终烧写到SD卡里面去的。
编写Makefile
led.bin:leds.s
arm-linux-gnueabihf-gcc -g -c leds.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 -f led.bin *.o led.elf led.dis