1.start.S
完成C语言环境搭建:
①设置处理器运行到SVC模式下
②初始化 SP 指针
③跳转到C文件的main函数中。
1 .global _start 2 .global _bss_start 3 _bss_start: 4 .word __bss_start 5 .global _bss_end 6 _bss_end: 7 .word __bss_end 8 _start: 9 /*设置处理器进入SVC模式 */ 10 mrs r0, cpsr //读取cpsr到r0 11 bic r0, r0, #0x1f //清除cpsr的bit4-0 12 orr r0, r0, #0x13 //使用SVC模式 13 msr cpsr, r0 //将r0写入到cpsr 14 15 /*清除BSS段 */ 16 ldr r0, =_bss_start 17 ldr r1, =_bss_end 18 mov r2, #0 19 bss_loop: 20 stmia r0!, {r2} 21 cmp r0, r1 //比较R0和R1里面的值 22 ble bss_loop//如果R0地址小于等于R1,继续清除BSS段 23 24 /*设置SP指针 */ 25 ldr sp, =0x80200000 26 b main //跳转到C语言main函数
2.main.c
完成功能,LED的0.5s的亮灭(I.MX6ULL主频396MHz)。
1 #include "imx6u.h" 2 /*使能外设时钟*/ 3 void clk_enable(void) 4 { 5 CCM->CCGR0 = 0xFFFFFFFF; 6 CCM->CCGR1 = 0xFFFFFFFF; 7 CCM->CCGR2 = 0xFFFFFFFF; 8 CCM->CCGR3 = 0xFFFFFFFF; 9 CCM->CCGR4 = 0xFFFFFFFF; 10 CCM->CCGR5 = 0xFFFFFFFF; 11 CCM->CCGR6 = 0xFFFFFFFF; 12 } 13 14 /*初始化LED*/ 15 void led_init(void) 16 { 17 IOMUX_SW_MUX->GPIO1_IO03 = 0x5;//复用为GPIO1_IO03,bit0/2置1 18 IOMUX_SW_PAD->GPIO1_IO03 = 0x10B0;//设置GPIO1_IO03的电气属性,bit4/5/7/12置为1. 19 /*GPIO初始化*/ 20 GPIO1->GDIR = 0x8;//设置为输出,bit3置1 21 GPIO1->DR = 0x0;//打开LED灯 22 23 } 24 25 /*短延时*/ 26 void delay_short(volatile unsigned int n) 27 { 28 while(n--){} 29 } 30 31 /*延时,一次循环大概是1ms,在主频390MHz 32 *n:延时ms数 33 */ 34 void delay(volatile unsigned int n) 35 { 36 while(n--){ 37 delay_short(0x7ff); 38 } 39 } 40 41 /*打开LED灯*/ 42 void led_on(void) 43 { 44 GPIO1->DR &= ~(1<<3);//bit3清零 45 } 46 47 /*关闭LED灯*/ 48 void led_off(void) 49 { 50 GPIO1->DR |= (1<<3);//bit3置1 51 } 52 int main(void) 53 { 54 clk_enable();//使能外设时钟 55 led_init();//初始化LED 56 /*初始化LED*/ 57 58 /*设置LED闪烁*/ 59 while(1){ 60 led_on(); 61 delay(500); 62 63 led_off(); 64 delay(500); 65 } 66 return 0; 67 }
3.Makefile
objs := start.o main.o ld := arm-linux-gnueabihf-ld gcc := arm-linux-gnueabihf-gcc objcopy := arm-linux-gnueabihf-objcopy objdump := arm-linux-gnueabihf-objdump ledc.bin : $(objs) $(ld) -Timx6u.lds -o ledc.elf $^ $(objcopy) -O binary -S ledc.elf $@ $(objdump) -D -m arm ledc.elf > ledc.dis %.o : %.c $(gcc) -Wall -nostdlib -c -O2 -o $@ $< %.o : %.S $(gcc) -Wall -nostdlib -c -O2 -o $@ $< clean: rm -rf *.o ledc.bin ledc.elf ledc.dis
4.链接脚本
主要做了:
①通过“-Ttext”来指定链接地址是 0X87800000
②清除bss段。清除前,需要使用如下语句来进行4字节对齐。不对齐而清除在某些情况下会发生数据丢失。
1 SECTIONS { 2 . = 0x87800000; 3 .text : 4 { 5 start.o 6 *(.text) 7 } 8 .rodata ALIGN(4) : {*(.rodata)} 9 .data ALIGN(4) : {*(.data)} 10 . = ALIGN(4); 11 __bss_start = .; 12 .bss ALIGN(4) : {*(.bss)*(COMMON)} 13 __bss_end = .; 14 }