logo资料库

ARM上电启动及Uboot代码分析.pdf

第1页 / 共30页
第2页 / 共30页
第3页 / 共30页
第4页 / 共30页
第5页 / 共30页
第6页 / 共30页
第7页 / 共30页
第8页 / 共30页
资料共30页,剩余部分请下载后查看
文件编号:01 版本号:1.0 ARM 上电启动及 Uboot 代码分析 部 门: 作 者: 联系方式: 日 期: 2013.03.08
文件修订记录 时间 作者 主要修订内容
目录 目录 文件修订记录 ...............................................................................................................................1 目录 ...............................................................................................................................................2 摘要 ...............................................................................................................................................4 1 ARM 上电取第一条指令流程 .................................................................................................5 1.1 上电后的第一条指令在哪里? ...........................................................................................5 1.1.1 norflash 和 nandflash 的异同 .............................................................................................5 2 Uboot.lds 链接脚本分析 ..........................................................................................................7 2.1 为什么要分析 uboot 链接脚本? ........................................................................................7 2.2 连接代码具体分析 ...............................................................................................................7 3 Uboot 中 start.S 文件分析 .......................................................................................................9 3.1 start.S 详解 .............................................................................................................................9 3.1.1 _start ....................................................................................................................................9 3.1.2 reset .....................................................................................................................................9 3.1.3 cpu_init_cp15 .................................................................................................................... 11 3.1.4 cpu_init_crit ......................................................................................................................12 3.1.5 lowlevel_init ......................................................................................................................13 3.1.6 s_init ..................................................................................................................................14 3.1.7 call_board_init_f ...............................................................................................................15 3.1.8 board_init_f .......................................................................................................................15 3.1.9 relocate_code .....................................................................................................................16 3.1.10 clear_bss ..........................................................................................................................17 3.1.11 jump_2_ram .....................................................................................................................17 3.2 本章小结 .............................................................................................................................18 4 板级初始化及跳入 Linux 内核执行 ....................................................................................19 4.1 board_init_r...........................................................................................................................19 4.1.1 三级标题 ............................................................................................ 错误!未定义书签。 4.2 本章小结 ............................................................................................... 错误!未定义书签。 5 Uboot 异常处理 ......................................................................................................................20 5.1 Uboot 异常向量表 ...............................................................................................................20 5.1.1 异常处理入口函数 ..........................................................................................................20 5.1.2 异常处理函数跳转 ..........................................................................................................21 5.1.3 异常真正处理函数 ..........................................................................................................22 5.2 本章总结 .............................................................................................................................24
目录 结论 .............................................................................................................................................25 参考文献 .....................................................................................................................................26 问题总结及解答 .........................................................................................................................27 附录 .............................................................................................................................................29
摘要 摘要 网上关于 ARM 的 bootloader(以 Uboot 为例)的启动顺序的资料有好多,但是对 于 Uboot 的地址映射、体系结构级操作介绍很少,都是直接开始 Start.s 代码的阅读。本 文拟详细分析 Uboot 从上电,到第一条指令的执行,同时分析代码对于 cache、TLB 等 部件的操作过程。 以下内容以 u-boot-2012.04.01 源码为例,从晚上很容易下载该版本。
ARM 上电取第一条指令流程 1 ARM 上电取第一条指令流程 1.1 上电后的第一条指令在哪里? 首先明确:对于 ARM 芯片,启动时 pc 值由 CPU 设计者规定,不同的 ARM CPU 有不同的值,例如 S3C2440 芯片上电后 PC 值被硬件设计者规定为 0x0;其他 ARM 芯 片不一定是 0x0。 第一章讲述的上电取第一条指令过程以 S3C2440 为例,该芯片是 ARMv4T 架构, 其他芯片在原理上类似。 S3C2440 的启动时读取的第一条指令是在内存 0x00 地址处,不管是从 nand flash 还 是 nor flash 启动。 但是上电后内存中是没有数据的,那么 0x00 地址处的指令是如何放进去的?针对 不同的 flash(nandflash、norflash),操作 方式是不同的,下面 讲述从 nandflash 和 norflash 启动的不同流程。 1.1.1 norflash 和 nandflash 的异同 nand flash:价格低,容量大,适合大容量数据存储,地址线和数据线共用 I/O 线, 所有信息都通过一条线传送,类比于 PC 的硬盘, nor flash:价格贵,容量小,适合小容量的程序或数据存储,类似硬盘,但是能在 其中运行程序;有独立地址线、数据线 sdram:主要用于程序执行时的程序存储、执行或计算,类比于 PC 的内存; 综上:norflash 比较适合频繁随即读写的场合,通常用于存储代码并直接在其中运 行。nandflash 用于存储资料。 只要知道以上大概区别就行。以下说明 ARM 从两种 flash 启动方式的异同。 1.1.1.1 ARM 从 nandFlash 启动 若从 nandflash 启动,上电后 nandflash 控制器自动把 nandflash 存储器中的 0—— 4K 内容加载到芯片内的起步石(Steppingstone,起步石这个机制是处理器中集成的功 能,对程序员透明),即内部 SRAM 缓冲器中,同时把内部 SRAM 的起始地址设置为 0x0(不同的 CPU 上电后的 PC 值不尽相同,对不同的 CPU 该值也不尽相同),然后把 这段片内 SRAM 映射到 nGCS0 片选的空间,进而 CPU 开始从内部 SRAM 的 0x0 处开 始取得第一条指令,该过程全部是硬件自动完成,不需要程序代码控制。 或许你有个疑问,为什么不能直接把 nandflash 映射到 0x0 地址处?非要经过内部 SRAM 缓冲?
ARM 上电取第一条指令流程 答案是,nandflash 根本没有地址线,没法直接映射,必须使用 SRAM 做一个载 体,通过 SRAM 把剩余的 nandflash 代码(即剩余的 uboot 启动代码)复制到 SDRAM 中运行。 若想从 nandflash 启动,那么 uboot 最核心的代码必须放在前 4k 完成。这 4k 代码要 完成 ARM CPU 的核心配置以及将剩余的代码拷贝到 SDRAM 中(若从 norflash 启动则 没有 4k 这个大小的限制,但是还会在完成最主要的设置后进入 SDRAM 中运行)。 1.1.1.2 ARM 从 norflash 启动 若从 norflash 启动,则 norflash 直接被映射到内存的 0x0 地址处(就是 nGCS0,这 里 就 不 需 要 片 内 SRAM 来 辅 助 了 , 所 以 片 内 SRAM 的 起 始 地 址 不 变 , 还 是 0x40000000),然后 cpu 从 0x00000000 开始执行(也就是在 Norfalsh 中执行)。 需要说明的是,uboot 代码段(.text 段)起始位置必须是与上电后 PC 值一致,即 编译 uboot 时,TEXT_BASE 宏必须设置成 0x0 ,反汇编 uboot 文件后,文本段第一条 指令的地址也是 0. 总结: 1、 从 norflash 还是从 nandflash 启动,是由 ARM 的 OM1 和 OM0 引脚组合决定 2、不管从 norflash 还是 nandflash 启动,S3C2440 上电后的 pc 值为 0x0 3、如果某芯片上电后 PC 值不是 0x0,假如是 0x38ff0000,那么从 norflash 启动 时,硬件就要自动将其映射到 0x38ff0000 地址处;如果从 nandflash 启动,那么硬 件就要自动将 nandflash 中的前 4K 内容加载到 0x38ff0000 地址处。
Uboot.lds 链接脚本分析 2 Uboot.lds 链接脚本分析 2.1 为什么要分析 uboot 链接脚本? 因为 u-boot.lds 决定了 u-boot 可执行映像的链接方式,以及各个段的装载地址(装 载域)和执行地址(运行域),也就是说,Uboot.lds 文件指定 uboot.bin 可执行文件放到 ROM 中的哪个地址、在运行时在 RAM 中运行的起始地址,具体内容涉及装载域和运 行域的概念,这里不详述。 2.2 连接代码具体分析 以 u-boot-2012.04.01 版本为例。 u-boot-2012.04.01/arch/arm/cpu/u-boot.lds //设置输出文件大小端格式——OUTPUT_FORMAT(default,big,little),如果不指 定大小端,默认为小段;就算指定了大端,也以小端处理。 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) //设置文件以 ARM 可执行文件格式输出 ENTRY(_start) //设置初始入口点,所有指令的入口点就是_start 标 号,见 3.1 章节 start.S 第一条指令 //告诉链接器如何将输入段组合映射到输出端,以及如何 SECTIONS 在内存中放置这些段 { . = 0x00000000; //“.”代表位置计数器,紧跟 SECTIONS 命令的这句命令 是指定后面的段在内存中的起始位置,缺省为 0x0,所以该指令可以不要。 //指定 text 输出端以 4 字节对齐。 . = ALIGN(4); .text : { __image_copy_start = .; CPUDIR/start.o (.text) 处的第一个可执行文件。CPUDIR 是一个宏,指定 start.s 的路径 *(.text) } . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }//只读数据 段,首先将所有文件的只读数据段以名字(即 asc 码排序),然后以对齐方式排序存 放到 text 段后面。 //text 段的第一个输入段是 start.o,即指定放到 0x0 地址 //其他文件的文本段紧跟 start.o 文件放置。 . = ALIGN(4); .data : { *(.data) }//所有的数据段 . = ALIGN(4); .got : { *(.got) }// got 段是 uboot 自定义的一个段,不是 GNU 官方定义的标准 段。 . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } //指定 u_boot_cmd 段, uboot 把所有的 uboot 命 // 令放在该段. __u_boot_cmd_end = .;
分享到:
收藏