TA的每日心情 | 开心 2024-11-20 21:23 |
---|
签到天数: 597 天 连续签到: 1 天 [LV.9]以坛为家II
|
本贴所有源码同步到 github
源码位于:https://github.com/robe-zhang/mys_y6ulx/tree/master/MYiR-iMX-uboot
分析位于:https://github.com/robe-zhang/mys_y6ulx/blob/master/note_robe/note_uboot/note_uboot_code
整个 uboot 项目源码分析注释:
- # ============================== 11111111
- (arch/arm/lib/vectors.S)
- _start: uboot 入口,中断向量表
- #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
- .word CONFIG_SYS_DV_NOR_BOOT_CFG
- #endif
- 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
-
- .globl _undefined_instruction
- .globl _software_interrupt
- .globl _prefetch_abort
- .globl _data_abort
- .globl _not_used
- .globl _irq
- .globl _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
- .balignl 16,0xdeadbeef
- irq stack frame 宏定义
- 中断处理函数,汇编处理,c 处理函数在 arch/arm/lib/interrupts.c
- # ============================== 22222222
- (arch/arm/cpu/armv7/start.o(uboot/u-boot.lds))
- reset:
- /* Allow the board to save important registers */
- b save_boot_params
- save_boot_params_ret:
- /*
- * 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 设置 SVC 模式,关中断
- #ifndef CONFIG_SKIP_LOWLEVEL_INIT
- bl cpu_init_cp15 协处理器 cp15 初始化,mmu,cache,TLBs 初始化,下面详细解析
- bl cpu_init_crit 系统复位初始化,pll 外设时钟初始化 ============ 此部分有 C 代码,设置了初始栈指针
- #endif
- bl _main uboot 主体部分,下面详细解析
- # ============================== 33333333
- (arch\arm\cpu\armv7\start.S)
- ENTRY(save_boot_params)
- b save_boot_params_ret @ back to my caller 用户自己可重新定义 save_boot_params 函数,实现功能
- ENDPROC(save_boot_params)
- .weak save_boot_params
- # ============================== 44444444
- (arch\arm\cpu\armv7\start.S)
- ENTRY(cpu_init_cp15)
- /*
- * Invalidate L1 I/D
- */
- mov r0, #0 @ set up for MCR 关闭 L1 i-cache,d-cache
- 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
- /*
- * disable MMU stuff and caches
- */
- mrc p15, 0, r0, c1, c0, 0 关闭 mmu,caches
- 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
- #ifdef CONFIG_SYS_ICACHE_OFF
- bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
- #else
- orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
- #endif
- mcr p15, 0, r0, c1, c0, 0
- #ifdef CONFIG_ARM_ERRATA_716044 errata 处理
- mrc p15, 0, r0, c1, c0, 0 @ read system control register
- orr r0, r0, #1 << 11 @ set bit #11
- mcr p15, 0, r0, c1, c0, 0 @ write system control register
- #endif
- #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
- mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
- orr r0, r0, #1 << 4 @ set bit #4
- mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
- #endif
- #ifdef CONFIG_ARM_ERRATA_743622
- mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
- orr r0, r0, #1 << 6 @ set bit #6
- mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
- #endif
- #ifdef CONFIG_ARM_ERRATA_751472
- mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
- orr r0, r0, #1 << 11 @ set bit #11
- mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
- #endif
- #ifdef CONFIG_ARM_ERRATA_761320
- mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
- orr r0, r0, #1 << 21 @ set bit #21
- mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
- #endif
- #ifdef CONFIG_ARM_ERRATA_845369
- mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
- orr r0, r0, #1 << 22 @ set bit #22
- mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
- #endif
- mov r5, lr @ Store my Caller cpu 版本相关的 errata 处理
- mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
- mov r3, r1, lsr #20 @ get variant field
- and r3, r3, #0xf @ r3 has CPU variant
- and r4, r1, #0xf @ r4 has CPU revision
- mov r2, r3, lsl #4 @ shift variant field for combined value
- orr r2, r4, r2 @ r2 has combined CPU variant + revision
- #ifdef CONFIG_ARM_ERRATA_798870
- cmp r2, #0x30 @ Applies to lower than R3p0
- bge skip_errata_798870 @ skip if not affected rev
- cmp r2, #0x20 @ Applies to including and above R2p0
- blt skip_errata_798870 @ skip if not affected rev
- mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
- orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
- push {r1-r5} @ Save the cpu info registers
- bl v7_arch_cp15_set_l2aux_ctrl
- isb @ Recommended ISB after l2actlr update
- pop {r1-r5} @ Restore the cpu info - fall through
- skip_errata_798870:
- #endif
- #ifdef CONFIG_ARM_ERRATA_801819
- cmp r2, #0x24 @ Applies to lt including R2p4
- bgt skip_errata_801819 @ skip if not affected rev
- cmp r2, #0x20 @ Applies to including and above R2p0
- blt skip_errata_801819 @ skip if not affected rev
- mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg
- and r0, r0, #1 << 3 @ check REVIDR[3]
- cmp r0, #1 << 3
- beq skip_errata_801819 @ skip erratum if REVIDR[3] is set
- mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
- orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate
- @ lines allocate in the L1 or L2 cache.
- orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate
- @ lines allocate in the L1 cache.
- push {r1-r5} @ Save the cpu info registers
- bl v7_arch_cp15_set_acr
- pop {r1-r5} @ Restore the cpu info - fall through
- skip_errata_801819:
- #endif
- #ifdef CONFIG_ARM_ERRATA_454179
- cmp r2, #0x21 @ Only on < r2p1
- bge skip_errata_454179
- mrc p15, 0, r0, c1, c0, 1 @ Read ACR
- orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits
- push {r1-r5} @ Save the cpu info registers
- bl v7_arch_cp15_set_acr
- pop {r1-r5} @ Restore the cpu info - fall through
- skip_errata_454179:
- #endif
- #ifdef CONFIG_ARM_ERRATA_430973
- cmp r2, #0x21 @ Only on < r2p1
- bge skip_errata_430973
- mrc p15, 0, r0, c1, c0, 1 @ Read ACR
- orr r0, r0, #(0x1 << 6) @ Set IBE bit
- push {r1-r5} @ Save the cpu info registers
- bl v7_arch_cp15_set_acr
- pop {r1-r5} @ Restore the cpu info - fall through
- skip_errata_430973:
- #endif
- #ifdef CONFIG_ARM_ERRATA_621766
- cmp r2, #0x21 @ Only on < r2p1
- bge skip_errata_621766
- mrc p15, 0, r0, c1, c0, 1 @ Read ACR
- orr r0, r0, #(0x1 << 5) @ Set L1NEON bit
- push {r1-r5} @ Save the cpu info registers
- bl v7_arch_cp15_set_acr
- pop {r1-r5} @ Restore the cpu info - fall through
- skip_errata_621766:
- #endif
- mov pc, r5 @ back to my caller 返回
- ENDPROC(cpu_init_cp15)
- # ============================== 55555555
- (arch\arm\cpu\armv7\start.S)
- #ifndef CONFIG_SKIP_LOWLEVEL_INIT
- /*************************************************************************
- *
- * CPU_init_critical registers
- *
- * setup important registers
- * setup memory timing
- *
- *************************************************************************/
- ENTRY(cpu_init_crit)
- /*
- * Jump to board specific initialization...
- * The Mask ROM will have already initialized
- * basic memory. Go here to bump up clock rate and handle
- * wake up conditions.
- */
- b lowlevel_init @ go setup pll,mux,memory
- ENDPROC(cpu_init_crit)
- #endif
- # ============================== 55555555.11111111
- (arch\arm\cpu\armv7\lowlevel_init.S)
- ENTRY(lowlevel_init)
- /*
- * Setup a temporary stack. Global data is not available yet.
- */
- ldr sp, =CONFIG_SYS_INIT_SP_ADDR 设置临时栈指针 CONFIG_SYS_INIT_SP_ADDR
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- #ifdef CONFIG_SPL_DM
- mov r9, #0
- #else
- /*
- * Set up global data for boards that still need it. This will be
- * removed soon.
- */
- #ifdef CONFIG_SPL_BUILD
- ldr r9, =gdata
- #else
- sub sp, sp, #GD_SIZE 预留 gdata 内存 GD_SIZE
- bic sp, sp, #7
- mov r9, sp
- #endif
- #endif
- /*
- * Save the old lr(passed in ip) and the current lr to stack
- */
- push {ip, lr}
- /*
- * Call the very early init function. This should do only the
- * absolute bare minimum to get started. It should not:
- *
- * - set up DRAM
- * - use global_data
- * - clear BSS
- * - try to start a console
- *
- * For boards with SPL this should be empty since SPL can do all of
- * this init in the SPL board_init_f() function which is called
- * immediately after this.
- */
- bl s_init 系统复位初始化,pll 外设时钟初始化 / anatop(SRC/system reset control),ccm 等,代码位于 (arch\arm\cpu\armv7\mx6\soc.c)
- 芯片寄存器定义位于 (arch\arm\include\asm\arch-mx6\imx-regs.h)
- pop {ip, pc} 弹栈,返回
- ENDPROC(lowlevel_init)
- # ==============================
- void s_init(void)
- {
- struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
- struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
- u32 mask480;
- u32 mask528;
- u32 reg, periph1, periph2;
- if (is_cpu_type(MXC_CPU_MX6SX) || is_cpu_type(MXC_CPU_MX6UL) ||
- is_cpu_type(MXC_CPU_MX6ULL))
- return;
- /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
- * to make sure PFD is working right, otherwise, PFDs may
- * not output clock after reset, MX6DL and MX6SL have added 396M pfd
- * workaround in ROM code, as bus clock need it
- */
- mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
- ANATOP_PFD_CLKGATE_MASK(1) |
- ANATOP_PFD_CLKGATE_MASK(2) |
- ANATOP_PFD_CLKGATE_MASK(3);
- mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
- ANATOP_PFD_CLKGATE_MASK(3);
- reg = readl(&ccm->cbcmr);
- periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
- >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
- periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
- >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
- /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
- if ((periph2 != 0x2) && (periph1 != 0x2))
- mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
- if ((periph2 != 0x1) && (periph1 != 0x1) &&
- (periph2 != 0x3) && (periph1 != 0x3))
- mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
- writel(mask480, &anatop->pfd_480_set);
- writel(mask528, &anatop->pfd_528_set);
- writel(mask480, &anatop->pfd_480_clr);
- writel(mask528, &anatop->pfd_528_clr);
- }
- # ============================== 66666666
- (arch\arm\lib\crt0.S)
- ENTRY(_main)
- /*
- * Set up initial C runtime environment and call board_init_f(0).
- */
- #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 设置栈指针 1111
- ldr sp, =(CONFIG_SPL_STACK)
- #else
- ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
- #endif
- #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
- mov r3, sp
- bic r3, r3, #7
- mov sp, r3
- #else
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- #endif
- mov r0, sp
- bl board_init_f_alloc_reserve board_init_f_alloc_reserve 2222 预留 堆空间 和 global_data 内存空间
- mov sp, r0
- /* set up gd here, outside any C code */
- mov r9, r0
- bl board_init_f_init_reserve board_init_f_init_reserve 3333 16字节对齐,从上下为 堆空间/gd->malloc_base,global_data 空间
- mov r0, #0
- bl board_init_f board_init_f 4444 最后调用 init_sequence_f
- #if ! defined(CONFIG_SPL_BUILD)
- /*
- * 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 */ 设置栈指针,对齐
- #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
- mov r3, sp
- bic r3, r3, #7
- mov sp, r3
- #else
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- #endif
- ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ 分配新 GD 内存,设置 r9 为新 GD 地址
- sub r9, r9, #GD_SIZE /* new GD is below bd */
- adr lr, here
- ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ 设置 relocate 后的 here 代码地址
- add lr, lr, r0
- #if defined(CONFIG_CPU_V7M)
- orr lr, #1 /* As required by Thumb-only */
- #endif
- ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ 设置 gd->relocaddr 指针后
- b relocate_code relocate_code 5555 relocate __image_copy 段 __rel_dyn 段
- here:
- /*
- * now relocate vectors
- */
- bl relocate_vectors relocate_vectors 6666 relocate 中断向量,并设置 VBAR
- /* Set up final (full) environment */
- bl c_runtime_cpu_setup /* we still call old routine here */ c_runtime_cpu_setup 7777 关闭 I-cache 后返回
- #endif
- #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
- # ifdef CONFIG_SPL_BUILD
- /* Use a DRAM stack for the rest of SPL, if requested */
- bl spl_relocate_stack_gd spl_relocate_stack_gd relocate 堆空间和 gd
- cmp r0, #0
- movne sp, r0
- movne r9, r0
- # endif
- ldr r0, =__bss_start /* this is auto-relocated! */
- #ifdef CONFIG_USE_ARCH_MEMSET
- ldr r3, =__bss_end /* this is auto-relocated! */
- mov r1, #0x00000000 /* prepare zero to clear BSS */ 清空 bss 空间
- subs r2, r3, r0 /* r2 = memset len */
- bl memset
- #else
- 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 */
- #if defined(CONFIG_CPU_V7M)
- itt lo
- #endif
- strlo r2, [r0] /* clear 32-bit BSS word */
- addlo r0, r0, #4 /* move to next */
- blo clbss_l
- #endif
- #if ! defined(CONFIG_SPL_BUILD)
- bl coloured_LED_init coloured_LED_init 板上初始化指示灯
- bl red_led_on red_led_on
- #endif
- /* 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 */
- #if defined(CONFIG_SYS_THUMB_BUILD)
- ldr lr, =board_init_r /* this is auto-relocated! */
- bx lr
- #else
- ldr pc, =board_init_r /* this is auto-relocated! */ board_init_r 8888 再次调用 board_init_r(new gd, gd->relocaddr)
- #endif
- /* we should not return here. */
- #endif
- ENDPROC(_main)
- # ======================================================================================================================================================
- # ============================== 1111
- (arch\arm\include\asm\arch-mx6\imx-regs.h)
- (include\configs\mys_imx6ull.h)
- CONFIG_SYS_INIT_SP_ADDR="(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)" IRAM 地址及大小,芯片级
- CONFIG_SYS_INIT_RAM_ADDR="IRAM_BASE_ADDR"
- CONFIG_SYS_INIT_SP_OFFSET="(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)"
- CONFIG_SYS_INIT_RAM_SIZE="IRAM_SIZE"
- # ============================== 2222
- (common\init\board_init.c)
- ulong board_init_f_alloc_reserve(ulong top)
- {
- /* Reserve early malloc arena */
- #if defined(CONFIG_SYS_MALLOC_F)
- top -= CONFIG_SYS_MALLOC_F_LEN; 预留堆空间
- #endif
- /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */
- top = rounddown(top-sizeof(struct global_data), 16); 预留 global_data 空间,并且对齐
- return top;
- }
- # ============================== 3333
- void board_init_f_init_reserve(ulong base)
- {
- struct global_data *gd_ptr;
- #ifndef _USE_MEMCPY
- int *ptr;
- #endif
- /*
- * clear GD entirely and set it up.
- * Use gd_ptr, as gd may not be properly set yet.
- */
- gd_ptr = (struct global_data *)base;
- /* zero the area */
- #ifdef _USE_MEMCPY 清零 gdata 空间
- memset(gd_ptr, '\0', sizeof(*gd));
- #else
- for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); )
- *ptr++ = 0;
- #endif
- /* set GD unless architecture did it already */
- #if !defined(CONFIG_ARM)
- arch_setup_gd(gd_ptr);
- #endif
- /* next alloc will be higher by one GD plus 16-byte alignment */
- base += roundup(sizeof(struct global_data), 16); 对齐,设置堆指针
- /*
- * record early malloc arena start.
- * Use gd as it is now properly set for all architectures.
- */
- #if defined(CONFIG_SYS_MALLOC_F)
- /* go down one 'early malloc arena' */
- gd->malloc_base = base;
- /* next alloc will be higher by one 'early malloc arena' size */
- base += CONFIG_SYS_MALLOC_F_LEN;
- #endif
- }
- # ============================== 4444
- (uboot\common\board_f.c)
- void board_init_f(ulong boot_flags)
- {
- #ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
- /*
- * For some archtectures, global data is initialized and used before
- * calling this function. The data should be preserved. For others,
- * CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack
- * here to host global data until relocation.
- */
- gd_t data;
- gd = &data;
- /*
- * Clear global data before it is accessed at debug print
- * in initcall_run_list. Otherwise the debug print probably
- * get the wrong vaule of gd->have_console.
- */
- zero_global_data(); 清零 global_data 内存
- #endif
- gd->flags = boot_flags;
- gd->have_console = 0; 还没有 console 可用 / gd->have_console = 0;
- if (initcall_run_list(init_sequence_f)) 初始化 init_sequence_f
- hang();
- #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
- !defined(CONFIG_EFI_APP)
- /* NOTREACHED - jump_to_copy() does not return */
- hang();
- #endif
- }
- // -----------------------------------
- (uboot\common\board_f.c)
- static init_fnc_t init_sequence_f[] = {
- #ifdef CONFIG_SANDBOX
- setup_ram_buf,
- #endif
- setup_mon_len, 设置 gd->mon_len 的值 / = (ulong)&__bss_end - (ulong)_start;
- #ifdef CONFIG_OF_CONTROL
- fdtdec_setup,
- #endif
- #ifdef CONFIG_TRACE
- trace_early_init,
- #endif
- initf_malloc, 设置堆指针和堆大小: gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; gd->malloc_ptr = 0;
- initf_console_record,
- #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
- /* TODO: can this go into arch_cpu_init()? */
- probecpu,
- #endif
- #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
- x86_fsp_init,
- #endif
- arch_cpu_init, /* basic arch cpu dependent setup */
- init_aips(); // aips 寄存器 reset(恢复到开机默认值)
- clear_mmdc_ch_mask // 清除 mmdc/DDR ch mask 位
- init_bandgap // 初始化基准频率/bandgap
- imx_set_wdog_powerdown // 关闭 wdog
- mxs_dma_init // apbh dma 初始化
- init_src // 初始化 src,热重启
-
- initf_dm, dm 初始化
- arch_cpu_init_dm,
- mark_bootstage, /* need timer, go after init dm */ 设置 bootstage "board_init_f"
- #if defined(CONFIG_BOARD_EARLY_INIT_F)
- board_early_init_f, 初始化 uart pin 脚
- #endif
- /* TODO: can any of this go into arch_cpu_init()? */
- #if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
- get_clocks, /* get CPU and bus clocks (etc.) */
- #if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
- && !defined(CONFIG_TQM885D)
- adjust_sdram_tbs_8xx,
- #endif
- /* TODO: can we rename this to timer_init()? */
- init_timebase,
- #endif
- #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
- defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \
- defined(CONFIG_SPARC)
- timer_init, /* initialize timer */ 初始化 GPT1,并启用,设置 gd->arch.tbl = __raw_readl(&cur_gpt->counter); gd->arch.tbu = 0;
- #endif
- #ifdef CONFIG_SYS_ALLOC_DPRAM
- #if !defined(CONFIG_CPM2)
- dpram_init,
- #endif
- #endif
- #if defined(CONFIG_BOARD_POSTCLK_INIT)
- board_postclk_init, 设置 ldo 电压
- #endif
- #if defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
- get_clocks, 设置 SD 时钟频率 / gd->arch.sdhc_clk
- #endif
- env_init, /* initialize environment */ 设置 env 地址和有效性 / gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1;
- #if defined(CONFIG_8xx_CPUCLK_DEFAULT)
- /* get CPU and bus clocks according to the environment variable */
- get_clocks_866,
- /* adjust sdram refresh rate according to the new clock */
- sdram_adjust_866,
- init_timebase,
- #endif
- init_baud_rate, /* initialze baudrate settings */ 设置串口波特率,(从环境变量获取) / gd->baudrate
- serial_init, /* serial communications setup */ 调用驱动,串口初始化,并添加 flag / gd->flag |= GD_FLG_SERIAL_READY
- console_init_f, /* stage 1 init of console */ console 已经可用,修改 flag,并输出信息 / gd->have_console = 1; gd->flags |= GD_FLG_SILENT;
- #ifdef CONFIG_SANDBOX
- sandbox_early_getopt_check,
- #endif
- #ifdef CONFIG_OF_CONTROL
- fdtdec_prepare_fdt,
- #endif
- display_options, /* say that we are here */ 输出 "U-Boot 2016.03 (Jun 05 2019 - 01:45:20 +0800)"
- display_text_info, /* show debugging info if required */ 输出 debug 信息(需要对应 DEBUG 宏)
- #if defined(CONFIG_MPC8260)
- prt_8260_rsr,
- prt_8260_clks,
- #endif /* CONFIG_MPC8260 */
- #if defined(CONFIG_MPC83xx)
- prt_83xx_rsr,
- #endif
- #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
- checkcpu,
- #endif
- print_cpuinfo, /* display cpu info (and speed) */ 输出 cpu 信息
- #if defined(CONFIG_MPC5xxx)
- prt_mpc5xxx_clks,
- #endif /* CONFIG_MPC5xxx */
- #if defined(CONFIG_DISPLAY_BOARDINFO)
- show_board_info, 输出 board 信息,调用 checkboard()
- #endif
- INIT_FUNC_WATCHDOG_INIT 初始化 watchdog
- #if defined(CONFIG_MISC_INIT_F)
- misc_init_f,
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
- init_func_i2c, 初始化 iic 控制器
- #endif
- #if defined(CONFIG_HARD_SPI)
- init_func_spi,
- #endif
- announce_dram_init, 输出 DRAM
- /* TODO: unify all these dram functions? */
- #if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_NDS32) || \
- defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32)
- dram_init, /* configure available RAM banks */ 初始化 DRAM (测试 DRAM 大小,获取 gd->ram_size) (DCD 数据初始化 DRAM,什么原理,ROM 如何实现的) =============== get help form NXP
- #endif
- #if defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_M68K)
- init_func_ram,
- #endif
- #ifdef CONFIG_POST
- post_init_f,
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #if defined(CONFIG_SYS_DRAM_TEST)
- testdram,
- #endif /* CONFIG_SYS_DRAM_TEST */
- INIT_FUNC_WATCHDOG_RESET
- #ifdef CONFIG_POST
- init_post,
- #endif
- INIT_FUNC_WATCHDOG_RESET
- /*
- * Now that we have DRAM mapped and working, we can
- * relocate the code and continue running from DRAM.
- *
- * Reserve memory at end of RAM for (top down in that order):
- * - area that won't get touched by U-Boot and Linux (optional)
- * - kernel log buffer
- * - protected RAM
- * - LCD framebuffer
- * - monitor code
- * - board info struct
- */
- setup_dest_addr, 设置 gd->ram_size,gd->ram_top,gd->relocaddr
- #if defined(CONFIG_BLACKFIN)
- /* Blackfin u-boot monitor should be on top of the ram */
- reserve_uboot,
- #endif
- #if defined(CONFIG_SPARC)
- reserve_prom,
- #endif
- #if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
- reserve_logbuffer, 保留 logbuffer 内存
- #endif
- #ifdef CONFIG_PRAM
- reserve_pram, 保留 pram 内存
- #endif
- reserve_round_4k,
- #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
- defined(CONFIG_ARM)
- reserve_mmu, 保留 tlb 内存(gd->arch.tlb_size, gd->arch.tlb_addr)
- #endif
- #ifdef CONFIG_DM_VIDEO
- reserve_video, 保留 video 内存 (gd->video_top ,gd->video_bottom)
- #else
- # ifdef CONFIG_LCD
- reserve_lcd, 保留 gd->fb_base 内存
- # endif
- /* TODO: Why the dependency on CONFIG_8xx? */
- # if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
- !defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
- !defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
- reserve_legacy_video,
- # endif
- #endif /* CONFIG_DM_VIDEO */
- reserve_trace, 保留 gd->trace_buff 内存
- #if !defined(CONFIG_BLACKFIN)
- reserve_uboot, 保留 uboot 内存
- #endif
- #ifndef CONFIG_SPL_BUILD
- reserve_malloc, 保留 堆 空间
- reserve_board, 保留 board 内存(gd->bd)
- #endif
- setup_machine, 设置 machine type (gd->bd->bi_arch_number)
- reserve_global_data, 保留 global_data 内存 (gd->new_gd)
- reserve_fdt, 保留 fdt 内存
- reserve_arch,
- reserve_stacks, 保留 gd->irq_sp
- setup_dram_config, 设置 gd->bd->bi_dram[0].start,gd->bd->bi_dram[0].size
- show_dram_config, 输出 dram bank 信息
- #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
- setup_board_part1,
- #endif
- #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
- INIT_FUNC_WATCHDOG_RESET
- setup_board_part2,
- #endif
- display_new_sp, 输出 new_sp 信息
- #ifdef CONFIG_SYS_EXTBDINFO
- setup_board_extra,
- #endif
- INIT_FUNC_WATCHDOG_RESET 看门狗复位
- reloc_fdt, relocate fdt
- setup_reloc, 设置新 gd->reloc_off,并且复制 gd 到 gd->new_gd
- #if defined(CONFIG_X86) || defined(CONFIG_ARC)
- copy_uboot_to_ram,
- clear_bss,
- do_elf_reloc_fixups,
- #endif
- #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
- jump_to_copy,
- #endif
- NULL,
- };
- # ============================== 5555
- (arch\arm\lib\relocate.S)
- ENTRY(relocate_code)
- ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ relocate __image_copy 段
- subs r4, r0, r1 /* r4 <- relocation offset */
- beq relocate_done /* skip relocation */
- ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */
- copy_loop:
- ldmia r1!, {r10-r11} /* copy from source address [r1] */
- stmia r0!, {r10-r11} /* copy to target address [r0] */
- cmp r1, r2 /* until source end address [r2] */
- blo copy_loop
- /*
- * fix .rel.dyn relocations
- */
- ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ relocate __rel_dyn 段
- ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */
- fixloop:
- ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */
- and r1, r1, #0xff
- cmp r1, #23 /* relative fixup? */
- bne fixnext
- /* relative fix: increase location by offset */
- add r0, r0, r4
- ldr r1, [r0]
- add r1, r1, r4
- str r1, [r0]
- fixnext:
- cmp r2, r3
- blo fixloop
- relocate_done:
- #ifdef __XSCALE__
- /*
- * On xscale, icache must be invalidated and write buffers drained,
- * even with cache disabled - 4.2.7 of xscale core developer's manual
- */
- mcr p15, 0, r0, c7, c7, 0 /* invalidate icache */
- mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
- #endif
- /* ARMv4- don't know bx lr but the assembler fails to see that */
- #ifdef __ARM_ARCH_4__
- mov pc, lr
- #else
- bx lr
- #endif
- ENDPROC(relocate_code)
- # ============================== 6666
- ENTRY(relocate_vectors)
- #ifdef CONFIG_CPU_V7M
- /*
- * On ARMv7-M we only have to write the new vector address
- * to VTOR register.
- */
- ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
- ldr r1, =V7M_SCB_BASE
- str r0, [r1, V7M_SCB_VTOR]
- #else
- #ifdef CONFIG_HAS_VBAR
- /*
- * If the ARM processor has the security extensions,
- * use VBAR to relocate the exception vectors.
- */
- ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ relocate 中断向量,并设置 VBAR
- mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
- #else
- /*
- * Copy the relocated exception vectors to the
- * correct address
- * CP15 c1 V bit gives us the location of the vectors:
- * 0x00000000 or 0xFFFF0000.
- */
- ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
- mrc p15, 0, r2, c1, c0, 0 /* V bit (bit[13]) in CP15 c1 */
- ands r2, r2, #(1 << 13)
- ldreq r1, =0x00000000 /* If V=0 */
- ldrne r1, =0xFFFF0000 /* If V=1 */
- ldmia r0!, {r2-r8,r10}
- stmia r1!, {r2-r8,r10}
- ldmia r0!, {r2-r8,r10}
- stmia r1!, {r2-r8,r10}
- #endif
- #endif
- bx lr
- ENDPROC(relocate_vectors)
- # ============================== 7777
- ENTRY(c_runtime_cpu_setup)
- /*
- * If I-cache is enabled invalidate it
- */
- #ifndef CONFIG_SYS_ICACHE_OFF
- 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
- #endif
- bx lr
- ENDPROC(c_runtime_cpu_setup)
- # ============================== 8888
- init_fnc_t init_sequence_r[] = {
- initr_trace,
- initr_reloc, 完全 relocate 代码 / gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
- /* TODO: could x86/PPC have this also perhaps? */
- #ifdef CONFIG_ARM
- initr_caches, 关闭 dcache,再打开 dcache,使能 OCRAM,RAM
- /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
- * A temporary mapping of IFC high region is since removed,
- * so environmental variables in NOR flash is not availble
- * until board_init() is called below to remap IFC to high
- * region.
- */
- #endif
- initr_reloc_global_data, monitor_flash_len = _end - __image_copy_start;
- #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
- initr_unlock_ram_in_cache,
- #endif
- initr_barrier,
- initr_malloc, malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;
- initr_console_record,
- #ifdef CONFIG_SYS_NONCACHED_MEMORY
- initr_noncached, 预留 mmu section
- #endif
- bootstage_relocate, relocate bootstage 分配空间,添加名字
- #ifdef CONFIG_DM
- initr_dm, 保留旧 dm_root, 初始化新 dm_root, gd->dm_root_f = gd->dm_root;gd->dm_root = NULL;
- #endif
- initr_bootstage, 添加 bootstage records
- #if defined(CONFIG_ARM) || defined(CONFIG_NDS32)
- board_init, /* Setup chipselects */
- #endif
- /*
- * TODO: printing of the clock inforamtion of the board is now
- * implemented as part of bdinfo command. Currently only support for
- * davinci SOC's is added. Remove this check once all the board
- * implement this.
- */
- #ifdef CONFIG_CLOCKS
- set_cpu_clk_info, /* Setup clock information */
- #endif
- stdio_init_tables, 初始化(stdio_dev) devs->list
- initr_serial, 注册串口驱动
- initr_announce, 打印信息 "Now running in RAM - U-Boot at: %08lx\n"
- INIT_FUNC_WATCHDOG_RESET
- #ifdef CONFIG_NEEDS_MANUAL_RELOC
- initr_manual_reloc_cmdtable, reloc cmdtable,reloc 之前不做
- #endif
- #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
- initr_trap,
- #endif
- #ifdef CONFIG_ADDR_MAP
- initr_addr_map,
- #endif
- #if defined(CONFIG_BOARD_EARLY_INIT_R)
- board_early_init_r,
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #ifdef CONFIG_LOGBUFFER
- initr_logbuffer, sdram 最顶部设置 logbuffer
- #endif
- #ifdef CONFIG_POST
- initr_post_backlog, post_backlog 测试
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #ifdef CONFIG_SYS_DELAYED_ICACHE
- initr_icache_enable,
- #endif
- #if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
- /*
- * Do early PCI configuration _before_ the flash gets initialised,
- * because PCU ressources are crucial for flash access on some boards.
- */
- initr_pci,
- #endif
- #ifdef CONFIG_WINBOND_83C553
- initr_w83c553f,
- #endif
- #ifdef CONFIG_ARCH_EARLY_INIT_R
- arch_early_init_r,
- #endif
- power_init_board, pmic 初始化
- #ifndef CONFIG_SYS_NO_FLASH
- initr_flash, 初始化 flash ,设置 gd->bd 的 bi_flashstart, bi_flashsize, bi_flashoffset
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) || \
- defined(CONFIG_SPARC)
- /* initialize higher level parts of CPU like time base and timers */
- cpu_init_r,
- #endif
- #ifdef CONFIG_PPC
- initr_spi,
- #endif
- #ifdef CONFIG_CMD_NAND
- initr_nand, 初始化 nand
- #endif
- #ifdef CONFIG_CMD_ONENAND
- initr_onenand,
- #endif
- #ifdef CONFIG_GENERIC_MMC
- initr_mmc, 初始化 mmc
- #endif
- #ifdef CONFIG_HAS_DATAFLASH
- initr_dataflash,
- #endif
- initr_env, 初始化 env
- #ifdef CONFIG_SYS_BOOTPARAMS_LEN
- initr_malloc_bootparams, 分配 bootparams 内存,赋值给 gd->bd->bi_boot_params
- #endif
- INIT_FUNC_WATCHDOG_RESET
- initr_secondary_cpu,
- #if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
- mac_read_from_eeprom, 读取 eeprom 中的 mac 地址
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
- /*
- * Do pci configuration
- */
- initr_pci,
- #endif
- stdio_add_devices, 设备初始化,调用驱动/common
- keyboard 初始化, IIC 初始化,LCD 初始化,logbuff 驱动,串口驱动,usb tty 驱动,nc/output 驱动,jtag 驱动注册
-
- initr_jumptable, 分配内存,赋值给 gd->jt
- #ifdef CONFIG_API
- initr_api, api 驱动初始化
- #endif
- console_init_r, /* fully init console as a device */ 初始化控制台 console
- #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
- show_board_info,
- #endif
- #ifdef CONFIG_ARCH_MISC_INIT
- arch_misc_init, /* miscellaneous arch-dependent init */
- #endif
- #ifdef CONFIG_MISC_INIT_R
- misc_init_r, /* miscellaneous platform-dependent init */
- #endif
- INIT_FUNC_WATCHDOG_RESET
- #ifdef CONFIG_CMD_KGDB
- initr_kgdb, kgdb 初始化
- #endif
- interrupt_init, 设置中断栈指针
- #if defined(CONFIG_ARM) || defined(CONFIG_AVR32)
- initr_enable_interrupts, 开启中断
- #endif
- #if defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || defined(CONFIG_M68K)
- timer_init, /* initialize timer */
- #endif
- #if defined(CONFIG_STATUS_LED)
- initr_status_led, led 初始化
- #endif
- /* PPC has a udelay(20) here dating from 2002. Why? */
- #ifdef CONFIG_CMD_NET
- initr_ethaddr, 从环境变量获取 ethaddr 设置 gd->bd->bi_enetaddr
- #endif
- #ifdef CONFIG_BOARD_LATE_INIT
- board_late_init, 设置环境变量 board_name, board_ver, 设置环境变量 mmcdev,mmcroot
- #endif
- #ifdef CONFIG_FSL_FASTBOOT
- initr_fastboot_setup,
- #endif
- #if defined(CONFIG_CMD_AMBAPP)
- ambapp_init_reloc,
- #if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
- initr_ambapp_print,
- #endif
- #endif
- #ifdef CONFIG_CMD_SCSI
- INIT_FUNC_WATCHDOG_RESET
- initr_scsi,
- #endif
- #ifdef CONFIG_CMD_DOC
- INIT_FUNC_WATCHDOG_RESET
- initr_doc,
- #endif
- #ifdef CONFIG_BITBANGMII
- initr_bbmii, bbmii 初始化
- #endif
- #ifdef CONFIG_CMD_NET
- INIT_FUNC_WATCHDOG_RESET
- initr_net, eth 初始化
- #endif
- #ifdef CONFIG_POST
- initr_post,
- #endif
- #if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
- initr_pcmcia,
- #endif
- #if defined(CONFIG_CMD_IDE)
- initr_ide,
- #endif
- #ifdef CONFIG_LAST_STAGE_INIT
- INIT_FUNC_WATCHDOG_RESET
- /*
- * Some parts can be only initialized if all others (like
- * Interrupts) are up and running (i.e. the PC-style ISA
- * keyboard).
- */
- last_stage_init,
- #endif
- #ifdef CONFIG_CMD_BEDBUG
- INIT_FUNC_WATCHDOG_RESET
- initr_bedbug,
- #endif
- #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
- initr_mem,
- #endif
- #ifdef CONFIG_PS2KBD
- initr_kbd, kbd 初始化
- #endif
- #if defined(CONFIG_SPARC)
- prom_init,
- #endif
- #ifdef CONFIG_FSL_FASTBOOT
- initr_check_fastboot, check_fastboot
- #endif
- run_main_loop, 主循环
- };
- # -------------------------------
- static int run_main_loop(void)
- {
- #ifdef CONFIG_SANDBOX
- sandbox_main_loop_init();
- #endif
- /* main_loop() can return to retry autoboot, if so just run it again */
- for (;;)
- main_loop(); // ========================================================== 重点分析
- return 0;
- }
- # -------------------------------
- void main_loop(void)
- {
- const char *s;
- bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
- #ifndef CONFIG_SYS_GENERIC_BOARD
- puts("Warning: Your board does not use generic board. Please read\n");
- puts("doc/README.generic-board and take action. Boards not\n");
- puts("upgraded by the late 2014 may break or be removed.\n");
- #endif
- #ifdef CONFIG_VERSION_VARIABLE
- setenv("ver", version_string); /* set version variable */
- #endif /* CONFIG_VERSION_VARIABLE */
- cli_init();
- run_preboot_environment_command(); 运行 preboot 命令 ( preboot 命令来自于env ):
- 调用 run_command_list
- cli_simple_run_command_list
- cli_simple_run_command
- cmd_process
- #if defined(CONFIG_UPDATE_TFTP)
- update_tftp(0UL, NULL, NULL);
- #endif /* CONFIG_UPDATE_TFTP */
- s = bootdelay_process(); 获取 bootdelay 延时时间(环境变量/配置定义),并且保存在 stored_bootdelay
- 获取 bootcmd 保存在 s 中
- if (cli_process_fdt(&s)) 尝试从 fdt 中获取 boootcmd 变量,和 secure_boot 变量
- cli_secure_boot_cmd(s); 如果有 secure_boot 变量,优先从 secure_boot 启动
- autoboot_command(s); 运行 s/bootcmd 命令
- cli_loop();
- }
- // ----------------------
- autoboot_command
- abortboot 打印"Hit any key to stop autoboot: %2d ",延时处理,
- abortboot_normal 如果有按键,放弃自动启动,如果没有按键,延时。最后都返回 abort 状态
- 根据 abort 状态,要不要继续往下运行。放弃 autoboot 之后返回到 cli_loop。
- run_command_list 执行 bootcmd 命令,bootcmd 是个命令列表
- cli_simple_run_command_list 循环执行 bootcmd 命令列表中的每个命令
- cli_simple_run_command 执行单个命令
- cmd_process(flag, argc, argv, &repeatable, NULL)
- cmd_call(cmdtp, flag, argc, argv);
- (cmdtp->cmd)(cmdtp, flag, argc, argv)
-
- // ----------------------
- cli_loop
- cli_simple_loop 陷入死循环中,不断读取 console buffer 然后执行,同样是调用 cli_simple_run_command -> cmd_process
- cli_simple_run_command
- cmd_process
复制代码
|
|