u-boot启动流程分析之start.s,第一阶段

文件:u-boot-1.1.6\cpu\arm920t\start.S

  1. reset部分代码详解
mrs指令语法
MRS{cond} Rd, psr
    Rd 是目标寄存器。 Rd 不能为 r15。
    psr 是下列项之一:
        APSR 任何处理器,任何模式。
        CPSR 不提倡使用的 APSR 同义词,用于调试状态,用于除
        ARMv7-M 和 ARMv6-M 之外的任何处理器。
        SPSR 用于除 ARMv7-M 和 ARMv6-M 之外的任何处理器,仅
可用于特权模式。
        Mpsr 仅用于 ARMv7-M 和 ARMv6-M 处理器。

关于arm寄存器的介绍

寄存器名字
Reg# APCS 意义
R0 a1 工作寄存器
R1 a2 "
R2 a3 "
R3 a4 "
R4 v1 必须保护
R5 v2 "
R6 v3 "
R7 v4 "
R8 v5 "
R9 v6 "
R10 sl 栈限制
R11 fp 桢指针
R12 ip 内部过程调用寄存器
R13 sp 栈指针
R14 lr 连接寄存器
R15 pc 程序计数器
The following register names are predeclared:

r0-r15 andR0-R15
a1-a4 (argument, result, or scratch registers, synonyms for r0 to r3)
v1-v8 (variable registers, r4 to r11)
sb andSB (static base, r9)
ip andIP (intra-procedure-call scratch register, r12)
sp andSP (stack pointer, r13)
lr andLR (link register, r14)
pc andPC (program counter, r15).

CPSR寄存器介绍


格式(参考文档

  1. ARM Architecture Reference Manual
    A2.5 Program status registers
  2. CPU三星S3C2440A芯片手册
    THE PROGRAM STATUS REGISTERS
    )
u-boot启动流程分析之start.s,第一阶段_第1张图片
ARM Architecture Reference Manual
u-boot启动流程分析之start.s,第一阶段_第2张图片
CPU三星S3C2440A芯片手册

mode bit各个对应值的相关参考,其他各个位均可参考ARM Architecture Reference Manual,这里就不一一列出来.

u-boot启动流程分析之start.s,第一阶段_第3张图片
The mode bits

bic指令语法
  BIC{}{S} , , 
Rd = Rn AND NOT shifter_operand
bit 位清除指令 
      格式:BIC{}{S} ,,; 
      功能:Rd=Rn AND (!op2) 用于清除寄存器Rn中的某些位,并把结果存放到目的寄存器Rd中
      例: 
        BIC R0,R0,#5 ;R0中第0位和第2位清0,其余位不变

ORR 逻辑或指令 
      格式:ORR{}{S} ,,; 
      功能:Rd=Rn OR op2 一般用于设置Rn的特定几位。
      例: 
        ORR R0,R0,#5  ;R0的第0位和第2位设置为1,其余位不变 
_start: b       reset


reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs r0,cpsr  //将cpsr寄存器的内容放到r0寄存器中
    bic r0,r0,#0x1f //将r0的bit4-bit0清零
    orr r0,r0,#0xd3//r0的bit4-bit0 = 0xd3
    msr cpsr,r0  //将cpsr寄存器赋值为r0寄存器里的内容,即设置为Supervisor模式,禁止IRQ和FIQ,运行于ARM stae
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    adr r0, _start      /* r0 <- current position of code   */
    ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */
    cmp     r0, r1                  /* don't reloc during debug         */
    blne    cpu_init_crit
#endif

接着往后看,adr指令获取_start符号的地址,因为adr是相对于pc进行计算符号的地址的,所以如果是刚上电的还没运行到sdram时PC的值是0,初始化完sdram把代码拷到sdram时是链接地址TEXT_BASE=0x33F80000.
ldr指令(这里不是伪指令ldr)是取出_TEXT_BASE处存放的内容(假如_TEXT_BASE的地址为0x10,里面存放的内容是0x11.那么使用上述指令r1 = 0x10,使用adr的话r1 = 0x10)
  那么_TEXT_BASE处存放的是什么鬼?
//定义在satrt.S开头处
_TEXT_BASE:
    .word   TEXT_BASE
那么问题来了_TEXT_BASE存放的是TEXT_BASE,那么他又等于什么

TEXT_BASE定义在
u-boot-1.1.6/board/100ask24x0/config.mk中,这里你肯定会有疑问,一个start.S源文件,一个是makefile文件.怎么联系起来的,显然肯定是有人使用了include指示符包含了这个config.mk

在/u-boot-1.1.6/config.mk中
#使用sinclude和include没有区别,手册上说是为了和别的make程序兼容
ifdef   BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk  # include board specific rules
endif

包含了之后就要使用该变量了

CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)     \
    -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE)
使用了gcc -D选项定义了一个宏TEXT_BASE其值就等于0x33F80000..就是这么联系起来的.
  所以上面那段代码可以判断程序是刚上电运行还是已经运行到sdram里面了.还是写的挺巧妙的..

进行栈的设置

stack_setup:
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CFG_MALLOC_LEN /* malloc area                      */
    sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */

初始化时钟

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl clock_init
#endif  
    ldr pc, _start_armboot

_start_armboot: .word start_armboot

你可能感兴趣的:(u-boot启动流程分析之start.s,第一阶段)