zoukankan      html  css  js  c++  java
  • 一个简单的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 # 可以看到效果了

  • 相关阅读:
    springboot集成flowable oracle数据库版本报错
    Vue.js中this.$nextTick()的使用
    Centos下虚拟环境的创建以及python3安装
    SaltStack实战
    第一章 Jenkins安装配置
    JavaScript 常用正则表达式
    ps 掉出字符设备面板,修改颜色等
    博客验证码破解
    我终于想起密码了~
    Linux grep 命令
  • 原文地址:https://www.cnblogs.com/kwingmei/p/3219284.html
Copyright © 2011-2022 走看看