加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

关于三星S3C44B0X目标板的uClinux Bootloader

时间:2013-11-23  来源:123485.com  作者:9stone

         uClinux是为控制领域设计的嵌入式Linux操作系统,它沿袭了主流Linux的大部分特性,并进行了一定幅度的裁减。其设计主要针对没有内存管理单元(MMU)的微处理器,例如基于ARM7TDMI内核的S3C44B0X。

       嵌入式Linux系统通常由三部份组成:Bootloader、Kernel和File System。其中Bootloader是在系统启动之后、Kernel运行之前所执行的第一段代码,其任务是为调用Kernel准备必要的软硬件环境。由此可见,Bootloader是非常依赖于硬件和操作系统的。所谓依赖于硬件,是指Bootloader的实现与处理器体系架构和板级硬件资源密切相关;所谓依赖于操作系统,是指不同操作系统的内核对调用方式和运行环境有不同的要求。

       理论上,uClinux在引导时并非一定需要一个独立于Kernel Image的Bootloader Image。然而将Bootloader与Kernel分开设计能够使软件架构更加清晰,也有助于灵活地支持多种引导方式,实现必要的辅助功能。 uClinux Bootloader的主要任务可概括如下:

       ● 引导和初始化
       ● 加载uClinux Kernel
       ● 设置内核启动参数
       ● 调用uClinux Kernel
       ● 辅助功能:文件下载、Flash烧写、人机界面等

       对于常见架构的处理器,一般都能找到现成的Bootloader,但其结构往往较为复杂,且仍需要针对具体的目标板进行移植。当然,也可以选择自行开发 Bootloader。由于Bootloader Image在物理上独立于Kernel Image,因此不一定跟随Linux选用GNU作为开发工具。对于ARM处理器,完全可以使用ADS或RVDS等集成环境来开发Bootloader。

       1.引导和初始化

       1.1 硬件初始化阶段一
       S3C44B0X在上电或复位后,程序从位于地址0x0的Reset Exception Vector处开始执行,因此需要在这里放置Bootloader的第一条指令:b ResetHandler,跳转到标号ResetHandler处进行第一阶段的硬件初始化,主要内容为:关WDT,关中断,配置PLL和时钟,初始化 Memory Controller。这里比较重要的是配置PLL的输出频率,S3C44B0X最高能够支持66MHz;如果目标板上使用DRAM/SDRAM,应当据此计算刷新频率等相关参数。

       1.2 建立异常向量表
       ARM7TDMI 内核规定:包括Reset Exception Vector在内的异常向量表的基地址是0x0,所以存放Bootloader的Flash基地址也必须是0x0;而S3C44B0X处理器又不支持 Remap,这意味着一旦发生中断,程序就要跳转到Flash中的异常向量表(中断属于异常的一种)。uClinux会在RAM里建立自己的二级异常向量表(基地址缺省为0x0C000000);所以编写Bootloader时,0x0处的一级异常向量表只需简单地包含向二级异常向量表的跳转:
       b ResetHandler  ;Reset Handler  
       ldr pc,=0x0c000004 ;Undefined Instruction Handler  
       ldr pc,=0x0c000008 ;Software Interrupt Handler  
       ldr pc,=0x0c00000c ;Prefetch Abort Handler  
       ldr pc,=0x0c000010 ;Data Abort Handler  
       b .   ;Reserved  
       ldr pc,=0x0c000018 ;IRQ Handler  
       ldr pc,=0x0c00001c ;FIQ Handler

       如果在Bootloader运行过程中不必响应中断,那么上面的配置已能满足要求。如果某些Bootloader功能要求使用中断(例如用Timer Interrupt实现精确定时),那么Bootloader必须在同样的位置建立自己的二级异常向量表,以便同uClinux保持一致。这张表应存放在 Flash中,并由Bootloader复制到RAM地址0x0C000000处。

       1.3 初始化各种处理器模式
       ARM7TDMI内核支持7种处理器模式:User,FIQ,IRQ,Supervisor,Abort,System和Undefined。 Bootloader需要依次切换到每种模式,初始化该模式的程序状态寄存器(SPSR)和堆栈指针(SP)。S3C44B0X在上电或复位后处于 Supervisor模式;本步骤中应该在最后切换回Supervisor模式,即Bootloader后续部份仍将运行在Supervisor模式下。

       1.4 section重定位
       对于ADS或RVDS等开发工具,一个ARM程序通常由RO、RW和ZI三个section组成,其中RO是代码和常量,RW是已初始化的全局变量,ZI 是未初始化的全局变量(在GNU中对应的概念是TEXT、DATA和BSS)。RO代码既可以在Flash中运行,也可以在RAM中运行。考虑到 Bootloader可能需要烧写Flash,而烧写时处理器无法从Flash中读取指令,因此应将RO和RW复制到RAM中,并将ZI清零。RO复制完毕之后,程序就可以跳转到RAM中运行。若不考虑烧写Flash,则Bootloader不必复制RO,程序始终在Flash中运行。

       1.5 填写中断向量表
       中断向量表一般位于RAM地址的最高端,存放着各个ISR的入口地址。由于IRQ Exception为全部中断所共用,因此必须在IRQ Exception服务例程中根据中断状态寄存器来判断中断源并调用相应的ISR。各个ISR的入口地址需要在这一步里填写。

       另外,S3C44B0X的中断控制器支持Vectored和Non-Vectored两种中断处理模式,其中前者是Samsung自行开发的模式,并不被大多数ARM处理器所支持。考虑到代码的可移植性,上面只讨论了Non-Vectored Mode。

       1.6 硬件初始化阶段二
       遵循“必要”原则继续对硬件资源进行初始化,包括S3C44B0X内置的GPIO、Cache、中断控制器和UART等。Bootloader中暂未用到的设备可以留待使用之前再进行初始化。

       S3C44B0X内置有数据/指令合一的8KB Cache,且允许按照地址范围设置两个Non-Cacheable的区间。合理的配置是打开对RAM地址区间的Cache,关闭对其它地址区间的Cache,以避免可能存在的Cache一致性问题。

       1.7 建立人机界面
       引导过程的最后一步是在串行终端上建立人机交互界面。常见的做法是先等待固定的时间,若未接收到用户输入,则直接从Flash中加载或调用uClinux Kernel;若接收到用户输入,则显示菜单模式或命令行模式的交互界面,并等待进一步的命令。

       2. 加载uClinux Kernel
       Bootloader是否需要执行加载操作,取决于uClinux Kernel Image的类型。根据不同的配置方式,可以生成以下几种uClinux Kernel Image:

       2.1 非压缩,非XIP
       XIP(eXecute In Place)是指在存放代码的位置上就地运行程序;而非XIP就是指在运行之前需要对代码进行重定位。该类型的uClinux Kernel Image以非压缩格式存放在Flash中,需由Bootloader加载到RAM然后调用。该类型在开发调试阶段最为常用。

       2.2 非压缩,XIP
       该类型的uClinux Kernel Image以非压缩格式存放在Flash中,不需加载,由Bootloader直接调用。复制Data段和清零BSS段的工作由Kernel自行完成。该类型常用于RAM空间非常有限的系统中,缺点是程序在Flash中运行的速度稍慢。

       2.3 RAM自解压
       压缩格式的uClinux Kernel Image由开头的一段自解压代码和其后的压缩数据组成。由于是以压缩格式存放,因此Kernel只能以非XIP方式运行。RAM自解压的uClinux Kernel Image存放在Flash中,由Bootloader加载到RAM中的临时空间,然后调用自解压代码。Kernel被解压到最终的目标空间然后运行;压缩镜像所占据的临时空间在随后由uClinux回收利用。该类型占用Flash较少,且运行速度较快,在最终产品中更为常见。

       2.4 ROM自解压
       解压缩代码也能够以XIP的方式在Flash中运行。ROM自解压的uClinux Kernel Image存放在Flash中,不需加载,由Bootloader直接调用其自解压代码,将uClinux Kernel解压到最终的目标空间并运行之。与RAM自解压相比,ROM自解压并不真正节省RAM,而且解压缩的速度较慢,因此实用价值不大。

       3.设置内核启动参数
       Linux 2.4版本以后的内核都期望以标记列表(tagged list)的形式来接收启动参数。每个标记存放在一个tag结构中,每个tag结构由标识被传递参数的tag_header结构以及随后的参数值组成。通常由Bootloader设置的启动参数有:ATAG_MEM、ATAG_CMDLINE、ATAG_SERIAL等。启动参数的标记列表以 ATAG_CORE开始,以ATAG_NONE结束,代码示例如下。其中0x0C000100是内核启动参数在RAM中的基地址,Bootloader应当将要传递的启动参数复制到该处RAM中;指针params的类型是struct tag。宏tag_next()以指向当前标记的指针为参数,计算下一个标记的起始地址。
       params = (struct tag *)0x0C000100;
       params->hdr.tag = ATAG_CORE;
       params->hdr.size = tag_size(tag_core);
       params->u.core.flags = 0;
       params->u.core.pagesize = 0;
       params->u.core.rootdev = 0;
       params = tag_next(params);
     
       params->hdr.tag = ATAG_NONE;
       params->hdr.size = 0;

       对应地,在Linux内核源码arch/armnommu/mach-s3c44b0/arch.c中设置内核启动参数在RAM中的基地址:
       MACHINE_START (S3C44B0, "44B0")
     
       BOOT_PARAMS (0x0C000100)
     
       MACHINE_END

       4.调用uClinux Kernel
       Bootloader调用Kernel的方法是直接跳转到其第一条指令处。对于ARM处理器,在跳转时应当满足下列条件:r0=0;r1=Machine ID;禁止IRQ和FIQ;处理器运行在Supervisor模式;关闭MMU;关闭Data Cache。

       对于S3C44B0X,它没有MMU,其Cache是指令与数据合一的,因此只能全部关闭。各种ARM处理器的Machine ID均由www.arm.linux.org.uk分配;S3C44B0X的Machine ID是178。据此,用C代码实现的Kernel调用示例如下,其中r0和r1的值通过参数传递:
       void (*CallKernel)(int zero, int mach) = (void (*)(int, int))KERNEL_ADDR;
       CallKernel(0, 178);

       5. 辅助功能
       完整的Bootloader还应该允许更新Flash中存放的uClinux Kernel Image以及Bootloader自身。为此,必要的辅助功能包括:从主机下载文件到目标板的RAM;用RAM中的数据烧写Flash;以及实现上述操作所需的人机交互接口,这里就不赘述了。


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门