自己动手编写嵌入式Bootloader.pdfVIP

  • 11
  • 0
  • 约1.54万字
  • 约 11页
  • 2022-04-09 发布于山西
  • 举报
第一部分:基本功能流程 CPU 上电后会从 IO 空间的某地址取第一条指令。但此时: PLL 没有启动, CPU 工作频率为外 部输入晶振频率,非常低; CPU 工作模式、中断设置等不确定;存储空间的各个 BANK (包括 内存)都没有驱动,内存不能使用。在这种情况下必须在第一条指令处做一些初始化工作, 这段 初始化程序与操作系统独立分开,称之为 bootloader 。 实际上,很少有必要自己写一个 Bootloader ,因为 U-Boot 已经强大到能够满足各种需要。但是强大必然复杂,一个初学者想要分析 U-Boot 的源代码,还是有些难度的。出于学习的目的, 我写了这个史上最简单的启动加载器,它只包含最基本的功能,却囊括了一个嵌入式 Bootloader 应该有的核心和精华。我把这个启动加载器命名为 S-Boot , 是 Simple Bootloader 的缩 写,亦可进一步简称为 SB 。 使用的实验环境为 OK2440 开发板,板上处理器为 S3C2440A ,有 64M 内存, Nand 存储器为 K9F1208 ,64M 。网口芯片为 CS8900A 。我们要实现的功能是:从串口下载 Linux 内核映 像到 RAM ;从网口下载 Linux 内核映像到 RAM ;从 RAM 启动内核挂载 NFS 根文件系统。 1. 第一阶段的汇编代码: start.S 一个嵌入式 Bootloader 最初始部分的代码几乎必须是用汇编语言写成的,因为开发板刚上电后没有准备好 C 程序运行环境,比如堆栈指针 SP 没有指到正确的位置。汇编代码应该完成最原 始的硬件设备初始化,并准备好 C 运行环境,这样后面的功能就可以用 C 语言来写了。 对我们的 S-Boot 来说,上电后的起始运行代码是 start/start.S 。 .text .global _start _start: b Reset @ 0x00: 发生复位异常时从地址零处开始运行 b HandleUndef @ 0x04: 未定义指令中止模式的向量地址 b HandleSWI @ 0x08: 管理模式的向量地址,通过 SWI指令进入此模 式 b HandlePrefetchAbort @ 0x0C: 指令预取终止导致的异常的向量地址 b HandleDataAbort @ 0x10: 数据访问终止导致的异常的向量地址 b HandleNotUsed @ 0x14: 保留 b HandleIRQ @ 0x18: 中断模式的向量地址 b HandleFIQ @ 0x1C: 快中断模式的向量地址 这里, 汇编指示符 .text 表明以下内容属于代码段, .global _start 指明 _start 是全局可访问的符号 (Give the symbol external linkage )。按照 ARM920T 的规定, 从地址 0x00 到 0x1C 放置异常向量表,向量表每个条目占四个字节,正好可以放置一条跳转指令,跳转到相应异常的服务程序中去。在 S-Boot 中没有使用中断,所以除 Reset 异常外,其它异常的服务程序都可 简单地写个死循环。 Reset 异常是系统上电后自动触发的,所以我们的代码都写在 Reset 的服务程序里面。 实际上,异常向量表不一定非要位于地址 0x00 处, CP15 协处理器中的 c1 寄存器的第 13 位用来控制异常向量表的起始地址。该位为 0 时,异常向量表位于低地址 0x00 处;该位为 1 时, 异常向量表位于高地址 0xFFFF0000 处。我们没有必要改变这个位的值,使用默认的低地址就行了。 Reset: mrs r0,cpsr @set cp

文档评论(0)

1亿VIP精品文档

相关文档