zoukankan      html  css  js  c++  java
  • uboot 代码执行顺序

    --- title: uboot 代码执行顺序 date: 2019-07-30 11:32:26 categories: tags: - uboot ---

    uboot: 2014.07

    ref : http://blog.chinaunix.net/uid-30352139-id-5128405.html

    U-boot相关文件

    boards.cfg:

    ARCH = ARM
    
    CPU = ARMv7
    
    SOC = exynos
    
    BOARD = smdkc210
    
    VENDER = samsung 
    

    files:

    Include/configs/smdkc210.h
    
    arch/$(ARCH)/cpu/$(CPU)/start.S
    
    board/$(VENDER)/$(BOARD)/smdkc210.c
    
    arch/$(ARCH)/lib/board.c
    
    arch/$(ARCH)/lib/crto.S
    
    arch/$(ARCH)/lib/relocate.S 
    

    初始化流程

    1.   start.S -> _start 
      
    2.   start.S -> reset 
      
    3.   crt0.S -> _main ==>> board.c -> board_init_f 
      
    4.   relocate.S -> relocate_code 
      
    5.   crt0.S -> here 
      
    6.   board.c -> board_init_r 
      
    7.   main.c -> main_loop 
      

    初始化实现(以ARM为例)

    《ARM Cortex-A Series Programmer’s Guide》中列出了Cortex-A系列的初始化方法(第十三章:Boot Code)。

    ARM启动时,会从异常向量表的reset异常处启动(0或0xffff0000)。对于u-boot,不需要实现所有启动流程,只需要实现几个必须的程:

    1. Initialize exception vectors.

    2. Initialize the memory system, including the MMU.

    3. Initialize core mode stacks and registers.

    4. Initialize any critical I/O devices.

    5. Call the main()application.

    代码分析

    初始化中断向量表 (Initialize exception vectors)

    .globl _start 
    _start: b    reset 
    ldr    pc, _undefined_instruction 
    ldr    pc, _software_interrupt 
    ldr    pc, _prefetch_abort 
    ldr    pc, _data_abort 
    ldr    pc, _not_used 
    ldr    pc, _irq 
    ldr    pc, _fiq 
    _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:            .word irq 
    _fiq:            .word fiq 
    _pad:            .word 0x12345678 /* now 16*4=64 */ 
    .global _end_vect 
    _end_vect: 
    .balignl
    16,0xdeadbeef
    

    禁止中断 (FIQ and IRQ), 设置CPU模式为SVC32 (Initialize core mode stacks and registers.)

    
    reset: 
    bl    save_boot_params 
    /* 
     * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 
     * except if in HYP mode already 
     */ 
    mrs    r0, cpsr 
    and    r1, r0, #0x1f        @ mask mode bits 
    teq    r1, #0x1a        @ test for HYP mode 
    bicne    r0, r0, #0x1f        @ clear all mode bits 
    orrne    r0, r0, #0x13        @ set SVC mode 
    orr    r0, r0, #0xc0        @ disable FIQ and IRQ 
    msr    cpsr,r0
    

    设置中断向量表 (Initialize exception vectors)

    /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */ 
    
    mrc    p15, 0, r0, c1, c0, 0    @ Read CP15 SCTRL Register 
    bic    r0, #CR_V        @ V = 0 
    mcr    p15, 0, r0, c1, c0, 0    @ Write CP15 SCTRL Register 
    
    /* Setvector address in CP15 VBAR register */ 
    ldr    r0, =_start 
    mcr    p15, 0, r0, c12, c0, 0    @Set VBAR 
    

    Invalidate L1 I/D cache (Initialize the memory system, including the MMU)

    ENTRY(cpu_init_cp15) 
    
    /* 
     * Invalidate L1 I/D 
     */ 
    
    mov    r0, #0            @ set up for MCR 
    mcr    p15, 0, r0, c8, c7, 0    @ invalidate TLBs 
    mcr    p15, 0, r0, c7, c5, 0    @ invalidate icache 
    mcr    p15, 0, r0, c7, c5, 6    @ invalidate BP array 
    mcr     p15, 0, r0, c7, c10, 4    @ DSB 
    mcr     p15, 0, r0, c7, c5, 4    @ ISB 
    

    禁止 MMU and caches (Initialize the memory system, including the MMU)

    /* 
     * disable MMU stuff and caches 
     */ 
    mrc    p15, 0, r0, c1, c0, 0 
    bic    r0, r0, #0x00002000    @ clear bits 13 (--V-) 
    bic    r0, r0, #0x00000007    @ clear bits 2:0 (-CAM) 
    orr    r0, r0, #0x00000002    @ set bit 1 (--A-) Align 
    orr    r0, r0, #0x00000800    @ set bit 11 (Z---) BTB 
    orr    r0, r0, #0x00001000    @ set bit 12 (I) I-cache 
    mcr    p15, 0, r0, c1, c0, 0 
    mov    pc, lr            @ back to my caller 
    

    设置C运行环境 (Initialize core mode stacks and registers.)

    ENTRY(_main) 
    
    /* 
     * Set up initial C runtime environment and call board_init_f(0). 
     */ 
    
    ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR) 
    bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */ 
    sub    sp, #GD_SIZE    /* allocate one GD above SP */ 
    bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */ 
    mov    r9, sp        /* GD is above SP */ 
    

    调用 board_init_f(0) 对串口进行初始化(Initialize any critical I/O devices)

    mov    r0, #0 
    bl    board_init_f 
    

    设置临时运行环境

    /* 
     * Set up intermediate environment (new sp and gd) and call 
     * relocate_code(addr_moni). Trick here is that we'll return 
     * 'here' but relocated. 
     */ 
    
    ldr    sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */ 
    bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */ 
    ldr    r9, [r9, #GD_BD]        /* r9 = gd->bd */ 
    sub    r9, r9, #GD_SIZE        /* new GD is below bd */ 
    

    代码重定向,保证u-boot迁入内存后能够正常运行 (Relocate the code)

    adr    lr, here 
    ldr    r0, [r9, #GD_RELOC_OFF]     /* r0 = gd->reloc_off */ 
    add    lr, lr, r0 
    
    ldr    r0, [r9, #GD_RELOCADDR]     /* r0 = gd->relocaddr */ 
    b    relocate_code 
    here: 
    

    接下来的这几步操作前面已经进行过,感觉可以去掉

    ENTRY(c_runtime_cpu_setup) 
    
    /* 
     * invalidate I-cache 
     */ 
    
    mcr     p15, 0, r0, c7, c5, 0    @ invalidate icache 
    mcr     p15, 0, r0, c7, c10, 4    @ DSB 
    mcr     p15, 0, r0, c7, c5, 4    @ ISB 
    

    由于u-boot经过了重定向,代码位置发生了改变,所以这里需要重新设置VBAR寄存器。

    实际的代码如下: ldr r0, [pc, #736]

    利用PC保证加载的是当前地址,而不是u-boot在ROM中的地址。

    
    /* 
     * Move vector table 
     */ 
    
    /* Set vector address in CP15 VBAR register */ 
    ldr     r0, =_start 
    mcr     p15, 0, r0, c12, c0, 0  @Set VBAR 
    

    把 .bss 段清零

    ldr    r0,
    =__bss_start    /* This is auto-relocated!   */ 
    
    ldr    r1, =__bss_end    /* this is auto-relocated! */ 
    mov    r2, #0x00000000    /* prepare zero to clear BSS */ 
    clbss_l:cmp    r0, r1        /* while not at end of BSS */ 
    strlo    r2, [r0]        /* clear 32-bit BSS word */ 
    addlo    r0, r0, #4        /* move to next */ 
    blo    clbss_l 
    

    调用 board_init_r(gd_t *id, ulong dest_addr它会初始化网口设备,然后调用main_loop进入u-boot控制台。(Call the main()application)

    /* call board_init_r(gd_t *id, ulong dest_addr) */ 
    mov     r0, r9                  /* gd_t */ 
    ldr    r1, [r9, #GD_RELOCADDR]    /* dest_addr */ 
    /* call board_init_r */ 
    ldr    pc, =board_init_r    /* this is auto-relocated! */ 
    

    board_init_f

    下面是board_init_f执行的操作:

    function comments
    arch_cpu_init Do nothing on smdkc210
    timer_init Do nothing on smdkc210
    env_init 初始化环境变量, 实际上是把default_environment设置到gd->env_addr. default_environment是一个字符串数组,每一个字符串用一个宏表示,我们通过在“include/configs/smdkc210.h”定义这些宏的方式设置环境变量。
    init_baudrate 设置波特率,其实它来自于 gd->baud.
    serial_init 调用串口初始化函数
    dram_init 设置RAM位置与大小
    Set gd. The most 设置gd表,用于保存配置
  • 相关阅读:
    python主要探索函数
    数据分析分析方法
    监控hadoop任务结果shell脚本
    shell编程
    hadoop介绍
    数据探索
    Python数据分析简介
    数据挖掘基础篇之整体思路
    sqlAlchemy
    python md5 加密
  • 原文地址:https://www.cnblogs.com/schips/p/13128992.html
Copyright © 2011-2022 走看看