




已阅读5页,还剩74页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章嵌入式系统的BootLoader 7 1BootLoader概述7 2BootLoader与嵌入式系统的关系7 3BootLoader的主要功能及典型结构7 4S3C44B0X的BootLoader分析7 5U Boot启动流程及相关代码分析 7 1BootLoader概述7 1 1BootLoader的作用和任务当一个微处理器启动时 它首先执行预定地址处的指令 通常这个位置是只读内存 其中存放着系统初始化或引导程序 如PC中的BIOS BIOS进行低级的处理器初始化并配置其他硬件 接着判断哪一个磁盘包含有操作系统 OS 再把该操作系统复制到RAM中 并把控制权交给操作系统 嵌入式系统的BootLoader程序 即系统的引导装载程序 简单地说 就是在操作系统内核或用户应用程序之前运行的一段小程序 通过这段小程序可以初始化硬件设备和建立内存空间的映射图 将系统的软 硬件环境带到一个合适的状态 以便为最终调用操作系统内核或用户应用程序准备好正确的环境 有的操作系统比较简单 或只有简单的应用程序 因而不需要专门的BootLoader来安装内核和文件系统 但仔细分析就会发现 它们都需要一个初始化程序来完成初始化 为后面程序的执行准备一个正确的环境 通常 BootLoader是依赖于硬件而实现的 因此 为嵌入式系统建立一个通用的BootLoader是很困难的 但是可以归纳出一些通用的概念 以便了解特定BootLoader的设计与实现 BootLoader的主要任务如图7 1所示 图7 1BootLoader的主要任务 7 1 2常用嵌入式BootLoader介绍常用的嵌入式BootLoader有vivi U Boot RedBoot ARMBoot Blob和DIY 1 vivivivi是由韩国MIZI公司开发的一种专门用于ARM产品线的BootLoader 因为vivi目前只支持使用串口与主机通信 所以必须使用一条串口电缆来连接目标板和主机 vivi的源代码下载地址为 检测目标板 下载程序并写入Flash 初始化硬件 把内核从Flash复制到RAM 然后启动它 vivi源代码的主要目录的解释如下 CVS 存放CVS工具相关的文件 Documentation 存放一些vivi的帮助文档 Arch 存放与CPU构架体系结构有关的代码文件 drivers 存放与vivi相关的驱动代码文件 include 存放所有vivi源代码的头文件 init 存放vivi初始化代码文件 lib 存放vivi实现的库函数文件 scripts 存放vivi脚本配置文件 test 存放一些测试代码文件 util 存放一些与NandFlash烧写image相关的工具实现代码 2 U BootU Boot是德国DENX小组开发的用于多种嵌入式CPU的BootLoader程序 它可以运行在PowerPC ARM MIPS等多种嵌入式开发板上 从http u ftp ftp denx de pub u boot 站点均可以下载U Boot的源代码 U Boot源代码的主要目录的解释如下 board 目标板相关文件 主要包含SDRAM Flash驱动 common 独立于处理器体系结构的通用代码 如内存大小探测与故障检测代码 cpu 与处理器相关的文件 如mpc8xx子目录下的串口 网口 LCD驱动及中断初始化等文件 driver 通用设备驱动 如CFIFlash驱动 目前对IntelFlash支持较好 doc U Boot的说明文档 examples 可以在U Boot下运行的示例程序 如hello world c和timer c include U Boot头文件 尤其是configs子目录下与目标板相关的配置头文件 它是移植过程中经常要修改的文件 lib xxx 处理器体系相关的文件 如lib ppc lib arm目录分别包含的与PowerPC ARM体系结构相关的文件 net 与网络功能相关的文件目录 如boot NFS和TFTP post 上电自检文件目录 尚有待进一步完善 rtc RTC RealTimeClock 实时时钟 驱动程序 tools 用于创建U Boot S RECORD和BIN镜像文件的工具 3 RedBootRedBoot是一个专门为嵌入式系统定制的引导启动工具 最初由RedHat公司开发 它基于ECOS EmbeddedConfigurableOperatingSystem 的硬件抽象层 同时继承了ECOS的高可靠性 简洁性 可配置性和可移植性等特点 在http sourceware org redboot站点可以下载RedBoot源码 同时也可以了解更多关于Redboot的详情信息 Redboot在嵌入式体系中应用非常广泛 RedBoot是集BootLoader 调试和Flash烧写于一体的 支持串口 网络下载的可执行嵌入式应用程序 它既可以用在产品的开发阶段 调试功能 也可以用在最终的产品上 Flash更新 网络启动 RedBoot支持下载和调试应用程序 用户可以通过TFTP协议下载应用程序和image 或者通过串口用X modem Y modem下载 开发板可以通过BOOTP DHCP协议动态配置IP地址 并支持跨网段访问 所以可对gcc编译的程序进行源代码级的调试 相比于简易JTAG调试器 它可靠 高速 稳定 RedBoot支持用GDB通过串口或网卡调试嵌入式程序 用户可通过串口或网卡以命令行的形式管理Flash上的image 并下载image到Flash 动态配置RedBoot启动的各种参数 启动脚本 上电后RedBoot可自动从Flash或TFTP服务器上下载应用程序执行 4 ARMBootARMBoot是一个以ARM或StrongARM为CPU内核的嵌入式系统的BootLoader固件程序 该软件的主要目标是使新的平台更容易被移植 并且尽可能地发挥其强大性能 它只基于ARM固件 但是它支持多种类型的启动 如Flash 网络下载通过BOOTP DHCP TFTP等 它也是开源项目 可以从 5 BlobBlob是BootLoaderObject的缩写 是一款功能强大的BootLoader 其源代码在 6 DIYDIY DoItYourself 即自己制作 上面介绍的U Boot vivi Blob RedBoot ARMboot等成熟工具虽然移植起来简单快捷 但它们都存在着一定的局限性 首先 因为它们是面向大部分硬件的工具 所以在功能上要满足大部分硬件的需求 但一般情况下用户只需要与特定的开发板相关的实现代码 其他型号开发板的实现代码对它来说是没有用的 因此通常会有较大的无用代码 其次 它们在使用上不够灵活 如在这些BootLoader上添加自己的特有功能比较困难 因为必须熟悉该代码的组织关系 且了解它的配置编译等文件 用DIY的方式自己编写针对目标的BootLoader 不但代码量短小 而且灵活性很大 最重要的是将来容易维护 所以在实际嵌入式产品的开发中大多都选择DIY的方式编写BootLoader 7 2BootLoader与嵌入式系统的关系不同的BootLoader有不同的处理器体系结构 有些BootLoader还支持多种体系结构的处理器 比如U Boot就同时支持ARM体系结构和MIPS体系结构 除了依赖处理器的体系结构外 BootLoader实际上也依赖于具体的嵌入式板级设备的配置 即使是基于同一种处理器构建的两块不同的嵌入式板级设备 它们的BootLoader也是不同的 BootLoader源程序是很关键的代码 因为它是把特定的数字写入指定硬件寄存器的指令序列 系统加电复位后 所有的处理器都从处理器制造商预先安排的地址上取指令 如基于S3C44B0X的处理器在复位时通常都从地址0 x00000000上取它的第一条指令 而且基于处理器构建的嵌入式系统通常都有某种类型的固态存储设备 如ROM E2PPOM Flash等 被映射到这个预先安排的地址上 因此在系统加电后 处理器将首先执行BootLoader程序 装有BootLoader内核的启动参数 内核映像和根文件系统映像的固态存储设备的典型空间分配结构如图7 2所示 图7 2存储设备典型空间分配结构 7 2 1BootLoader的操作模式1 启动加载 BootLoading 模式启动加载模式也称为自主 Autonomous 模式 即BootLoader从目标机的某个固态存储设备上将操作系统加载到RAM中运行 整个过程并没有用户的介入 这种模式是BootLoader的正常工作模式 因此在嵌入式产品发布的时候 BootLoader显然必须工作在这种模式下 只有工作在这种模式下 当系统上电或复位后 才能正常地运行操作系统 出现通信信息或图形界面供用户操作 2 下载 DownLoading 模式当采用下载模式时 目标机的BootLoader将通过串口连接 网络连接等通信手段从主机上下载文件 如应用程序 数据文件 内核映像等 从主机下载的文件通常先被BootLoader保存到目标机的RAM中 然后再被BootLoader写到目标机上的固态存储设备中 下载模式要求在BootLoader中完成对串口或以太网口的初始化 定义相关的命令和向其终端提供相应简单的命令接口 BootLoader的这种模式通常在系统更新时使用 7 2 2BootLoader的总体设计1 阶段设计BootLoader的启动是可以分阶段的 因此在设计时也可将BootLoader分为阶段1和阶段2 BootLoader的设计分为两个阶段的原因如下 1 基于编程语言的考虑 阶段1主要用汇编语言编写 这是因为它主要进行与CPU核心及存储设备密切相关的处理工作和进行一些必要的初始化工作 是依赖于CPU体系结构的代码 所以为了增加效率以及匹配协处理器的设置 只能用汇编语言编写 这部分直接在Flash中执行 阶段2可以用C语言编写 主要实现一般的流程以及对板级的一些驱动支持 这部分会被复制到RAM中执行 2 为了使代码具有更好的可读性与可移植性 对于相同的CPU以及存储设备 若要增加外设支持 阶段1的代码可以维持不变 只对阶段2的代码进行修改 而对于不同的CPU 则只需在阶段1中修改基础代码 2 地址规划设计当BootLoader的阶段设计完成之后 需要考虑的是镜像存储的地址分配 如总镜像保存在什么地方 阶段2对应的镜像会被复制到什么地方 内核镜像原先存放在什么地方及BootLoader会把它又重新加载到什么地方 如何进行准确的地址规划以保证没有相互冲突等 本章所介绍的内核镜像以及根文件系统镜像都是被加载到SDRAM中运行的 这样做是基于运行速度的考虑 尽管在嵌入式系统中内核镜像与根文件系统镜像也可以直接在ROM或Flash这样的固态存储设备中直接运行 但是BootLoader在启动以及加载内核时通常要考虑这一点 虽然BootLoader最终会生成一个可执行镜像 但是为了能更清楚地解释其实现流程 将其与启动阶段对应起来分成镜像1和镜像2 事实上 在编译过程中也会形成这两个镜像 即总的镜像1和被复制至SDRAM中的镜像2 这里用物理地址的0 x00000000 0 x00040000存放BootLoader的镜像 内核镜像放在物理地址0 x000C0000之后的1MB空间内 内核镜像一般都小于1MB 镜像2则在SDRAM中运行 这样BootLoader的启动速度会大大加快 因此这里镜像2放在SDRAM的以0 xA0000000为起始地址的空间内运行 而内核镜像则规划至物理地址的0 xA0300000处执行 3 模式设计对于普通用户来说只需要BootLoader的启动加载模式 但是对于开发者来说 则需要下载模式 因为他们需要实时地进行一些镜像的更新 为了在两者之间做到兼顾 这里介绍一个既支持启动加载模式又支持下载模式的具体思路 在BootLoader完成一些硬件初始化工作之后 在加载内核镜像之前 判断一定的时间内有没有用户的键盘输入 如果没有 则为启动加载模式 直接加载内核镜像进行启动 如果有 则进入命令行格式 这时开发者就可以根据自己的需要以及BootLoader的支持情况 做一些其他的工作 模式的转换设计主要在阶段2中实现 7 3BootLoader的主要功能及典型结构7 3 1BootLoader的阶段11 基本的硬件初始化基本的硬件初始化是BootLoader一开始就执行的操作 其目的是为了阶段2的内核的执行准备好一些基本的硬件环境 它执行的步骤如下 1 屏蔽所有的中断 为中断提供服务通常是操作系统设备驱动程序的责任 因此在BootLoader的执行全过程中可以不必响应任何中断 中断屏蔽可以通过写处理中断屏蔽寄存器或状态寄存器 比如ARM的CPSR寄存器 来完成 2 设置处理器的速度和时钟频率 这一步骤可以通过设置时钟控制寄存器来完成 注意设置的时候应该根据晶振的振荡频率和实际需要的频率来设置 3 初始化RAM 包括正确地设置系统内存控制器的功能寄存器以及各内存控制寄存器 4 初始化LED LED一般通过GPIO来驱动 其目的是表明系统的状态是否正常 如果板子上没有LED 那么也可以通过初始化UART向串行口输出BootLoader的特定字符 如 OK 信息来完成 这样可方便用户判断BootLoader是否已经成功启动 5 关闭处理器内部指令 数据缓存 2 加载阶段2的RAM空间为了获得更快的执行速度 通常把阶段2加载到RAM空间中来执行 因此必须为加载BootLoader的阶段2准备好一段可用的RAM空间 由于阶段2通常用C语言来执行 因此在考虑空间大小时 除了阶段2可执行映像的大小外 还必须把堆栈空间也考虑进来 此外 空间大小最好是页面文件 MemoryPage 大小 通常是4KB 的倍数 一般而言 1MB的RAM空间已经足够了 具体的地址范围可以任意安排 比如Blob方式就是将它的阶段2可执行映像安排到系统RAM地址0 xC0200000开始的1MB空间内执行 但是 将阶段2安排到整个RAM最顶层的1MB空间是一种最常用的方法 为了后面叙述的方便 这里把所安排的RAM空间的大小记为stage2 size 字节 把起始地址和终止地址分别记为stage2 start和stage2 end 这两个地址均为以4字节边界对齐 另外 还必须确保所安排的的地址是可读写的RAM空间 因此 必须对所安排的地址进行测试 具体的测试方法可以采用类似于Blob的方法 即以MemoryPage为被测试单位 测试每个MemoryPage开始的两个字是否是可读写的 为了后面叙述的方便 这个检测算法记为test mempage 其具体步骤如下 1 先保存MemoryPage最开始两个字的内容 2 向这两个字写入任意的数字 如向第一个字写入0 x55 第二个字写入0 xAA 3 立即将这两个字的内容读回 正常情况下 读到的内容应该分别是0 x55和0 xAA 如果不是 则说明这个MemoryPage所占据的地址不是一段有效的RAM空间 4 再向这两个字中写入任意的数字 如向第一个字写入0 xAA 向第2字写入0 x55 5 立即将这两个字的内容读回 读到的内容应该分别是0 xAA和0 x55 如果不是 则说明这个MemoryPage所占据的地址不是一段有效的RAM空间 6 恢复这两个字的原始内容 测试完毕 为了得到一段干净的RAM空间范围 也可以将所安排的RAM空间进行清零操作 3 复制阶段2到RAM复制阶段2到RAM时要确定以下两点 1 阶段2的可执行映像在固态存储设备的存放起始地址和终止地址 2 RAM空间的起始地址 4 设置堆栈指针 SP 堆栈指针的设置是为执行C语言代码作准备的 通常可以把SP的值设置为stage2 end 4 即在7 3 2节中提到的那个1MB的RAM空间的最顶端 堆栈向下生长 此外 在设置堆栈指针SP之前 也可以关闭LED灯 以提示用户程序准备跳转到阶段2 5 跳转到阶段2的C程序入口点在上述一切都就绪后 就可以跳转到BootLoader的阶段2去执行了 比如 在ARM系统中 就可以通过修改寄存器PC为合适的地址来实现 BootLoader在Flash和RAM中的系统布局如图7 3所示 图7 3BootLoader在Flash和RAM中的系统布局 7 3 2BootLoader的阶段2阶段2的代码通常用C语言来实现 以便实现更复杂的功能和取得更好的代码可读性及可移植性 1 初始化阶段2要使用的硬件设备初始化阶段2通常包括初始化一个串行口 以便和终端用户进行I O输出信息 初始化计时器等 2 检测系统内存映射所谓内存映射就是指整个物理地址空间中那些分配用来寻址系统的RAM单元 在S3C44B0X处理器中 从0 x0C000000到0 x10000000之间的64MB地址空间被用作系统的RAM地址空间 虽然CPU通常预留出一大段足够的地址空间给系统RAM 但是在搭建具体的嵌入式系统时却不一定会实现CPU预留的全部RAM地址空间 也就是说 具体的嵌入式系统往往只把CPU预留的全部RAM地址空间处于未使用状态 由于上述事实 BootLoader的阶段2必须在执行操作 比如 将存储在Flash上的内核映像读到RAM空间中 之前检测整个系统的内存映射情况 即它必须知道处理器预留的全部RAM地址空间哪些被真正映射到RAM地址单元 哪些是处于 未使用 状态的 3 加载内核映像和根文件系统映像 1 规划内存占用的布局 在规划内存占用的布局时 主要考虑内核映像所占用的内存范围和根文件系统所占用的内存范围两个方面 2 从Flash上复制 由于像ARM这样的嵌入式处理器通常都是在统一的内存地址空间中寻找Flash等固态存储设备的 因此从Flash上读取数据与从RAM单元中读取数据并没有什么不同 用一个简单的循环就可以完成从Flash设备上拷贝映像的工作 程序代码如下 拷贝Flash地址0 x10000内核到RAM0 xC300000中 ldrR0 0 x10000ldrR1 0 xC300000addR2 R0 1536 1024 copy kernel ldmiaR0 R3 R10 stmiaR1 R3 R10 cmpR0 R2blecopy kernel 4 调用内核所有硬件的设置完成之后 就可以跳转到内核 并开始运行内核了 调用内核的程序代码如下 跳转到RAM中执行内核 ldrR0 0 xC30000 0 xC30000正是前面拷贝kernel函数中的目的地址movPC R0 修改程序地址寄存器 完成跳转 7 4S3C44B0X的BootLoader分析S3C44B0X下的 CLinux的BootLoader只是一个比较简单的BootLoader 所以它的阶段1和阶段2是一起由汇编完成的 程序流程如图7 4所示 图7 4简单的BootLoader工作流程图 以下是该BootLoader的完整程序 File boot s WTCONEQU0 x01D30000 以下的几个定义均是为了设置相应的控制寄存器 请注意查阅各位所对应的作用 理解所作的设置PCONEEQU0 x01D20028LOCKTIMEEQU0 x01D8000CPLLCONEQU0 x01D80000CLKCONEQU0 x01D80004GLOBAL start start breset 程序的第一条指令 在烧写时 它将会被烧写在0 x00000000地址addpc pc 0 x0C000000addpc pc 0 x0C000000addpc pc 0 x0C000000addpc pc 0 x0C000000addpc pc 0 x0C000000addpc pc 0 x0C000000addpc pc 0 x0C000000MEMORY CONFIG 定义一组数据用来设置后面的存储器 可以把它看做一个数组 DCD0 x11110102DCD0 x600DCD0 x7FFCDCD0 x7FFCDCD0 x7FFCDCD0 x7FFCDCD0 x7FFCDCD0 x18000DCD0 x18000DCD0 x860459DCD0 x10DCD0 x20DCD0 x20 复位地址reset 关看门狗ldrr0 WTCONldrr1 0 x0strr1 r0 设置端口控制寄存器PortE 打开RxD0和TxD0 串口输入功能 ldrr1 PCONEldrr0 0 x25529strr0 r1 设置时钟控制寄存器ldrr1 LOCKTIMEldrr0 0 xFFFstrr0 r1 ldrr1 PLLCONldrr0 0 x78061strr0 r1 ldrr1 CLKCONldrr0 0 x7FF8strr0 r1 设置寄存器memsetup ldrr0 MEMORY CONFIG 注意不用一个一个设置 通过前面已经定义好的数 组用4条指令就可以完成设置ldmiar0 r1 r13 ldrr0 0 x01C80000stmiar0 r1 r13 拷贝Flash地址0 x1000内核到RAM0 xC300000中 ldrr0 0 x10000ldrr1 0 xC300000addr2 r0 1536 1024 计算内核的终点地址copy kernel ldmiar0 r3 r10 stmiar1 r3 r10 cmpr0 r2blecopy kernel 跳转到RAM中执行内核ldrr0 0 xC300000 0 xC300000正是前面拷贝内核函数中的目的地址movpc r0 修改程序地址寄存器 完成跳转 7 5U Boot启动流程及相关代码分析7 5 1U Boot启动流程U Boot作为ARM平台常用的引导程序 具有结构强大和功能强大的特点 下载u boot 1 2 0 tar bz2源码包 解压后会生成u boot 1 2 0目录 该目录主要包括三类子目录 与处理器或硬件电路板相关的文件目录 如cpu board libarm等 存放通用文件和设备驱动的目录 如common inculde drivers等 存放U Boot应用程序 工具和文档的目录 如examples tools等 下面来分析U Boot的启动流程 1 阶段1U Boot的阶段1 Stage1 代码通常放在u boot 1 2 0 cpu arm920t start s文件中 用汇编语言写成 其主要代码功能如下 定义入口 由于一个可执行的Image必须有一个入口点 并且只能有一个全局入口 通常这个入口放在ROM Flash 的0 x0地址 因此 必须使编译器知道这个入口 该工作可通过修改链接器脚本来完成 设置异常向量 ExceptionVector 设置CPU的速度 时钟频率及终端控制寄存器 初始化内存控制器 将ROM中的程序复制到RAM中 初始化堆栈 转到RAM中执行 该工作可使用指令ldrpc来完成 2 阶段2对于ARM平台来说 U Boot的阶段2 Stage2 代码在u boot 1 2 0 lib arm board c文件中 文件中的start armboot函数是整个C语言启动代码中的主函数 同时还是整个U Boot 针对ARM平台 的主函数 该函数将完成如下操作 调用一系列的初始化函数 初始化Flash设备 初始化系统内存分配函数 如果目标系统拥有NAND设备 则初始化NAND设备 如果目标系统有显示设备 则初始化该设备 初始化相关网络设备 填写IP MAC地址等 进入命令循环 即整个boot的工作循环 接收用户从串口输入的命令 然后进行相应的工作 图7 5U Boot启动代码顺序图 7 5 2U Boot代码分析U Boot代码分析如下 U Boot的start S 定义变量 start 然后跳转到处理器复位代码 glob1 start U Boot启动入口 start breset 若产生中断则利用pc来跳转到对应的中断处理程序中ldrpc undefined instruction 未定义指令向量ldrpc software interrupt 软件中断向量ldrpc prefetch abort 预取指中止向量ldrpc data abort 数据中止向量ldrpc not used 保留ldrpc irq 中断请求向量ldrpc fiq 快速中断请求向量 利用 word在当前位置放置一个值 这个值实际上就是对应的中断处理函数的地址 word的意义为在当前地址处放入一个16bits的值 undefined instruction wordundefined instruction software interrupt wordsoftware interrupt prefetch abort wordprefetch abort data abort worddata abort not used wordnot used irq wordirq fiq wordfiq balignl16 0 xdeadbeef reset代码 reset mrsr0 cpsrbicr0 r0 0 x1f bic清除指定为1的位orrr0 r0 0 xd3 orr逻辑或操作 经过以上两步r0值控制位为11010011 第0 4位表示处理器当前所处模式为10011 32 位管理模式 第6 7位为1表示禁止IRQ和FIQ中断 第5位为0表示程序在ARM 状态 若其为1则运行在Thumb状态msrcpsr r0 设置处理器为32位管理模式 关闭看门狗 definepWTCON0 x53000000 看门狗寄存器地址 defineINTMSK0 x4A00008 中断掩码寄存器 决定哪个中断源被屏蔽 某位为1则 屏蔽中断源 初始值为0 xffffffff 屏蔽所有中断 defineINTSUBMSK0 x4A00001C 中断子掩码寄存器 该寄存器只能屏蔽11个中断源 因此其仅低11位有效 初始值为0 x7ff defineCLKDIVN0 x4C000014 时钟分频控制寄存器 将看门狗寄存器清空 其各位含义为 第0位为1则当看门狗定时器溢出时重启 为 0则不重启 初值为1 第2位为中断使能位 初值为0 第3 4位为时钟分频因子 初值为00 第5位为看门狗的使能位 初值为1 第8 15位为比例因子 初值为0 x80ldrr0 pWTCONmovr1 0 x0strr1 r0 将看门狗寄存器所有位置0 关闭看门狗 其实只要将第5位置0即可movr1 0 xFFFFFFFFldrr0 INTMSKstrr1 r0 屏蔽所有中断 实际上中断掩码寄器初值即为0 xFFFFFFFldrr1 0 x3FFldrr0 INTSUBMSK strr1 r0 设置中断子掩码寄存器 设置时钟寄存器 CLKDIVN第0位为PDIVN 为0则PCLK HCLK 为1则 PCLK HCLK 2 第1位为HDIVN 为0则HCLK FCLK 为1则HCLK FCLK 2 这里两位均为1 则FCLK HCLK PCLK 4 2 1ldrr0 CLKDIVNmovri 3strr1 r0 reset代码 cpu init crit代码 对关键寄存器的初始化 如果从RAM中启动则不执行cpu init crit段代码cpu init crit 清空指令和数据cachesmovr0 0mcrp15 0 r0 c7 c7 0mcrp15 0 r0 c8 c7 0 disableMMUstuffandcaches mrcp15 0 r0 c1 c0 0bicr0 r0 0 x00002300 clearbits13 9 8 V RS bicr0 r0 0 x00000087 clearbits7 2 0 B CAM orrr0 r0 0 x00000002 setbit2 A Alignorrr0 r0 0 x00001000 setbit12 I I Cachemcrp15 0 r0 c2 c0 0 在重定向代码之前 必须初始化内存时序 因为重定向时需要将Flash中的代码复制 到内存中 内存初始化的代码在board smdk2410 lowlevel ini S中movip lrbllowlevel init 调用lowlevel init子程序 board smdk2410 lowlevel ini S movlr ipmovpc lr 程序返回 cpu init crit代码 lowlevel init代码 lowlevel ini S lowlevel init memorycontrolconfiguration maker0relativethecurrentlocationsothatit readsSMRDATAoutofFlashratherthanmemory ldrr0 SMRDATAldrr1 TEXT BASEsubr0 r0 r1ldrr1 BWSCON BusWidthStatusController addr2 r0 13 40b ldrr3 r0 4strr3 r1 4cmpr2 r0bne0b everythingisfinenow movpc lr lowlevel init代码 lowlevel ini s relocate代码 relocate relocateU BoottoRAM 当前代码地址 adr获取当前代码的地址信息 若从RAM运行 则 start TEXT BASE 否则 start 0 x00000000adrr0 start r0 currentpositionofcode 获取 TEXT BASEldrr1 TEXT BASE testifwerunfromflashorRAM cmpr0 r1 don treloctduringdebug 两者相等 表示从RAM运行则跳转到堆栈设置bepstack setup 不相等则表示从Flash中运行 重定向代码ldrr2 armboot start 获取未初始化数据段地址Ldrr3 bss start 计算代码段大小subr2 r3 r2 r2 sizeofarmboot 计算代码段终止地址addr2 r0 r2 r2 sourceendaddress 复制代码 r0为代码的起始地址 r1为RAM中地址 r2为代码的终止地址 每次复制后将r0值递增同r2比较来判断是否复制完成copy loop ldmiar0 r3 r10 copyfromsourceaddress r0 stmiar1 r3 r10 copytotargetaddress r1 cmpr0 r2 untilsourceendaddreee r2 blecopy loop relocate代码 stack setup代码 stack setup 获取 TEXT BASEldrro TEXT BASE upper128K B relocateduboot 获取分配区域起始指针 CFG MALLOC LEN 128 1024 CFG ENV SIZE 128 1024 0X1000 192Ksubr0 r0 CFG MALLOC LEN mallocarea 另外分配128B来存储开发板信息subr0 r0 CFG GBL DATA SIZE bdinfo ifdefCONFIG USE IRQsubr0 r0 CONFIG STACKSIZE IRQ CONFIG STACKSIZE FIQ endif 再减去12B用于栈起点subsp r0 12 leave3wordsforabort stack 清空未初始化数据段clear bss ldrr0 bss start findstartofbsssegment ldrr1 bss end stophere movr2 0 x00000000 clear clbss 1 strr2 r0 clearloop addr0 r0 4cmpr0 r1 bleclbss 1 stack setup代码 完成复制后跳转到start armboot 到这里则进入lib arm board c的start armboot函数中ldrpc start armboot start armboot wordstart armboot在lib arm board c中 首先定义函数指针数组 代码如下 typedefint init fnc t void 定义函数指针数组 对硬件初始化按照该数组进行init fnc t init sequence cpu init cpu arm920t cpu c中定义 该函数为空 因为没有采用IPQ或FIQ模式board init board smdk2410 smdk2410 c interrupt init cpu arm920t s3c24x0 interrupt cenv init tools env FW env cinit baudrate lib arm board cserial init cpu arm920t s3c24x0 serial cconsole init f common console cdisplay banner lib arm board c ifdefined CONFIG DISPLAY BOARDINFO print cpuinfo endif ifdefined CONFIG DISPLAY BOARDINFO checkboard endifdram init board smdk2410 smdk2410 cdisplay dram config lib arm board cNULL start armboot代码 voidstar armboot void init fnc t init fnc ptr char s ifndefCFG NO FLASHulongsize endif ifdefined CONFIG VFD defined CONFIG LCD unsignedlongaddr endif Pointeriswritablesinceweallocatedaregisterforit 获取全局gd指针gd gd t armboot start CFG MALLOC LEN sizeof gd t compileroptimizationbarrierneededforGCC 3 4 asm volatile memory 清空该结构体memset void gd 0 sizeof gd t 获取bd info结构体指针gd bd bd t char gd sizeof bd t memset gd bd 0 sizeof bd t 整个代码区的长度 Monitor flash len bss start armboot start 调用初始化函数 用来初始化gd结构体for init fnc ptr init sequence init fnc ptr ini fnc ptr if init fnc ptr 0 hang ifndefCFG NO FLASH configureavailableFLASHbanks board smdk2410 flash c配置flash 从其实现来看 好像只是配置NORFlash 按页对其方式保留显存addr bss end PAGE SIZE 1 PAGE SIZE 1 size vfd setmem addr gd fb base addr endif CONFIG VFD 显示器为LCD 同上 ifdefCONFIG VFD ifndefPAGE SIZE definePAGE SIZE4096 endif reservememoryforLCDdisplay alwaysfullpages bss endisdefinedintheboard specificlinkerscript size flash init 显示Flash信息display flash config size endif CFG NO FLASH 定义显示类型 ifdefCONFIG VFD ifndefPAGE SIZE definePAGE SIZE4096 endif reservememoryforVFDdisplay alwaysfullpages bss endisdefinedintheboard specificlinkerscript addr bss end PAGE SIZE PAGE SIZE 1 size lcd setmem addr gd fb base addr endif CONFIG LCD 初始化CFG MALLOC LEN大小空间 armboot startisdefinedintheboard specificlinkerscript mem malloc init armboot start CFG MALLOC LEN 初始化NANDFlash 这是在NANDFlash启动的s3c2410移植U Boot的关键 根据Flash 时序编写函数即可 在include configs smdk2410 h中的commanddefinition中增加CONFIG COMMANDS 和CFG CMD NAND命令 if CONFIG COMMAND CFG CMD
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑转量化金融方案设计
- 《纪念白求恩》课例研磨:课堂实录篇之教学设计
- 盐池综合互联网营销方案
- 水泥楼梯防滑槽施工方案
- 运输设备技术分类报告
- 版权登记流程简化分析报告
- 声表面波显示技术专利布局策略报告
- 农村盖房门楼施工方案
- 高职创新创业教育现状调研报告
- 信息安全风险防控指导手册
- 2025年电梯安全培训试题附答案
- 2025年职业技能鉴定考试(涂装工·高级/三级)历年参考题库含答案详解(5套)
- 2025至2030年中国猫砂行业发展监测及投资战略研究报告
- 2025年理赔人员上岗考试题库
- 2025年AI技术在项目管理中的应用洞察报告
- 荧光分析技术第二章荧光信号机制讲课文档
- 2025-2026年秋季学期各周国旗下讲话安排表+2025-2026学年上学期升旗仪式演讲主题安排表
- 2025年公务员(国考)之公共基础知识考试题库(带答案解析)
- 初级医学影像技术师考试试卷及答案2025年
- 幼儿园一日生活指引培训
- 中班健康运蔬菜喽
评论
0/150
提交评论