uboot过程分析(stage1)

本文详细介绍了ARM处理器在启动过程中的关键步骤,包括从_start标签开始的上电跳转,进入不同处理器模式,关闭中断,初始化CPU状态。在reset函数中,通过mrs、msr指令切换到管理员模式,并关闭缓存、MMU、对齐检查等。接着,调用cpu_init_crit进行更深入的初始化,如清空D cache,关闭Icache,配置C1协处理器以关闭MMU和Dcache,选择异常中断向量并启用地址对齐。最后,设置堆栈指针并调用board_init_f进入C语言世界。内容涉及ARM状态寄存器、协处理器CP15的使用以及低级初始化流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

uboot/arch/arm/cpu/start.s

mrs、msr读写ARM状态寄存器指令

bit(bit clear)位清除指令

orr 位或指令

LDR{条件}   目的寄存器     <存储器地址>

1、上电跳转

start.s:

_start:
    b    reset

I、F中断禁止位,置1中断禁止

M[4:0]处理器模式ARM模式可访问的寄存器THUMB模式可访问的寄存器
0b10000用户模式PC,CPSR,R0~R14PC,CPSR,R0~R7,LR,SP
0b10001FIQ模式PC,CPSR,SPSR_fiq,R14_fiq~R8_fiq,R0~R7PC,CPSR,SPSR_fiq,LR_fiq,SP_fiq,R0~R7
0b10010IRQ模式PC,CPSR,SPSR_irq,R14_irq~R13_irq,R0~R12PC,CPSR,SPSR_irq,LR_irq,SP_irq,R0~R7
0b10011管理模式PC,CPSR,SPSR_svc,R14_svc~R13_svc,R0~R12PC,CPSR,SPSR_svc,LR_svc,SP_svc,R0~R7
0b10111中止模式PC,CPSR,SPSR_abt,R14_abt~R13_abt,R0~R12PC,CPSR,SPSR_abt,LR_abt,SP_abt,R0~R7
0b11011未定义模式PC,CPSR,SPSR_und,R14_und~R13_und,R0~R12PC,CPSR,SPSR_und,LR_und,SP_und,R0~R7
0b11111系统模式PC,CPSR,R0~R14PC,CPSR,LR,SP,R0~R74

2、关闭普通中断和快速中断,状态位清零,进入管理员模式

reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs    r0,cpsr
    bic    r0,r0,#0x1f
    orr    r0,r0,#0xd3             /*11010011*/
    msr    cpsr,r0

我们只在重新启动时进行系统关键初始化,从ram启动时不会

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit /*跳转到3*/

#endif

3、清空D cache、关闭D cache、关闭I cache、关闭MMU系统保护和ROM保护、关闭MMU、关闭对齐检查、关闭TLB(TLB是啥)、选择高端异常中断向量、使能地址对齐、使能I cache

cpu_init_crit:
在禁用缓存之前刷新D cache
mov    r0, #0

flush_dcache:
mrc    p15, 0, r15, c7, c10, 3/*清空D cache*/
bne    flush_dcache

mcr    p15, 0, r0, c8, c7, 0    /* 关闭TLB */
mcr    p15, 0, r0, c7, c5, 0    /* 关闭I cache */

/*
 * disable MMU and D cache
 * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined
 */

配置C1协处理器
mrc    p15, 0, r0, c1, c0, 0    /*读C1协处理器到R0*/
bic    r0, r0, #0x00000300    /* clear bits 9:8 (---- --RS) 关闭MMU系统保护和ROM保护*/
bic    r0, r0, #0x00000087    /* clear bits 7, 2:0 (B--- -CAM) 关闭MMU 关闭对齐检查 关闭D cache */

#ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH
    orr    r0, r0, #0x00002000    /* set bit 13 (--V- ----) 选择高端异常中断向量*/
#else
    bic    r0, r0, #0x00002000    /* clear bit 13 (--V- ----) */
#endif
    orr    r0, r0, #0x00000002    /* set bit 2 (A) Align 使能地址对齐*/
#ifndef CONFIG_SYS_ICACHE_OFF
    orr    r0, r0, #0x00001000    /* set bit 12 (I) I-Cache 使能icache*/
#endif
    mcr    p15, 0, r0, c1, c0, 0    /*把R0写进C1*/

配置完毕

mov    ip, lr      /* 将返回地址寄存器内容放到指令地址寄存器中,LRbl    cpu_init_crit 后面的地址*/
bl    lowlevel_init    /* go setup pll,mux,memory */
mov    lr, ip        /* restore link */
mov    pc, lr        /* back to my caller */ 跳回2 bl    cpu_init_crit 后面

lowlevel_init:
#ifdef CONFIG_SOC_DM644X

#else /* CONFIG_SOC_DM644X */
    mov pc, lr(相当于啥也没做,又跳回去了,LR是bl后面的地址)
#endif

4、上接1reset函数的bl    cpu_init_crit 

/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
#ifdef CONFIG_NAND_SPL /* deprecated, use instead CONFIG_SPL_BUILD disable*/
    ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR)
#else
#ifdef CONFIG_SPL_BUILD /*disable*/
    ldr    sp, =(CONFIG_SPL_STACK)
#else
    ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR)  /*设置堆栈寄存器、堆栈的偏移地址*/
#endif
#endif
    bic    sp, sp, #7 /* 8-byte alignment for ABI compliance 8字节对齐*/
    ldr    r0,=0x00000000  /*设置参数,r0-r3参数寄存器*/
    bl    board_init_f      /*设置堆栈之后,就能进入C语言世界 ,为什么C语言需要堆栈,请参考unix高级环境编程进程部分/arch/arm/lib/board.c*/

ARM协处理器CP15寄存器详解_GameIT-优快云博客_arm cp15 寄存器https://blog.youkuaiyun.com/gameit/article/details/13169405?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-2.control

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值