OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子新作:阿波罗STM32F767&F429&探索者STM32F4开发板&赶快来下载资料哦。

查看: 685|回复: 0

OK6410开发板学习之一步一步实现精简BootLoader(BL1部分)一

[复制链接]

  离线 

12

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2016-7-24
在线时间
13 小时
发表于 2018-4-18 20:55:37 | 显示全部楼层 |阅读模式
正点原子公众号

众所周知,ok6410开发板是一块基于s3c6410芯片的开发板,板载资源丰富。s3c6410是三星电子生产的基于arm11内核的芯片。本文旨在总结一下bootloader操作步骤,用于以后复习、查找。通过分析bootloader行业老大哥uboot代码,总结出要实现OK6410开发板的启动引导,只要实现如下的操作即可:

1. 设置异常向量表;

2. 设置处理器模式为svc模式;

3. 外设基地址初始化;

4. 关闭看门狗;

5. 关闭所有中断;

6. 关闭MMU和cache;

7. 初始化系统时钟;

8. 内存初始化;

9. 复制内存;

10.栈初始化;

11.清除bss段;

12.跳入c函数(点亮led)。

下面一步一步的介绍如何实现它们。

1. 设置异常向量表:


想要设置arm的异常向量表,首先得知道其有那些异常,查看arm架构参考手册Programmers’ Model 章节的A2.6 Exceptions我们知道其共有7中异常,如下图:


设置异常向量表,按我个人的理解其实就是将异常发生时要处理的地址指向PC即可,所以通过如下代码来实现:

.text.global _start_start:        b reset        ldr pc, _undifined_instruction                 @ 将pc指针指向地址_undefined_instruction处,即当该异常发生时处理器跳到标号undifined_instruction处执行        ldr pc, _software_interrupt        ldr pc, _prefetch_abort        ldr pc, _data_abort        ldr pc, _not_used        ldr pc, _irq        ldr pc, _fiq                                                                _undifined_instruction:  .word undifined_instruction      @ .word 伪指令,用于取地址,该段表示_undefined_instruction是一个指向标号                                                        @ undifined_instruction处的32位地址_software_interrupt:        .word software_interrupt_prefetch_abort:        .word prefetch_abort_data_abort:        .word data_abort_not_used:        .word not_used_irq:        .word irq_fiq:        .word resetundifined_instruction:nopsoftware_interrupt:nopprefetch_abort:nopdata_abort:nopnot_used:nopirq:nopfiq:nop

开头的.text告诉编译器下面的内容是代码段,.global _start告诉编译器_start是全局的。细心的人可能会发现,明明只有7种异常,为什么会有8个异常向量表,多出来的not_used是啥?从字面理解,它是一个未使用的异常,细心阅读arm架构参考手册就会发现有下面这么一段话


地址0x00000014处向量是一个未使用的,预留的向量表,从异常处理模式图也能发现0x00000010和0x00000018之间不是连续的,如下图:


为了异常的连续性,或者说是异常发生能够正确找到异常向量表,我们需要补全这个乡里表。

分析代码可知,首先跳转到reset处执行代码,那么在reset处都干啥呢了,我们可以找到reset处看一下,代码如下:

reset:        bl set_svc              @ 设置cpu为svc模式        bl set_peri_port        @ 外设基地址初始化        bl disable_watchdog     @ 关闭看门狗        bl disable_interrupt    @ 关闭所有中断        bl disable_mmu          @ 关闭mmu和cache        bl init_clock           @ 时钟初始化        bl mem_init             @ 内存初始化        bl copy_to_ram          @ 拷贝bl到内存        bl init_stack           @ 栈初始化        bl clean_bss            @ 初始化bss段        ldr pc, =main           @ 进入c语言编程环境,main函数

原来后面的操作都是从reset处一次执行的,下面一步一步的介绍接下来的操作。

2.设置处理器模式为svc模式:bl set_svc

通过查看arm架构参考手册“A2.2 Processor modes ”章节可以知道,arm共有7种工作模式,如下:


要想cpu工作在svc模式下,首先我们来了解一下arm的程序状态寄存器CPSR,它可以用来改变工作模式等操作,CPSR格式如下:


它的低5位就是模式选择,通过查看模式为设置,可知只要将cpsr的第五位设置成0b10011就可以了,如下:


理论上,到此就可以了,但是,我们发现cpsr的I、F位是关于中断的,这里顺便也将其配置了,关闭IRQ和FIQ如下图:


代码如下:

        @ set the cpu to SVC32 modeset_svc:        mrs        r0,cpsr             @ 将程序状态寄存器取出保存在通用寄存器r0中        bic        r0,r0,#0x1f         @ 将从状态寄存器取出的值(r0)低5位清零后存入r0中        orr        r0,r0,#0xd3         @ 将r0中的值的第0 1 4 6 7位置1后存入r0中,关闭中断与快速中断,进入svc模式        msr        cpsr,r0             @ 将r0的中的值写入程序状态寄存器        mov pc, lr                  @ 返回调用的地方下一个地址处继续执行

2.外设基地址初始化:bl set_peri_port

这一步必须要做,而且必须在这一步做,否则cpu无法正常使用外设。要想初始化s3c6410的外设基地址,首先得知道外设基地址是从0x7000000开始的,同时还得了解一下arm11的协处理器p15的内容,参考arm11内核手册,找到系统协处理器章节,找到关于Peripheral Port Memory Remap Register的协处理器命令,如下:


跳到page 3-130章节处,查看其详细内容。该寄存器格式如下:


[31:12]:表示基地址,这里我们需要将其设成0x70000000,

[11:5]:不要考虑,保留默认值即可,

[4:0]:外设基地址的大小,s3c6410外设需要256M大小的内存。

查看Peripheral Port Memory Remap Register bit functions ,如下图:


通过上图可知只要往p15的c15中写入0x70000013即可。代码如下:

  @ 初始化外设地址,必须做这一步,要不外设无法使用。set_peri_port:        ldr r0, =0x70000000     @ 将基地址0x70000000存入寄存器r0中        orr r0, r0, #0x13       @ 将寄存器r0的值设为0x70000013        mcr p15,0,r0,c15,c2,4          @ 将寄存器r0的值传送到协处理器p15的c15寄存器中,参看arm11内核手册:c15, Peripheral Port Memory Remap Register        mov pc, lr              @ 返回调用处继续往下执行

3.关闭看门狗:bl disable_watchdog

要想关闭看门狗,需要找到看门狗控制寄存器地址,通过查看s3c6410手册Watch Dog章节可以找到,如下:


看门狗控制寄存器位操作说明如下:


红框中的就是和关闭看门狗有关的位,只要将这几个位设置为0,即将看门狗控制寄存器设为0。代码如下:

  @ Disable Watchdog 参看s3c6410手册:Watch Dog章节#define pWTCON 0x7e004000  @ addr of watchdog timer control register (WTCON)disable_watchdog:        ldr r0, =pWTCON         @ 将看门狗控制寄存器地址写入寄存器r0中        mov r1, #0x0            @ 将0x0保存在寄存器r1中        str r1, [r0]            @ 将0x0传送到看门狗控制寄存器中        mov pc, lr              @ 返回调用处继续往下执行

4.关闭所有中断:bl disable_interrupt


可能有人会问,在前面设置cpu为svc工作模式时不是已经关闭了IRQ和FIQ吗,这里还需做啥操作呢?之前的只是关闭了中断,但是并没有清除中断使能位,这里就是进行这样的操作,清除所有中断的使能位。s3c6410共有两个中断控制器VIC0、VIC1。所以需要分别找到这两个INTERRUPT ENABLE CLEAR 寄存器,并且对其进行配置,如下图:


通过上图,可知只要将其设置为0 即可,代码如下:

        @ Disable all interrupts (VIC0 and VIC1),参考s3c6410手册:Vectored Interrupt Controller章节disable_interrupt:        mvn r1,#0x0        ldr r0,=0x71200014      @ VIC0INTENCLEAR地址        str r1,[r0]             @ 将VIC0INTENCLEAR设为0        ldr r0,=0x71300014      @ VIC1INTENCLEAR地址        str r1,[r0]             @ 将VIC1INTENCLEAR设为0                mov pc, lr              @ 返回调用处继续往下执行

5.关闭mmu和cache

MMU是MemoryManagement Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。

Cache:高速缓冲存储器,是位于CPU和主存储器DRAM(DynamicRandomAccessMemory)之间,规模较小,但速度很高的存储器,通常由SRAM(StaticRandomAccessMemory静态存储器)组成。它是位于CPU与内存间的一种容量较小但速度很高的存储器。CPU的速度远高于内存,当CPU直接从内存中存取数据时要等待一定时间周期,而Cache则可以保存CPU刚用过或循环使用的一部分数据,如果CPU需要再次使用该部分数据时可从Cache中直接调用,这样就避免了重复存取数据,减少了CPU的等待时间,因而提高了系统的效率。3sc6410含有两个cache,分别是数据cache和指令cache。

这么好的东西为什么要关闭呢?对呀,为什么呀?那是因为相对于s3c6410的启动引导文件,并不需要使用到他们,开启了使用不当反而会导致异常产生。那么如何来关闭他们呢?这又的操作协处理器p15了。查看arm架构参考手册协处理器相应章节,找到cache相关协处理器命令,如下:


协处理器的命令都是死命令,想干啥找到了直接用就可以,是不是很爽呢?这里只是让cache失效了,但是cache具体使能位和mmu使能位还没有设置,找到协处理器的控制寄存器(c1),其中有这么一句话,如下红框中:


协处理器p15的控制寄存器c1格式如下:


详细说明如下:


因此我们只要设置[2:0]位位0即可,顺便关闭字节对齐检查功能,代码如下:

        @ 关闭MMU和cache        disable_mmu:        mcr p15,0,r0,c7,c7,0    @ 使I/D cache全部失效 参考arm11内核手册:c7, Cache operations        mrc p15,0,r0,c1,c0,0    @ 取出协处理器p15的控制寄存器(c1)内容,存放在r0中 参考arm11内核手册:c1, Control Register        bic r0, r0, #0x00000007 @ 将r0的[2:0]设为0后存入r0        mcr p15,0,r0,c1,c0,0    @ 将r0的值传送到协处理器p15的控制寄存器(c1)中,完成mmu和cache配置        mov pc, lr              @ 返回调用处继续往下执行

未完,待续。。。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-6-23 01:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */