毕业论文论文范文课程设计实践报告法律论文英语论文教学论文医学论文农学论文艺术论文行政论文管理论文计算机安全
您现在的位置: 毕业论文 >> 论文 >> 正文

嵌入式系统ARM的通用bootloader的设计与实现 第8页

更新时间:2010-7-2:  来源:毕业论文
嵌入式系统ARM本文来自辣文论文网的通用bootloader的设计与实现
以上涉及的是相关存储方面通用的处理,接着就要开始具体的硬件初始化的工作了,与
具体的CPU以及具体的存储芯片大小有关。
1. 屏蔽所有的中断:为中断提供服务通常是操作系统设备驱动程序的责任,因此在bootloader的执行全过程中可以不必相应任何中断,中断屏蔽是通过写CPU提供的中断屏蔽寄存器来完成的。

ldr r1, =(INT_BASE | INT_ICMR)   /* 通过中断控制器基地址与相关偏移量获得中断屏蔽寄存器的地址*/
    ldr r2, =0x0          
str r2, [r1]     

2. 设置CPU的速度与时钟频率:系统复位后对于CPU的速度与时钟频率都有一个初始的默认值,可以直接使用该值,到内核启动初始化的时候再设置;也可以在此处直接设置。

    ldr r1, =CLK_BASE   
    ldr r2毕业论文http://www.Lwfree.cn_CCCR] 

3. SDRAM 的初始化以及使能,这个设置与具体的RAM大小有关,包括正确地设置系统的内存控制器以及各内存库控制寄存器。具体代码稍长,在这里相关代码略去。

    相关基本硬件初始化之后,开始设置模式。
1. 为ARM的各个操作模式设置称栈指针:在前面的伪代码中已经为各个操作模式分配相应的栈区,而且ARM各个模式下都有自己通用的栈顶指针SP,现在要做的是在不同模式下将该模式下的SP指向栈顶。每个模式的处理都类似,都是通过设置状态寄存器CPSR(可以参看前面章节的介绍)来完成,并且每个模式都要完成。以IRQ模式为例:

mrs r0, cpsr                         /* 保存CPSR的值 */
    bic r0, r0, #0x1f                     /* 清楚所有的模式位*/
    orr r0, r0, #0x12                    /* 将系统设置为IRQ模式*/
    msr CPSR_c, r0                    /*将改变后的状态值发会给CPSR*/
ldr sp, =(IrqStack + IrqStackSz - 4)    /* 设置SP*/

2. 将系统模式设置成监管模式(SVC),并设置SP。

    mrs r0, cpsr              
    bic r0, r0, #0x1f          
    orr r0, r0, #0x13          
    msr CPSR_c, r0             
ldr sp, =(MonStack + MonStackSz - 4)

到此时,用汇编编写的硬件基本初始化代码完成,对于阶段1来说,剩下的工作就是将镜像2拷贝到SDRAM的指定处,这个工作我们通过一小段C代码来完成,文件名为cstart.c,完成拷贝功能的函数设为cstart。则在汇编末尾可以通过跳转指令进入阶段1的这一小段C代码:
bl cstart
在编译时,本课题将镜像2存放在一个二进制数组umon[ ]之中,具体的编译实现在后面相关篇幅中会有介绍。这样的话,将镜像2拷贝到SDRAM中的实现就比较简单,通过以下代码代码就可以实现:

memcpy((char *)UMON_RAMBASE,(char *)umon,(int)sizeof(umon));

其中,毕业论文http://www.Lwfree.cn

entry = (void(*)())UMON_RAMBASE;
entry();
4.3.2  阶段2的代码实现
本文在阶段2的处理,本文来自辣文论文网更多的是对bootloader的功能性的扩展,具体集中在对本文的硬件系统的支持,并在此基础上实现bootloader的两种操作模式。

4.3.2.1  基本功能的实现
 基本功能的实现包括加载内核镜像并转让控制权给内核,具体的实现步骤包括:
(1) 前面的存储布局中已经提过,本课题的内核镜像存放在地址0x000c0000处。根据linux内核压缩镜像的构成,离镜像起始的0x24处存放的是一个32位数来标识其身份,因此首先判断(0x000c0000+0x24)处的一个32位数是否等于0x016F2818(标识符)。
(2) 若检查一致,则将位于FLASH中的kernel镜像直接拷入SDRAM中,地址设为0xa0300000,如下:
 memcpy(ram_start, (uchar *)KERNEL_FLASH_START, KERNEL_MAX_SIZE)
其中,KERNEL_MAX_SIZE设为1M,ram_start为0xa0300000,KERNEL_FLASH_START为0x000c0000。
(3) 设置启动参数,现今的Linux内核都以链表(tagged list)的形式来传递参数,启动参数以标记ATAG_CORE开始,ATAG_NONE结束。任何bootloader想要传递给kernel的参数都可以添加在在这两个表头与表尾之间。相关的代码如下:

struct tag *params = (struct tag *)BOOT_PARAMS;

    params->hdr.size = tag_size(tag_core);
    params->hdr.tag = ATAG_CORE;
    params->u.core.flags = 0;
    params->u.core.pagesize = 0;
    params->u.core.rootdev = 0;
    params = tag_next(params);

   //如果有参数传递,在此添加

    params->hdr.size = 0;
    params->hdr.tag = ATAG_NONE;

其中,相关数据结构如下:
struct tag_header {
   ulong size;
   ulong tag;
};


struct tag {
   毕业论文http://www.Lwfree.cnmem;
    struct tag_videotext videotext;
    struct tag_ramdisk ramdisk;
    struct tag_initrd initrd;
    struct tag_serialnr serialnr;
    struct tag_revision revision;
    struct tag_videolfb videolfb;
    struct tag_cmdline cmdline;
struct tag_acorn acorn;
    struct tag_memclk memclk;
    } u;
};
(4) 直接跳转至RAM中的内核镜像的第一条指令执行:

 linux_kernel = (void (*)(int, int, struct tag *))ram_start;
 linux_kernel(LINUX_ARG0, LINUX_ARG1, tagparams);

 其中,三个参数的函数如下:
 LINUX_ARG0固定为0;
 LINUX_ARG1为表征系统机器类型,要与内核中的一致;
 Tagparams为系统传给内核的参数列表的首物理地址。
 以汇编角度看,最终这三个参数会对应系统寄存器R0,R1和R2。

4.3.2.2  扩展功能的实现本文来自辣文论文网
本文对bootloader的设计决定了实现的bootloader不仅仅起到加载内核镜像这一基本功能,而是把bootloader看作是一个虚拟的小系统,让其对硬件板级系统有更多的支持以为系统开发者提供方便。

(1) 串口的支持
本文将串口的支持放在扩展功能的范畴内,事实上现在一般都已经存在一种共识:bootloader应该串口功能的支持,能够从串口终端正确地收到打印信息。
 串口打印信息支持
向串口终端打印信息是一个非常重要而且有效地调试手段。
基于以上的原因,本课题没有通过外界的触发,而是直接在bootloader的阶段2代码中,初始化串口,串口初始化时将其配置成8位数据位、1停止位、无奇偶校验,波特率为115200。此串口使用PXA255内置的FF UART(全功能串口)。
另外在串口的支持代码中,增加相关接收与发送数据应用接口getchar( void )以及putchar(char c)。当要接收数据时,可以通过毕业论文http://www.Lwfree.cn,以达到打印信息的功能。

(2) 下载模式的实现
有了串口的支持,就可以实现下载模式的实现。在基本功能实现的第四个步骤(也就是启动内核)之前,首先使得代码流程延迟一段时间,接着调用串口的接收函数看是否有输入(开发者对应的是键盘输入),如果有数据,则bootloader不加载运行内核镜像,转入等待命令状态;如果没有,则加载运行内核镜像。
   udelay(50000);          /* 等待用户输入*/
   if(getachar())
      return;              /* 返回之后进入命令行等待状态 */
   else{                  /* 否则运行内核*/
     linux_kernel = (void (*)(int, int, struct tag *))ram_start;     
linux_kernel(LINUX_ARG0, LINUX_ARG1, tagparams);}
那么在等待命令状态后,bootloader又如何进行工作呢?
在本文中,定义了一个数据结构monCommand(如下),它主要用来描述一个命令,结构体中,name项指向具体的命令,第二项指向该命令对应的执行函数,最后一项则指向一些帮助文档说明,例如命令的用法等等。

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] 下一页

嵌入式系统ARM的通用bootloader的设计与实现 第8页下载如图片无法显示或论文不完整,请联系qq752018766
设为首页 | 联系站长 | 友情链接 | 网站地图 |

copyright©751com.cn 辣文论文网 严禁转载
如果本毕业论文网损害了您的利益或者侵犯了您的权利,请及时联系,我们一定会及时改正。