0 引言
在嵌入式系统中,当cpu启动起来后,首先会在预先设置的地址上执行引导程序,用来加载和启动系统。通过引导程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。引导程序与硬件紧密结合,不同处理芯片体系,不同主板设计,对应不同的引导程序。本系统采用ppcboot作为引导程序。ppcboot的功能强大,而且代码公开。一般来说,它可以分为两部分:与硬件相关的代码,与硬件无关的代码。在设计时,可以先从其官方网站下载完整的代码,然后根据自己系统的特点,对与硬件相关代码部分进行修改,最后进行编译,烧入 Flash。接下来,将对ppcboot的工作流程和具体的修改过程进行讨论
1 ppcboot工作流程
作为ppc体系的引导程序ppcboot上电后,将完成初始化硬件设备,建立内存映射, 启动系统内核三个任务。
初始化硬件设备:
系统上电复位后,CPU首先从Flash 的0x100处执行第一条指令。该指令跳转到具体地址后,开始执行部分初始化和真正初始化前的准备工作:屏蔽所有的中断,设置CPU的速度和时钟频率,禁止cache、禁止地址转换等等。
在这个阶段中,执行空间始终在Flash,功能通常都用汇编语言来实现。之后,系统开始建立内存映射。
建立内存映射:
(1)设置系统的内存控制器的功能寄存器以及各内存库控制寄存器等,使CPU能够正常运行起来并执行C语言程序,并且为下一步加载引导程序,准备RAM空间。
(2)引导程序重新定位执行空间,ppcboot代码从flash拷贝到内存,开始在内存中执行。
(3)再次初始化部分硬件设备,并检测系统内存映射,知道 CPU 预留的全部 RAM 地址空间中的哪些被真正映射到 RAM 地址单元,哪些是处于无状态的。经过这个阶段后,系统建立了内存映射图(见图1),并开始在内存里执行程序,能够执行C语言程序。之后,系统进入启动操作系统内核阶段。
启动操作系统内核
(1)把内核映像和根文件系统映像从Flash上读到RAM中。
(2) 为内核设置启动参数。以标记列表的形式来传递。
(3)解压内核,初始化串口,使解压后内核获得CPU的控制权,结束ppcboot的任务。
2 基于MPC823e的ppcboot的具体编写
在上面提过,由于ppcboot的代码硬件无关部分是通用的,不需要修改。而硬件相关的代码部分,与硬件紧密相关,所以需要针对自己具体的硬件进行修改,主要是cpu部分与主板部分的代码。
2.1 ppcboot中cpu部分的开发
ppcboot的一个任务是初始化CPU内部寄存器,包括:定义中断向量表、数据和指令cache的设置、内存管理单元MMU的设置、系统接口单元SIU设置、内存控制器和UPM表的设置、时钟和复位寄存器设置、外部总线接口设置、与编译器相关的堆栈设置等。
步骤1: 禁止 中断 -> 禁止cache -> 禁止MMU
启动过程中无法处理中断,所以必须关闭中断;另外,因内存管理、cache尚未设置,所以应先全部禁止,待设置完毕再打开。
步骤2: 初始化内存 init_memc
MPC823e提供了强大的内存接口控制单元,包括一个通用内存接口单元GPCM和两个用户可编程内存接口单元UPMA/UPMB。还提供了8个片选信号线与8片独立的内存接口。
编写ppcboot时,需要研究SDRAM芯片的时序图,构造出MPC823e特有的64个时序字,填入MPC823e内部相应的寄存器中。以后,每当发出内存访问的指令时,硬件就能够根据设置好的64个时序字,产生正确的读写时序。而且要针对具体的设计,编写片选内存的寄存器BRx和ORx来设置其属性,包括定义内存片基地址、地址掩码、读写属性、总线宽度(8位、16位、32位)、控制单元(使用GPCM或UPM)等。如本系统中,使用了CS0 控制16位的Flash存储器、CS1控制32位的sdram,对CS1进行设置时应设为基地址0x00000000,32位可读写,使用UPMA。
步骤3:初始化系统接口单元init_SIU -> 初始化调试寄存器der -> 初始化时钟 init_clk
系统接口单元主要包含对MPC823e复用引脚的设置寄存器、调试寄存器(该寄存器可用来设置CPU在各种不同的意外情况下是否进入调试状态)。
初始化时钟主要是对CPU主频的设置。MPC823e有一个倍频率达数千倍的内部倍频器,本系统中,采用了5MHz的晶振,经过10倍频后稳定运行在50MHz频率上。[page]
步骤4:初始化cache
MPC823e采用Harvard结构的cache,它的指令cahce和数据cache是独立的;采用最近最少使用法(LRU Least Recently Used)替代算法。在具体编写时,要注意只有在对MMU编程后cache才能工作,应此要采用以下的步骤进行初始化(如图2所示):
步骤5:初始化内存管理单元 init_MMU
MPC823e的MMU的特点主要有:支持多种页面大小、全相联映像规则TLB(Translation Look-aside Buffer)、指令和数据TLB可独立控制等。在编写时,因为启动程序中,不需要虚拟内存到物理内存的地址变换,所以只需对内存属性做一些设置,如回写策略、内存读写保护等
步骤6:设置中断向量表 b vector_reloc
中断向量表用于嵌入式Linux启动代码,在启动过程中,最主要的就是设置复位中断。可以在LILO(Linux bootloader)中填写0x100复位中断向量。当发生复位时,MPC823e自动读取复位配置字,通过相应的配置,MPC823e会读取复位中断向量0x100处的指令,进行正确引导过程。
步骤7:init_stack初始化堆栈 -> 初始化编译相关寄存器
此外,在运行C语言编译的程序前必须先定义这些与编译相关的寄存器,如堆栈指针寄存器、代码段、数据段指针寄存器等。Mpc823e针对不同的编译器使用不一样寄存器的规则,如diab编译器和gcc编译器,在编写时,需要仔细查阅编译器手册。
2.2 ppcboot中主板部分的开发
ppcboot支持数十种主板,可以在其中寻找与自己设计的主板相近的主板,并以其的ppcboot的主板代码部分为模板,进行必要的修改来移植。本系统采用的主板HD823e与其中的RPXlite板十分相近,在其基础上进行调整。接下来,将讨论如何进行修改。
(1)在Makefile文件中,添加硬件基本配置信息,如cpu型号,主板类型,cpu体系
如本系统添加:
HD823e_config: unconfig
echo "ARCH = ppc" > config.mk ;\\
echo "BOARD = HD823e" >>config.mk ; \\
echo "CPU = mpc8xx" >>config.mk ; \\
echo "#include
(2) 修改开发板的配置文件.包括 CPU,调试串口,内存映射,Flash与SDRAM等多部分配置参数进行修改。以下给出部分重要的参数。
CPU部分配置:
#define CONFIG_MPC823 1 /* CPU类型 */
#define CFG_RTCSC (RTCSC_SEC | RTCSC_RTE) /*配置cpu内部时钟*/
#define CFG_PLPRCR ( (0x00900000) | PLPRCR_TEXPS )
#define CONFIG_8xx_GCLK_FREQ 50000000 /*设置CPU运行频率*/
调试串口的部分配置:
#define CONFIG_BAUDRATE 9600 /* 串口波特率 = 9600bps */
#define CONFIG_8xx_CONS_SMC1 1 /* 串口使用 SMC1口 */
内存映射的部分配置:
#define CFG_IMMR 0xFF000000 /* Internel Memory Mapped Register */
#define CFG_LOAD_ADDR 0x100000 /* ppcboot缺省的引导地址 */
由于篇幅的关系,其他部分参数不介绍了,可以根据CPU的使用手册和ppcboot手册进行配置,注意的是,这些参数都需要严格的确定,不能出错,否则,无法正确引导系统。
(3) 修改 include /commproc.h
该文件包含与通信接口相关的一些参数,由于本系统需要网络来下载内核,需要对网络接口引脚进行相关的定义。
#ifdef CONFIG_HD823e
#define PROFF_ENET PROFF_SCC2 #define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1 #define PA_ENET_RXD 0x0004
#define PA_ENET_TXD 0x0008 #define PA_ENET_TCLK 0x0800
#define PA_ENET_RCLK 0x0200 #define PB_ENET_TENA 0x2000
#define PC_ENET_CLSN 0x0040 #define PC_ENET_RENA 0x0080
#define SICR_ENET_MASK 0xff00 #define SICR_ENET_CLKRT 0x2f00
#endif
2.3 编译ppcboot
修改完成后,可以使用下列命令进行编译,一般说来,都可以编译成功,得到适合自己系统的ppcboot。本系统,在原有RPXLite的模板基础上,通过上修改,编译成功,顺利的引导了系统。
make clean
make HD823e_config
make all
3 结束语
本文根据所选用的嵌入式系统的特点,概述了ppcboot的启动流程,对Mpc823e下的ppcboot体系进行了介绍,并针对自己的开发板,详细的说明了如何开发适应自己系统的ppcboot。代码已通过了系统的调试,成功的引导了linux内核,达到设计的目的。
本文作者的创新点是:在分析嵌入式系统在Linux下的引导程序工作流程和ppcboot源代码基础上,开发了特定的、适合本文系统硬件的引导程序。参考ppcboot中支持RPLite主板的相关代码,给出了将ppcboot移植到本文所使用的HD823e主板的修改方案。
参考文献
[1]周长春,王志言.PowerPC概念、体系结构与设计[M].北京:电子工业出版社,1995.1-158.
[2]毛德操,胡希明. Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.663-737.
[3]王学龙. 嵌入式Linux系统设计与应用[M].北京:清华大学出版社,2001.35-69.
[4]万永波,张根宝.基于ARM的嵌入式系统Bootloader启动流程分析 微计算机信息 2005.11-2
[5]motorola Inc.MPC823e User’S Manual[EB/OL].
上一篇:嵌入式Web服务器技术及其在电力系统中的应用综述
下一篇:嵌入式系统的低功耗软件方案
推荐阅读最新更新时间:2024-03-16 13:00
设计资源 培训 开发板 精华推荐
- 宁德时代巧克力换电生态大会将举行,什么是“巧克力换电”?1.5分钟换电能实现吗?
- 新型生物材料与高端医疗器械广东研究院、远诺技术转移中心加入面向初创企业的 MathWorks
- S5PV210 Linux字符驱动之PWM蜂鸣器驱动
- 尼得科机床新增可实现高效加工的高速主轴产品线
- Gartner发布2025年影响基础设施和运营的重要趋势
- 智谱清言英特尔酷睿Ultra专享版发布,离线模型玩转AIPC
- Bourns推出全新高效能、超紧凑型气体放电管 (GDT) 浪涌保护解决方案
- S5PV210之UBOOT-2011.06启动过程解析
- 六个理由告诉您为什么应该将模拟无线麦克风更换为数字无线麦克风
- S5PV210启动过程分析