一个简单的arm 裸机程序

是参照网上的一些例子

start.S

.globl _start /*汇编的入口, 生成bin文件的开始处的标识, 把程序加载到某个地址, 用go 命令 go addr, 执行的就是下面的一条指令 */
_start:
    /* peri port setup = Peripheral port setup */
    ldr r0,=0x70000000
    orr r0, r0, #0x13
    mcr p15, 0, r0, c15, c2, 4 /*写处理器的操作 mcr move to coprocessor from register */

/*

当时很疑惑,不知道这段代码有什么用,经过一番查找,原来和ARM的协处理器有关,如下所示:

c15, Peripheral Port Memory Remap Register。

其实,arm11把memory和Peripheral接口分开了,上面的代码在初始化是告诉CPU外设寄存器的基地址和地址空间。
我却没有这份求知心
 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/Bgbfejia.html 有说明
*/

    /* close watch dog  0x7e004000文档上有, 是在上一步的基础上的 */
    ldr r0,=0x7e004000
    mov r1, #0
    str r1, [r0]

    /* setup sp */
    ldr sp,=0x50000000 + 8*1024   /* 不知道 与0x50000000 + 4*1024的区别, 是sd or nand 方式 设置栈指针 */

    /* go to setup clock 调用c函数 bl = branch with link */
    bl clock_init
    
halt:
    b halt

end of start.S

 

main.c

#define GPKCON0  (*((volatile unsigned long *)0x7f008800))
#define GPKDAT  (*((volatile unsigned long *)0x7f008808))

/* Bit Operate */
#define SET_BIT(x,y) (x|=(1<<y)) // 设置 x的ybit为 1
#define CLR_BIT(x,y) (x&=~(1<<y)) // 设置x的ybit为0
#define CPL_BIT(x,y) (x^=(1<<y)) // 设置x的ybit为原来的反 1-》0 0-》1
#define GET_BIT(x,y) (x&(1<<y)) // 获取x的ybit的值   如x=0x09123456 GET_BIT(x,24) 返回 0x01000000

void delay()
{
     volatile unsigned long i=0x100000;
     while(i--)

    ;
}

void clock_init()
{
    int i=0;
    GPKCON0=0x11110000; // gpk的控制寄存器 表示控制 led1 -led4
    GPKDAT=0XF0;       // gpk的数据寄存器 数据为0 表示低电平 来点亮led

    for(i=0;i<100;i++)
    {
        if(i%2==0)
               CLR_BIT(GPKDAT,4);
        else
            SET_BIT(GPKDAT,4);
        if(i%2==0)
            SET_BIT(GPKDAT,6);
        else
            CLR_BIT(GPKDAT,6);

   delay(); //延时函数

   }

}

makefile

led.bin: start.o main.o
    arm-linux-ld -Ttext 0x50000000 -o led.elf $^ #生成elf文件 text的第一条指令定位到0x50000000 (我们之后要加载的地方一致)
    arm-linux-objcopy -O binary led.elf led.bin #去掉elf文件的其他信息数据, 使text的第一条指令位于文件的开始
    arm-linux-objdump -D led.elf > led.dis #led.elf的相关符号信息

%.o : %.S
    arm-linux-gcc -o $@ $< -c

%.o : %.c
    arm-linux-gcc -o $@ $< -c

clean:
    rm *.o led.bin led.dis

 

end of makefile

 

进入到uboot命令行发

tftp 0x50000000(与编译一致) led.bin # 把led.bin 从tftp服务器加载到内存的0x50000000处

go 0x50000000 # 可以看到效果了

 

posted on 2013-07-27 12:34  kwingmei  阅读(817)  评论(0编辑  收藏  举报

导航