u-boot分析 四 (程序入口start.S)
注:部分内容摘抄自网络,如有问题,请联络博主。
本文内容:了解以stars.S为开始的ARM汇编程序部分。
回顾前几篇博文,咱们见识过了u-boot的目录结构,另外简要分析了u-boot.lds脚本文件的link原理。而今天我们要来听听嵌入式程序君告诉咱们的第一句“话”。
正式开始之前,我们需要准备三样东西:
- u-boot source code
- 常用ARM指令集
- Source Insight(用于trace code,使用方法略过,不会问百度)
bootloader通常stage1和stage2两步骤,u-boot也不例外。
- Stage1:依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在这个程序段,且可以用汇编语言来实现;
- stage2:通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
具体的说,
Stage1 start.S代码结构
u-boot的stage1代码通常放在start.S文件中,用汇编语言写成,其主要代码部分如下:
(1) 定义入口。由于一个可执行文件必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址。因此,必须通知编译器以使其知道这个入口,该工作可通过修改链接器脚本(.lds文件)来完成。
(2) 设置异常向量(Exception Vector)。
(3) 设置CPU的速度、时钟频率及终端控制寄存器。
(4) 初始化内存控制器。
(5) 将ROM中的代码复制到RAM中。
(6) 初始化堆栈。
(7) 转到RAM中执行,该工作可使用指令ldr pc来完成。Stage2 C语言代码部分
./arch/arm/lib/board.c中的board_init_r()是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:
(1) 调用一系列的初始化函数。
(2) 初始化Flash设备。
(3) 初始化系统内存分配函数。
(4) 如果目标系统拥有NAND设备,则初始化NAND设备。
(5) 如果目标系统有显示设备,则初始化该类设备。
(6) 初始化相关网络设备,填写IP、MAC地址等。
(7) 进去命令循环(即整个boot的工作循环),接收用户从串口输入的命令,然后进行相应的工作。
事不宜迟,我们赶紧打开start.S:
./arch/arm/cpu/slsiap/s5p4418/start.S
/*
* armboot - Startup Code for NXPxxxx/ARM Cortex CPU-core
*/
#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <asm/system.h>
#include <linux/linkage.h>
/*
*************************************************************************
*
* Exception vectors as described in ARM reference manuals
*
* replace arm/lib/vectors.S
*
*************************************************************************
*/
.globl _stext
/*程序的全局入口,《u-boot分析 三》中u-boot.lds设置此入口地址为0x00000000*/
_stext:
b reset
/*参阅《常用ARM指令集及汇编》可知,b为跳转指令,跳转到reset函数处,reset在后面*/
/*ARM体系结构规定在上电复位后的起始位置,必须有8条连续的跳转指令,通过硬件实现。他们就是异常向量表*/
/*ldr,用于加载32bit的立即数或一个地址值到指定寄存器*/
ldr pc, _undefined_instruction /*未定义指令异常,0x04*/
ldr pc, _software_interrupt /*软中断异常,0x08*/
ldr pc, _prefetch_abort /*内存操作异常,0x0c*/
ldr pc, _data_abort /*数据异常,0x10*/
ldr pc, _not_used /*未使用,0x14*/
ldr pc, _irq /*慢速中断异常,0x18*/
ldr pc, _fiq /*快速中断异常,0x1c*/
/*.word的意思是将后边的符号所对应的32bit值赋予前面的符号*/
/*而如下的七条语句,后面的符号正好是对应的中断异常服务程序的入口地址*/
/*这七个中断服务程序位于./arch/arm/cpu/slsiap/s5p4418/vector.S*/
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: