zoukankan      html  css  js  c++  java
  • 万丈高楼平地起(一) S3C6410的启动

    废话不多说,去年折腾了一年s3c2440的板子,今年自己又买了一块s3c6410的板子,从今天开始,进行裸机驱动的开发,本文开始第一篇,启动代码的编写,注意,仅仅是启动代码,并不是bootloader,因为只有boot,没有loader。

           第一要明确:CPU上电之后,会从某个固定地址执行指令。ARM结构的CPU从地址0x00000000开始执行指令,MIPS结构的CPU将会从0XBFC00000取第一条指令并执行。(注意,这个地址是CPU的统一编址,需要把存储器件ROM或者flash映射到这个地址上

           第二要知道启动代码需要做那些事情:

                    1、异常向量表

                    2、禁看门狗,禁中断

                    3、设置系统时钟

                    4、初始化存储控制器

                    5、设置各个模式下的堆栈

                    6、跳转到C环境执行

           第三,要知道CPU的七种工作模式:

                     用户模式:程序正常运行的模式,不能直接从用户模式切换到其他模式

                     系统模式:支持操作系统的特权任务,与用户模式类似,但是可以直接切换到其他模式

                     管理模式:供操作系统使用的保护模式,只有在系统复位和软中断响应后,才能进入该模式

                     终止模式:用于虚拟内存和存储器保护的模式,对程序存储器或数据存储器访问失败时,进入此模式

                     未定义模式:只有在未定义指令异常响应时,才进入该模式

                     中断模式:在IRQ(普通中断)响应时,进入该模式

                     快速中断模式:在FIQ(快速中断)响应时,进入该模式。

            以上做一个简要的前提知识介绍,仅仅了解这些还不够,请自行查阅相关资料。下面我们来实现一个简单的boot代码,不懂汇编的,赶快去学 :-(

                     ARM上电后,从地址0x00000000取指并执行,但是从地址0x00000000开始一直到0x0000001c,都是异常向量表的位置,不要问我为什么,因为硬件是这么做的 :-(

                           [0x00000000] b ResetHandler    ;--CPU上电即在0地址执行这句跳转代码

                           [0x00000004] b UndHandler      ;--CPU遇到未定义指令时,跳转到此地址执行

                           [0x00000008] b SWIHandler      ;--CPU遇到软中断时,跳转到此地址执行

                           [0x0000000c] b PaAbort            ;--CPU取指令出错时,跳转到此地址执行

                           [0x00000010] b DaAbort           ;--CPU取数据出错时,跳转到该地址执行

                           [0x00000014] b 0x00000014;   ;--该地址保留,啥叫保留,就是占个位子,不使用....能否省略,写下句代码?答案是不行!

                           [0x00000018] b IRQHandler     ;--CPU碰到中断时,跳转到该地址执行

                           [0x0000001c] b FIQHandler     ;--CPU碰到快速中断时,跳转到该地址执行。

           本文主要写管理模式的代码,其他模式暂时忽略,以后讨论。本文将点亮开发板上的LED4灯,其他三个LED是灭的。(我用的是OK6410的板子)

                            ResetHandler

                                                    ldr r0,=WTCON    ;禁止看门狗

                                                    ldr r1,=0x0

                                                    str r1,[r0]

                                                    

                                                    ldr r0,=GPMCON    

                                                    ;从地板原理图看出四个LED灯接在GPM接口,那么我们就控制GPMCON寄存器即可,此处把GPMCON的地址写入r0寄存器

                                                    ldr r1,=0x111111     ;将数值0x111111

                                                    str r1,[r0]                 ;向GPMCON寄存器中写入0x111111直,是的GPM口都作为数据输出口。

                                                    ldr r0,=GPMDAT     ;将GPMDAT寄存器地址写入r0

                                                    ldr r1,=~(1<<3)       ;向r1寄存器写入二进制 111值

                                                    str r1,[r0]                ;向GPMDAT寄存器写入111值,此时可以看到开发板的LED4亮,其他三个LED是灭的

                                                    b halt                      ;进入死循环

                            halt

                                                     b halt

                             以下这些代码都是CPU其他工作模式下的代码,本文仅仅是做了一个简单的死循环处理,以后会讨论各种模式的使用方法。

                             HandlerUndef

                                                    b HandlerUndef

                             HandlerSWI

                                                    b HandlerSWI

                             HandlerPabort

                                                     b HandlerPabort

                             HandlerDabort

                                                     b HandlerDabort

                             HandlerIRQ

                                                     b HandlerIRQ

                             HandlerFIQ

                                                     b HandlerFIQ

              注意,本文代码没有禁中断,没有设置各个模式的堆栈,没有初始化sdram,也没有跳转到C预言执行环境,仅仅是点亮了一盏led灯,是最简单的一个启动代码,在连接选项中要设置Robase 为0x0地址,映像文件入口地址为0x0,映像文件头为startup.o,section为Init。如下图:

                 

                   

                  

                  调试方法:使用J-link v8进行调试,首先你得买j-link,Ok6410不带这个仿真器。然后装好驱动Setup_JLinkARM_V410i.zip,按照S3C6410的JLink的调试方法.pdf这个文档配置好开发环境,期间会提示缺少jlinkarm.dll,直接从j-link安装文件夹里把这个文件拷贝过去即可,然后使用axd进行调试。

                   源代码下载:最简单的ok6410启动代码,转载请注明出处:燕之威的实验室

                   补充说明:这里使用j-link是把代码下载到0x0地址,而0x0地址是片内的ram,然后j-link会接管cpu,将cup的pc寄存器(当前指令执行地址)指向0x0地址,然后执行。要说区别,唯一的区别是上电不能直接启动,因为代码是写在内存里的,掉电就丢失,如果想实现上电就启动,那么我们可以在启动代码中加入nand falsh的驱动,将我们的程序写入nand flash即可,这将在以后讨论 :-)

                   欢迎访问:我的新blog 

    80岁也要写程序
  • 相关阅读:
    协方差的意义
    ios7新特性实践
    微信支付大盗--黑色产业链
    UVA 297 Quadtrees(四叉树建树、合并与遍历)
    HDU 2876 Ellipse, again and again
    java中接口的定义与实现
    Oracle Linux 6.3下安装Oracle 11g R2(11.2.0.3)
    Fortran使用隐形DO循环和reshape给一维和多维数组赋初值
    Java实现 蓝桥杯VIP 算法训练 成绩的等级输出
    Java实现 蓝桥杯VIP 算法训练 成绩的等级输出
  • 原文地址:https://www.cnblogs.com/smartcoder/p/1971691.html
Copyright © 2011-2022 走看看