《基于at91sam9260的嵌入式系统的Bootloader启动流程分析.pdf》由会员分享,可在线阅读,更多相关《基于at91sam9260的嵌入式系统的Bootloader启动流程分析.pdf(7页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、http:/-1-基于基于at91sam9260的嵌入式系统的的嵌入式系统的Bootloader启动流程分析启动流程分析 程前,陈永泰 武汉理工大学信息工程学院,武汉(430070)E-mail: 摘摘 要要:Bootloader 是上电后,应用程序或操作系统运行前对处理器及内部功能模块的初始化,以及引导内核过程的一段启动代码。本文根据 at91sam9260 的引导策略,采用了 at91bootsrap加 u-boot 组成了本系统的 Bootloader。文中结合代码分析了基于 at91sam9260 的嵌入式系统的 Bootloader 启动流程中的各个阶段及最终引导操作系统内核的过程.
2、对进一步的系统功能设计有很大的帮助。关键字关键字:at91sam9260;嵌入式;Bootloader 1.引言引言 对于 PC 机,其开机后的初始化处理器配置、硬件初始化等操作是由 BIOS(Basic Input/Output System 完成的,但对于嵌入式系统来说,出于经济性、价格方面的考虑一般不配置 BIOS,因此我们必须自行编写完成这些工作的程序,这就是所需要的开机程序。而在嵌入式系统中2,通常并没有像 BIOS 那样的固件程序,启动时用于完成初始化操作的这段代码被称为 Bootloader 程序1,因此整个系统的加载启动任务就完全由 Bootloader 来完成。简单地说,通过
3、这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境设定在一个合适的状态,以便为最终调用操作系统内核、运行用户应用程序准备好正确的环境。Booloader 依赖于实际的硬件和应用环境,因此要为嵌入式系统建立一个通用、标准的 Bootloader 是非常困难的。Bootloader 也依赖于具体的嵌入式板级设备的配置,这也就是说,对于两块不同的嵌入式主板而言,即使它们是基于同一 CPU 而构建,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上通常都需要修改Bootloader的源程序。嵌入式linux系统中常用的Bootloader有armboot、r
4、edboot、blob、u-boot等,其中U-Boot是当前比较流行,功能比较强大,是目前用来开发嵌入式系统引导代码使用最为广泛的Bootloader,可以支持多种体系结构,但相对也比较复杂。本系统采用了U-Boot作为系统的启动程序。2.U-Boot简介简介 U-Boot,全称 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。从 FADSROM、8xxROM、PPCBOOT 逐步发展演化而来。其源码目录、编译形式与 Linux 内核很相似,事实上,不少 U-Boot 源码就是相应的 Linux 内核源程序的简化,尤其是一些设备的驱动程序,这从 U-Boot
5、源码的注释中能体现这一点。U-Boot 支持很多嵌入式操作系统的引导,且支持多种嵌入式处理器。2.1 U-Boot源代码目录结构源代码目录结构 U-Boot 为目录结构,多个子目录分别存放和管理不同的源程序,按其规则可分为 3 类:1.与处理器体系结构或开发板硬件直接相关 2.通用函数或驱动程序 http:/-2-3.U-Boot 应用程序,工具和文档 2.2 U-Boot 的编译的编译 U-Boot的源码是通过GCC和Makefile组织编译的。顶层目录下的Makefile首先可以设置开发板的定义,然后递归调用各级子目录下的Makefile,最后把编译过的程序链接成U-Boot映像。3.at
6、91sam9260的引导策略的引导策略 本系统以at91sam9260芯片为核心,它有两种引导方式,片内引导和片外引导。当系统上电后,会自动检测引脚BMS的电平来决定系统的引导方式。如果BMS为高电平,系统从片内rom启动,内部ROM上电后被映射到了0 x0和0 x100000处,在这两个地址处都可以访问到ROM。图1 Sam9260内部存储映射 片内rom里固化一个romboot程序,它完成以下功能:1.FIQ初始化 2.ARM SCV32模式下的堆栈设置 3.外部时钟检测 4.C变量的初始化 5.如没有外部时钟检测,则进行主时钟频率检测 6.PLL设置 7.初始化DEBUG口(115200
7、,8,n,1)8.禁止看门狗 完成以上步骤后,AT91sam9260按照dataflash、nandflash的顺序依次来找合法的BOOT程序。所谓合法的指的是在这些存储设备的开始地址处连续的存放的32个字节,也就是8条指令必须是跳转指令或者装载PC的指令,其实这样规定就是把这8条指令当作是异常向量表来处理。必须注意的是第6条指令要包含将要装载的映像的大小。一旦合法的映像找到之后,则BOOT程序会把找到的映像搬到SRAM中去,所以映像的大小是非常有限的,不能超过16K的大小。当BOOT程序完成了把合法的映像搬到SRAM的任务以后,接下来就进行存储器的REMAP,经过REMAP之后,SRAM从映
8、设前的0X200000地址处被映设到了0X0地址并且程序从0X0处开始执行。而ROM这时只能在0X100000这个地址处看到了。上电后,我们一般把http:/-3-存储在flash中的bootstrap映像搬移到sram中,bootstrap完成一些静态初始化工作,如PMCS,PIOs,再把u-boot从flash中搬移到sdram中运行。如果BOOT程序在以上所列的几种存储设备中未找到合法的映像,则自动初始化DEBUG,USART口和USB DEVICE口以准备从外部载入映像。对DEBUG口的初始化包括设置参数(115200,8,N,1)以及运行XMODEM协议。对USB DEVICE进行初
9、始化以及运行DFU协议。Atmel公司提供了samba-2.6下载工具。图2 At91sam9260的启动规则 而BMS为低电平的时候,则at91sam9260会从片外的FLASH启动,这时片外的FLASH的起始地址就是0X0了,并且要求已经在此地址烧些了启动映象了,由于片外FLASH可以设计的大,所以这里编写的Bootloader可以一步到位,也就是说不用像片内启动可能需要BOOT好几级了。通常选择在flash的首地址处放的是boot.bin,由其将u-boot.bin.gz解压到高端RAM中,再运行真正的u-boot.bin,也就是实际的启动映象。本系统选择的是片内启动的方式。且准确的说本
10、系统由U-Boot加上at91bootstrap组成了系统的bootloader。4.U-Boot启动流程分析启动流程分析 U-boot的运行流程符合前面提出的典型BootLoader结构框架,也可分为stage1和stage2两个部分,依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1,且用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。http:/-4-4.1 阶段一介绍阶段一介绍 U-boot的stage1代码通常放在Start.S中,它用汇编语言写成,是U-Boot的入口程序3,主要代码如下:1.定义入口 一个
11、可执行的Image必须有一个入口点.并且只有一个全局入口,通常这个入口放在ROM(Flash)的0 x0地址,因此,必须通知编译器以使其知道这个入口,该工作可以通过修改连接器脚本来完成。1.Board/at91sam9260/u-boot.Lds:ENTRY(_start)=cpu/arm926ejs/start.S:.globl _start 2.U-boot代码区(TEXT_BASE=0 x23f00000)定义在Board/at91sam9260/config.mk 2.设置异常向量表 异常向量表的开始地址是由ARM架构决定的,必须位于0 x0处。_start:/地址0 x0 b res
12、et /复位向量 ldr pc,_undefined_instruction ldr pc,_software_interrupt ldr pc,_prefetch_abort ldr pc,_data_abort ldr pc,_not_used ldr pc,_irq /中断向量 ldr pc,_fiq /中断向量 reset:/*复位启动子程序,设置cpu为superviser模式*/mrs r0,cpsr /*读cpsr寄存器状态*/bic r0,r0,#0 x1f /*位清除模式位*/orr r0,r0,#0 xd3 /*设置M=10011,svc32模式*/msr cpsr,r0
13、/*写回cpsr寄存器*/3.设置CP15 设置cp15,失效指令(I)cache和数据(D)cache后,禁止MMU和cache cpu_init_crit:/*清空指令/数据caches*/mov r0,#0 mcr p15,0,r0,c7,c7,0 /*失效I/Dcache*/mcr p15,0,r0,c8,c7,0 /*失效TLB*/*flush cache 使所有IDC无效,这样cpu直接到原存储地址读数据和指令,而不是从cache中得到。初始化之前,这样可以保证初始化过程正确连续*/4.配置内存区控制寄存器 mov ip,lr bl lowlevel_init mov lr,ip
14、mov pc,lr 5.将flash程序复制到sdram relocate:/*搬移u-boot到sdram*/adr r0,_start /*r0代码的当前位置*/ldr r1,_TEXT_BASE /*得到的目标地址*/http:/-5-cmp r0,r1 /*两者相等表示从sdram中运行,则进行堆栈设置*/beq stack_setup ldr r2,_armboot_start /*代码起始地址*/ldr r3,_bss_start /*u-boot代码尾地址*/sub r2,r3,r2 /*r2为代码大小 */add r2,r0,r2 copy_loop:ldmia r0!,r3-
15、r10 /*从起始地址开始 */stmia r1!,r3-r10 /*复制到目标地址*/cmp r0,r2 /*直到代码全部复制完成 */ble copy_loop 6.初始化堆栈和清零bss段 stack_setup:ldr r0,_TEXT_BASE /*_TEXT_BASE为u-boot代码搬移到sdram中的起始地址*/sub r0,r0,#CFG_MALLOC_LEN /*动态储存区 */sub r0,r0,#CFG_GBL_DATA_SIZE /*板子的全局信息*/clear_bss:/*未赋初值的全局变量存储在bss段中*/ldr r0,_bss_start /*bss段开始*/
16、ldr r1,_bss_end /*结束 */mov r2,#0 x0 /*清零*/clbss_l:str r2,r0 /*清零循环*/add r0,r0,#4 cmp r0,r1 ble clbss_l 7.跳转到c语言代码函数处执行 ldr pc,_start_armboot _start_armboot:.word start_armboot 当程序在Flash中运行时,执行程序跳转时必须要使用相对跳转指令,而不能使用绝对地址的跳转(即直接对PC操作)。如果使用绝对地址,那么,程序的取指是相对于当前PC位置向前或者向后的32MB空间内,而不会跳入SDRAM中。4.2 阶段二的阶段二的c语
17、言代码部分语言代码部分 进入到C语言的入口函数start_armboot(),此函数是整个启动代码中C语言的主函数,也是整个U-boot的主函数,在lib_arm/board.c中定义,主要完成以下工作:4.2.1 初始化本阶段用到的硬件设备初始化本阶段用到的硬件设备 cpu_init()在cpu.c中定义,如果定义了IRQ,FIQ中断,设置相应的堆栈区。board_init()板级初始化,打开系统控制器中断,配置板子ID信息和参数入口地址。interrupt_init()这里没有执行中断,只是开启了PITC的计数器。env_init()函数初始化环境变量,此函数在common/env_dat
18、aflash.c中。先取出dataflash中的crc校验,然后把环境变量取出来进行新的crc校验,两次比较,看环境变量是否可用。init_baudrate()得到环境变量中的波特率,否则用缺省配置。http:/-6-serial_init()设置串口的初始化,以便使主机和目标机及其之间用串口连接,这里初始化串口的波特率为:115200;数据位:8;停止位:1;无校验,停止位为1。console_init_f()设置控制台,如果为静态模式,则设置全局数据标志位。display_banner()显示U-boot启动标记,如版本信息,代码段地址,堆栈地址等。dram_init()和display_
19、dram_config()这两个函数的作用是配置sdram的起始地址及大小并把其显示出来。flash_init()flash.c初始化flash,提供flash的bank分布情况,是否擦除,是否上锁等信息。mem_malloc_init()初始化系统内存分配函数,供后面的代码使用malloc等函数(U-boot没有使用其他现成的库,所有函数均实现在文件中)。AT91F_DataflashInit()本系统用dataflash来储存bootstrap和u-boot,先对其spi口进行初始化,然后探测dataflash的状态寄存器,得到其型号,并由此来确定页数,页大小等信息。env_relocat
20、e()在env_common.c中定义,为环境变量在内存中随机分配一块空间,用malloc函数。执行将环境变量搬移到内存。eth_initialize()由于at91sam9260自带有EMAC控制器,所以外接一个phy芯片dm9161a就组成网卡了,初始化其i/o口,查看连接状态。另外,如果目标系统拥有显示设备,初始化该设备;或者是nandflash初始化等等。4.2.2 进入命令循环进入命令循环main_loop()首先检查环境变量中有没有提供bootdelay的值,有的话把值读出来。这个环境变量定义了进入u-boot的等待时间。如果此时间内没有按键,从串口查询无输入,则执行设置的缺省命令
21、(本系统执行的缺省命令是bootm命令,启动操作系统内核)。若按键则进入命令循环,显示命令行模式的交互界面,接受用户从串口的输入的命令。在循环中,每从串行口读入一个命令行,就与U-Boot所提供的命令对比,发现相符就以命令行中剩下的部分为参数调用相应的函数。4.2.3 引导引导linux内核内核 U-Boot的命令函数名都是do_commandname()的形式,所以Bootm命令是由do_bootm()函数(common/cmd_bootm.c)执行的,其作用是从内存中引导应用程序或内核映像4,这个镜像是经过U-boot的工具mkimage打包之后的镜像,mkimage工具在tools/目录
22、下,它可以用来制作不压缩或者压缩的多种可启动映像文件,mkimage在制作映像文件的时候,是在原来的可执行映像文件的前面加上一个64字节的特殊头,这个头在include/image.h中定义。do_bootm()函数所做工作就是读出这个头,根据头中的信息做一些处理:检查CRC校验和;判断CPU的体系结构;判断header中的压缩标志,如果是压缩的,要先解压;判断映像类型;判断操作系统类型,进入专门的处理函数。本系统用的Linux操作系统,所以转向执行do_bootm_linux()(lib_arm/armlinux.c中定义)。在进入内核映像之前还要做一些准备工作,首先是设置好Linux内核的
23、启动参数。启动参数为内核提供内存的起始地址、大小、引导命令行、硬件的版本等等信息。在跳转到内核前,要满足下列条件:a)CPU寄存器的设置:R00;R1机器类型ID,本系统的机器类型ID1099。R2启动参数标记列表在RAM中的起始基地址;b)CPU模式:必须禁止中断(IRQs和FIQs);CPU必须工作在SVC模式;http:/-7-c)Cache和MMU的设置:MMU 必须关闭;指令Cache可以打开也可以关闭;数据Cache必须关闭。最后执行一条语句来引导操作系统内核:theKernel(0,bd-bi_arch_number,bd-bi_boot_params);这里所谓的“引导”,实际
24、上只是把前面已装入RAM的Linux内核映像当作一个函数来调用。这个映像的起点是hdr-ih_ep,所以先使一个函数指针theKernel指向这个起点,然后就通过theKernel把内核的映像作为函数调用。TheKernel()函数调用永远都不会返回,至此,操作系统已经成功启动了。5.结论结论 本文讨论了嵌入式系统的Bootloader的概念、Bootloader的主要功能,并对Bootloader的启动过程进行了详细的分析,为以后的具体实践打下理论基础。进一步介绍了嵌入式系统中的一个源码开放的BootloaderU-Boot,结合启动程序的工作机理,对U-Boot的运行代码进行深入分析,详细
25、介绍了其初始化过程及其对操作系统的引导过程。掌握了启动代码之后,对系统功能设计会有很大的帮助,是进行下一步设计的基础。参考文献参考文献 1 王薇.基于嵌入式Linux的BootLoader的设计与应用D.成都:西南交通大学硕士论文,2006 2 张晓林,崔迎炜.嵌入式系统设计与实践M.北京:北京航空航天大学出版社,2006 3 钱峰,刘晔.U-Boot在S3C44B0上的移植J.微型计算机信息,2006,(25):25-28 4 Daniel P.Bovet.Understanding the Linux KernelM.0 Reilly.2002 Startup code Analye of
26、 Embedded Systems Bootloader base on At91sam9260 Cheng Qian,Chen yongtai School of Infomation Engineering,Wuhan University of Technology,Wuhan(430070)Abstract Bootloader is a start up code,which initialize to the inside registers and the function block of the ARM processor,after the embedded system
27、has powered on before the run of operation system or application program.According to at91sam9260 boot strategy,the article adopted at91bootsrap and u-boot formed Bootloader of the system.Then by using the startup code of at91sam9260,detailedly explains the all stages of the process and ultimately loading the operating system kernel.To further,its useful for the system function design.Keywords:at91sam9260;embedded system;bootloader