0 环境

ARMV8,uboot 2020.10,rpi3平台

1 移植框架

  • board,不用说了,板级,uboot使用dts后,这块代码应尽量简化
  • machine, SOC级,主要是一些外设
  • ARCH, 如arm(包含armv7和armv8)
  • CPU, 如armv8

各框架启动时的关系:

配置相关文件:

  1. configs/xxx_defconfig: 平台的默认配置,make ***_defconfig时会用到
  2. include/conigs/***.h: 各平台的一些额外CONFIG_配置项,写在头文件里

3 执行流程

3.0 链接地址

Makefile中:

  1. LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)

链接文件

  1. ENTRY(_start)
  2. SECTIONS
  3. {
  4. . = 0x00000000; /*text段在lds文件的偏移0*/
  5. . = ALIGN(8);
  6. .text :
  7. {
  8. *(.__image_copy_start)
  9. arch/arm/cpu/armv8/start.o (.text*)
  10. }
  11. ...
  • CONFIG_SYS_TEXT_BASE: lds文件中偏移为0,再结合-Ttext选项, 所以CONFIG_SYS_TEXT_BASE是重定位之前,最初的uboot起始地址

3.1 start.S, 入口

此阶段的CONFIG_

  1. 已定义:
  2. CONFIG_SYS_TEXT_BASE: uboot realocate之前的起始地址,代码里 _TEXT_BASE = CONFIG_SYS_TEXT_BASE
  3. 未定义:
  4. CONFIG_SYS_RESET_SCTRL, 设置 little endian, cache, MMU
  5. CONFIG_ARMV8_SET_SMPEN, 若为EL3,使能SMPEN, EL2/1无动作
  6. CONFIG_ARMV8_SPIN_TABLECONFIG_ARMV8_MULTIENTRY,像是两种处理slave core的方式,不过rpi3应该只有core0执行uboot,所以都没有定义

代码加注释:arch/arm/cpu/armv8/start.S

  1. /*************************************************************************
  2. *
  3. * Startup Code (reset vector)
  4. *
  5. *************************************************************************/
  6. .globl _start
  7. _start:
  8. #if defined(CONFIG_LINUX_KERNEL_IMAGE_HEADER)
  9. #include <asm/boot0-linux-kernel-header.h>
  10. #elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
  11. /*
  12. * Various SoCs need something special and SoC-specific up front in
  13. * order to boot, allow them to set that in their boot0.h file and then
  14. * use it here.
  15. */
  16. #include <asm/arch/boot0.h>
  17. #else
  18. b reset // 执行此分支
  19. #endif
  20. .align 3 # 2^3 = 8 Bytes对齐
  21. /*
  22. * 计算几个变量的值,并写入bin文件里,这些变量后面会用到
  23. */
  24. .globl _TEXT_BASE
  25. _TEXT_BASE:
  26. .quad CONFIG_SYS_TEXT_BASE
  27. /*
  28. * These are defined in the linker script.
  29. */
  30. .globl _end_ofs
  31. _end_ofs:
  32. .quad _end - _start
  33. .globl _bss_start_ofs
  34. _bss_start_ofs:
  35. .quad __bss_start - _start
  36. .globl _bss_end_ofs
  37. _bss_end_ofs:
  38. .quad __bss_end - _start
  39. reset:
  40. /* Allow the board to save important registers */
  41. b save_boot_params // 一般为空,直接跳到save_boot_params_ret
  42. .globl save_boot_params_ret
  43. save_boot_params_ret:
  44. #if CONFIG_POSITION_INDEPENDENT // 未定义
  45. /*
  46. * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
  47. * executed at a different address than it was linked at.
  48. */
  49. pie_fixup:
  50. adr x0, _start /* x0 <- Runtime value of _start */
  51. ldr x1, _TEXT_BASE /* x1 <- Linked value of _start */
  52. sub x9, x0, x1 /* x9 <- Run-vs-link offset */
  53. adr x2, __rel_dyn_start /* x2 <- Runtime &__rel_dyn_start */
  54. adr x3, __rel_dyn_end /* x3 <- Runtime &__rel_dyn_end */
  55. pie_fix_loop:
  56. ldp x0, x1, [x2], #16 /* (x0, x1) <- (Link location, fixup) */
  57. ldr x4, [x2], #8 /* x4 <- addend */
  58. cmp w1, #1027 /* relative fixup? */
  59. bne pie_skip_reloc
  60. /* relative fix: store addend plus offset at dest location */
  61. add x0, x0, x9
  62. add x4, x4, x9
  63. str x4, [x0]
  64. pie_skip_reloc:
  65. cmp x2, x3
  66. b.lo pie_fix_loop
  67. pie_fixup_done:
  68. #endif
  69. // 未定义此宏,设置 little endian, 关cache、 关MMU
  70. #ifdef CONFIG_SYS_RESET_SCTRL
  71. bl reset_sctrl
  72. #endif
  73. #if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
  74. .macro set_vbar, regname, reg
  75. msr \regname, \reg
  76. .endm
  77. adr x0, vectors # vectors是中断向量表,在arch/arm/cpu/armv8/exception.S中定义
  78. #else
  79. .macro set_vbar, regname, reg
  80. .endm
  81. #endif
  82. /*
  83. * Could be EL3/EL2/EL1, Initial State:
  84. * Little Endian, MMU Disabled, i/dCache Disabled
  85. */
  86. switch_el x1, 3f, 2f, 1f
  87. 3: set_vbar vbar_el3, x0
  88. mrs x0, scr_el3
  89. orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
  90. msr scr_el3, x0
  91. msr cptr_el3, xzr /* Enable FP/SIMD */
  92. #ifdef COUNTER_FREQUENCY
  93. ldr x0, =COUNTER_FREQUENCY
  94. msr cntfrq_el0, x0 /* Initialize CNTFRQ */
  95. #endif
  96. b 0f
  97. 2: set_vbar vbar_el2, x0
  98. mov x0, #0x33ff
  99. msr cptr_el2, x0 /* Enable FP/SIMD */
  100. b 0f
  101. 1: set_vbar vbar_el1, x0 /* 设置中断向量表,x0 = vectors */
  102. mov x0, #3 << 20
  103. msr cpacr_el1, x0 /* Enable FP/SIMD */
  104. 0:
  105. isb
  106. /*
  107. * Enable SMPEN bit for coherency.
  108. * This register is not architectural but at the moment
  109. * this bit should be set for A53/A57/A72.
  110. */
  111. #ifdef CONFIG_ARMV8_SET_SMPEN // 未定义
  112. switch_el x1, 3f, 1f, 1f
  113. 3:
  114. mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */
  115. orr x0, x0, #0x40
  116. msr S3_1_c15_c2_1, x0
  117. isb
  118. 1:
  119. #endif
  120. /* Apply ARM core specific erratas,处理一些已知的芯片bug */
  121. bl apply_core_errata
  122. /*
  123. * Cache/BPB/TLB Invalidate
  124. * i-cache is invalidated before enabled in icache_enable()
  125. * tlb is invalidated before mmu is enabled in dcache_enable()
  126. * d-cache is invalidated before enabled in dcache_enable()
  127. */
  128. /* Processor specific initialization */
  129. // 初始化临时sp, 实现一个weak函数s_init,给各个平台一个早期初始化的机会
  130. // 不过重新实现s_init的厂商不多
  131. bl lowlevel_init
  132. #if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
  133. branch_if_master x0, x1, master_cpu
  134. b spin_table_secondary_jump
  135. /* never return */
  136. #elif defined(CONFIG_ARMV8_MULTIENTRY)
  137. branch_if_master x0, x1, master_cpu
  138. /*
  139. * Slave CPUs
  140. */
  141. slave_cpu:
  142. wfe
  143. ldr x1, =CPU_RELEASE_ADDR
  144. ldr x0, [x1]
  145. cbz x0, slave_cpu
  146. br x0 /* branch to the given address */
  147. #endif /* CONFIG_ARMV8_MULTIENTRY */
  148. master_cpu:
  149. bl _main /* 跳转后不返回*/

3.2 __main



此阶段的CONFIG_

  1. 已定义:
  2. CONFIG_SYS_INIT_SP_ADDR 调用board_init_frelocate_code之前用的SP
  3. CONFIG_SYS_MALLOC_F_LEN 早期用于malloc的空间大小
  4. 未定义:
  5. CONFIG_TPL_BUILD:TPLSPL差不多,是第三级程序加载器,也是一个精简版的u-boot,很少用到,参见 doc/README.TPL

代码加注释:arch/arm/lib/crt0_64.S

  1. ENTRY(_main)
  2. /*
  3. * Set up initial C runtime environment and call board_init_f(0).
  4. * 先分配SP地址(CONFIG_SYS_INIT_SP_ADDR), 在sp上分配大名鼎鼎的gd_t空间,gd_t是重要的全局数据,地址保存在X18里,整个uboot都在使用
  5. */
  6. #if defined(CONFIG_TPL_BUILD) && defined(CONFIG_TPL_NEEDS_SEPARATE_STACK)
  7. ldr x0, =(CONFIG_TPL_STACK)
  8. #elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
  9. ldr x0, =(CONFIG_SPL_STACK)
  10. #elif defined(CONFIG_INIT_SP_RELATIVE)
  11. adr x0, __bss_start
  12. add x0, x0, #CONFIG_SYS_INIT_SP_BSS_OFFSET
  13. #else
  14. ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) // 进此分支, CONFIG_SYS_INIT_SP_ADDR一般在include/configs/****.h中定义
  15. #endif
  16. bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
  17. mov x0, sp
  18. bl board_init_f_alloc_reserve // 从sp顶端分配早期malloc空间(受CONFIG_SYS_MALLOC_F_LEN控制),分配global_data(gd)空间
  19. mov sp, x0
  20. /* set up gd here, outside any C code, 把global_data的地址赋给X18,X18始终保存着gd的地址 */
  21. mov x18, x0
  22. bl board_init_f_init_reserve // gd初始化为0, gd->malloc_base赋值(受CONFIG_SYS_MALLOC_F_LEN控制)
  23. mov x0, #0
  24. bl board_init_f // front, 前置初始化.执行函数指针数组init_sequence_f里的若干初始化函数,会把重定位时需要的若干信息写给gd
  25. #if !defined(CONFIG_SPL_BUILD)
  26. /*
  27. * Set up intermediate environment (new sp and gd) and call
  28. * relocate_code(addr_moni). Trick here is that we'll return
  29. * 'here' but relocated.
  30. */
  31. ldr x0, [x18, #GD_START_ADDR_SP] /* x0 <- gd->start_addr_sp, 获取重定位后的sp地址*/
  32. bic sp, x0, #0xf /* 16-byte alignment for ABI compliance ,将重定位后的地址赋给sp */
  33. ldr x18, [x18, #GD_NEW_GD] /* x18 <- gd->new_gd, 将重定位后的gd地址赋给X18 */
  34. /* 先把relocation_return给lr,此时lr的地址是为重定位前的relocation_return
  35. * 后面会给lr增加重定位的offset,保证重定位执行完毕返回lr时,能找到重定位后的relocation_return
  36. */
  37. adr lr, relocation_return
  38. #if CONFIG_POSITION_INDEPENDENT // 未定义
  39. /* Add in link-vs-runtime offset */
  40. adr x0, _start /* x0 <- Runtime value of _start */
  41. ldr x9, _TEXT_BASE /* x9 <- Linked value of _start */
  42. sub x9, x9, x0 /* x9 <- Run-vs-link offset */
  43. add lr, lr, x9
  44. #endif
  45. /* Add in link-vs-relocation offset */
  46. ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */
  47. add lr, lr, x9 /* new return address after relocation, 给lr加上重定位offset,此时lr已经指向重定位后的relocation_return */
  48. ldr x0, [x18, #GD_RELOCADDR] /* x0 <- gd->relocaddr, 重定位后的起始地址 */
  49. b relocate_code /* 重定位,拷贝text、data、rodata段, 拷贝并重写rel_dyn段,具体原理单独描述 */
  50. relocation_return:
  51. /*
  52. * Set up final (full) environment
  53. */
  54. bl c_runtime_cpu_setup /* still call old routine, 设置中断向量表vbar_elX */
  55. #endif /* !CONFIG_SPL_BUILD */
  56. #if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
  57. #if defined(CONFIG_SPL_BUILD)
  58. bl spl_relocate_stack_gd /* may return NULL */
  59. /* set up gd here, outside any C code, if new stack is returned */
  60. cmp x0, #0
  61. csel x18, x0, x18, ne
  62. /*
  63. * Perform 'sp = (x0 != NULL) ? x0 : sp' while working
  64. * around the constraint that conditional moves can not
  65. * have 'sp' as an operand
  66. */
  67. mov x1, sp
  68. cmp x0, #0
  69. csel x0, x0, x1, ne
  70. mov sp, x0
  71. #endif
  72. /*
  73. * Clear BSS section
  74. */
  75. ldr x0, =__bss_start /* this is auto-relocated! */
  76. ldr x1, =__bss_end /* this is auto-relocated! */
  77. clear_loop:
  78. str xzr, [x0], #8
  79. cmp x0, x1
  80. b.lo clear_loop
  81. /* call board_init_r(gd_t *id, ulong dest_addr) */
  82. mov x0, x18 /* gd_t */
  83. ldr x1, [x18, #GD_RELOCADDR] /* dest_addr */
  84. b board_init_r /* PC relative jump,重定位后的初始化和main loop, rear后置初始化 */
  85. /* NOTREACHED - board_init_r() does not return */
  86. #endif
  87. ENDPROC(_main)

3.3 board_init_f()和init_sequence_f[]

此阶段的CONFIG_选项:

  1. 已定义:
  2. CONFIG_OF_CONTROL:使用device tree
  3. CONFIG_OF_EMBED: dtsuboot集成到一起,一般都用此方式。makefile连接时会把dtb放到__dtb_dt_begin的位置
  4. CONFIG_DM: 使能driver model,驱动模型,一套抽象且统一的驱动框架,复杂了,也为标准化
  5. CONFIG_BAUDRATE 默认串口波特率
  6. CONFIG_SERIAL_PRESENT,存在串口
  7. CONFIG_DM_VIDEO
  8. 未定义:
  9. CONFIG_OF_SEPARATEdtsuboot分开,一般不用
  10. CONFIG_TIMER_EARLY:尽早使用timer
  11. CONFIG_BOARD_EARLY_INIT_F 早期board初始化,给board提供一个hook
  12. CONFIG_SYSRESET
  13. CONFIG_DISPLAY_CPUINFO
  14. CONFIG_DISPLAY_BOARDINFO
  15. CONFIG_SYS_I2C
  16. CONFIG_SYS_DRAM_TEST
  17. CONFIG_SYS_MEM_TOP_HIDE uboot对上面的内存不可见,将ram_size -= CONFIG_SYS_MEM_TOP_HIDE
  18. CONFIG_SYS_SDRAM_BASE: DDR的起始地址,没啥意义,0
  19. CONFIG_PRAM protected RAM, 可以预留一段不被uboot使用
  20. CONFIG_SYS_NONCACHED_MEMORY:分配non-cache区域

board_init_f()直接执行init_sequence_f[]里的若干函数,黄底层为board移植时一般需要实现的。

  • setup_mon_len(), gd->mon_len = 整个程序大小(text/data/bss等)
  • fdtdec_setup(),gd->fdt_blob = __dtb_dt_begin,dts用
  • initf_malloc(), 初始化gd的malloc相关成员,gd->malloc_limit和gd->malloc_ptr
  • log_init(),log相关初始化,暂不关注
  • initf_bootstage(),初始化bootstage功能,用于标记启动到哪个阶段了
  • arch_cpu_init(),cpu级别的初始化操作,可以在需要的时候由CPU有关的code实现,weak实现啥也没干
  • mach_cpu_init(), SoC/machine级别初始化,在mach_***里可以覆盖weak实现
  • initf_dm(), driver model有关的初始化操作
  • arch_cpu_init_dm(), cpu相关的dm初始化
  • board_early_init_f(), 早期board级初始化,一般没用
  • timer_init(), timer初始化
  • env_init,environment系统初始化
  • init_baud_rate,gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE),优先从环境变量“baudrate”中获取
  • serial_init, 初始化串口,之后串口可用
  • console_init_f
  • display_options,显示版本信息等
  • display_text_info,进一步显示信息
  • checkcpu
  • announce_dram_init,打印一句话
  • dram_init, ddr初始化,如果其他boot已经初始化了,初始化gd->ram_size = ***
  • testdram, dram测试
  • 后面是重定位后的地址分配相关内容,分配空间的函数以reserve_***开头,见下图



    uboot把自己重定位到高地址,linux启动后在低地址
  • dram_init_banksize(),设置:
  1. gd->bd->bi_dram[bank].start
  2. gd->bd->bi_dram[bank].size
  3. gd->ram_size
  4. gd->ram_base
  • show_dram_config(), 显示dram信息
  • setup_bdinfo(), bd->bi_memstart和bd->bi_memsize
  • display_new_sp(), 显示sp
  • reloc_fdt(),reloc_bootstage(), reloc_bloblist(),如果定义了相关宏,则把对应内容放到上面图中对位的位置
  • setup_reloc(), 计算gd->reloc_off,将gd拷贝到新地址

3.4 relocate

  • relocate的历史:可能是早期SOC,uboot可能在ROM中执行,效率低,所以要拷贝到RAM里,虽然当前SOC, 一般UBOOT在一开始就在RAM里了,但relocate这个环节被保留了。
  • arch/arm/lib/relocate_64.S, 对text、data、rel_dyn做重定位处理,返回时,已经在新地址运行了。
  • relocate是uboot比较难理解的部分,需要一些基础知识。



    1.每个func后面有label,PC+offset找labal;2.label中存全局变量地址;3.func后面的label作为text段的一部分; 4.rel_dyn段再保存所有label的地址;5.重定位时从rel_dyn段找lable地址,再修改lable里的内容,即修改了全局变量的地址
  • rel_dyn里保存的数据格式(arm64)
  1. -objdump -D u-boot > uboot_objdump.txt可得:
  2. Disassembly of section .rela.dyn:
  3. 00000000000f6940 <__image_copy_end>:
  4. ...
  5. f6970: 00082ad0 .inst 0x00082ad0 ; undefined
  6. f6974: 00000000 udf #0 // 8B, lable 地址
  7. f6978: 00000403 udf #1027
  8. f697c: 00000000 udf #0 // 8B, 标记
  9. f6980: 00102070 .inst 0x00102070 ; undefined
  10. f6984: 00000000 udf #0 // 8B, lable中保存的数据,即地址0x00082ad0里保存的值(全局变量地址)
  11. ...
  12. f69a0: 000d71b8 .inst 0x000d71b8 ; undefined
  13. f69a4: 00000000 udf #0
  14. f69a8: 00000403 udf #1027
  15. f69ac: 00000000 udf #0
  16. f69b0: 000e85e6 .inst 0x000e85e6 ; undefined
  17. f69b4: 00000000 udf #0

rel_dyn的格式为:

  1. long lable_addr; label地址
  2. long flag = 1027;
  3. long val_in_lable; labal里存的内容,即全局变量地址

所以rel_dyn重定位就很简单了, [lable_addr + rel_off] = val_in_lable + rel_off,, 段.rela.dyn本身没有拷贝,重定位后就不用了。

源码分析:

  1. /*
  2. * void relocate_code(addr_moni)
  3. *
  4. * This function relocates the monitor code.
  5. * x0 holds the destination address.
  6. */
  7. ENTRY(relocate_code)
  8. stp x29, x30, [sp, #-32]! /* create a stack frame */
  9. mov x29, sp
  10. str x0, [sp, #16]
  11. /*
  12. * Copy u-boot from flash to RAM
  13. * __image_copy_start = _TEXT_BASE = CONFIG_SYS_TEXT_BASE = 0x80000, 初始加载地址
  14. */
  15. adrp x1, __image_copy_start /* x1 <- address bits [31:12] */
  16. add x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
  17. subs x9, x0, x1 /* x9 <- Run to copy offset, X9 = 重定位前后地址的offset */
  18. b.eq relocate_done /* skip relocation */
  19. /*
  20. * Don't ldr x1, __image_copy_start here, since if the code is already
  21. * running at an address other than it was linked to, that instruction
  22. * will load the relocated value of __image_copy_start. To
  23. * correctly apply relocations, we need to know the linked value.
  24. *
  25. * Linked &__image_copy_start, which we know was at
  26. * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
  27. * relocated value, since it isn't a symbol reference.
  28. */
  29. ldr x1, _TEXT_BASE /* x1 <- Linked &__image_copy_start */
  30. subs x9, x0, x1 /* x9 <- Link to copy offset, X9 = 重定位前后地址的offset */
  31. adrp x1, __image_copy_start /* x1 <- address bits [31:12] */
  32. add x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
  33. adrp x2, __image_copy_end /* x2 <- address bits [31:12] */
  34. add x2, x2, :lo12:__image_copy_end /* x2 <- address bits [11:00] */
  35. copy_loop:
  36. ldp x10, x11, [x1], #16 /* copy from source address [x1] */
  37. stp x10, x11, [x0], #16 /* copy to target address [x0] */
  38. cmp x1, x2 /* until source end address [x2] */
  39. b.lo copy_loop
  40. str x0, [sp, #24]
  41. /* 上面代码完成__image_copy_start、__image_copy_end之间的代码拷贝,包括text和data段 */
  42. /*
  43. * Fix .rela.dyn relocations
  44. * rela.dyn里1个LABEL结构是:
  45. * 8 Bytes 地址
  46. * 8 Bytes 标记
  47. * 8 Bytes addend
  48. */
  49. adrp x2, __rel_dyn_start /* x2 <- address bits [31:12] */
  50. add x2, x2, :lo12:__rel_dyn_start /* x2 <- address bits [11:00] */
  51. adrp x3, __rel_dyn_end /* x3 <- address bits [31:12] */
  52. add x3, x3, :lo12:__rel_dyn_end /* x3 <- address bits [11:00] */
  53. fixloop:
  54. ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup), X0是label地址,X1存标记 */
  55. ldr x4, [x2], #8 /* x4 <- label地址里的值 */
  56. and x1, x1, #0xffffffff
  57. cmp x1, #R_AARCH64_RELATIVE
  58. bne fixnext
  59. /* relative fix: store addend plus offset at dest location */
  60. add x0, x0, x9
  61. add x4, x4, x9
  62. str x4, [x0] /* label值 + offset = lable里的值(全局变量地址) +offset */
  63. fixnext:
  64. cmp x2, x3
  65. b.lo fixloop
  66. relocate_done:
  67. switch_el x1, 3f, 2f, 1f
  68. bl hang
  69. 3: mrs x0, sctlr_el3
  70. b 0f
  71. 2: mrs x0, sctlr_el2
  72. b 0f
  73. 1: mrs x0, sctlr_el1
  74. 0: tbz w0, #2, 5f /* skip flushing cache if disabled */
  75. tbz w0, #12, 4f /* skip invalidating i-cache if disabled */
  76. ic iallu /* i-cache invalidate all */
  77. isb sy
  78. 4: ldp x0, x1, [sp, #16]
  79. bl __asm_flush_dcache_range
  80. bl __asm_flush_l3_dcache
  81. 5: ldp x29, x30, [sp],#32
  82. ret
  83. ENDPROC(relocate_code)

3.5 board_init_r()

3.5.1 init_sequence_r

relocate之后的初始化及主函数,执行init_sequence_r[]里的函数指针。

  • initr_trace,初始化并使能u-boot的tracing system,涉及的配置项有CONFIG_TRACE。
  • initr_reloc,设置relocation完成的标志。
  • initr_caches,使能dcache、icache等,涉及的配置项有CONFIG_ARM。
  • initr_reloc_global_data(), 重定位gd相关内容,gd->env_addr,gd->fdt_blob,efi相关初始化
  • initr_malloc,malloc有关的初始化
  • log_init, log相关初始化
  • initr_dm, relocate之后,重新初始化DM,涉及的配置项有CONFIG_DM
  • board_init,具体的板级初始化,需要由board代码根据需要实现,涉及的配置项有CONFIG_ARM。
  • set_cpu_clk_info,Initialize clock framework,涉及的配置项有CONFIG_CLOCKS。
  • efi_memory_init, efi相关初始化
  • initr_binman() ?
  • initr_dm_devices, CONFIG_TIMER_EARLY决定是否初始化timer
  • stdio_init_tables
  • serial_initialize
  • initr_announce, 打印
  • board_early_init_r, CONFIG_BOARD_EARLY_INIT_R控制是否调用,板级实现
  • arch_early_init_r,由arch代码实现,涉及的配置项有CONFIG_ARCH_EARLY_INIT_R。
  • power_init_board,板级的power init代码,由板级代码实现,例如hold住power。
  • initr_flash,initr_nand,initr_onenand,initr_mmc,根据各宏调用各存储设备初始化
  • initr_env, 环境变量相关初始化
  • initr_secondary_cpu,其他core初始化
  • stdio_add_devices,各种输入输出设备的初始化,如LCD driver等
  • initr_jumptable ?
  • console_init_r
  • arch_misc_init, 受CONFIG_ARCH_MISC_INIT控制的arch杂项
  • misc_init_r, 受CONFIG_MISC_INIT_R控制
  • interrupt_init, 使能中断
  • initr_status_led,状态指示LED的初始化,涉及的配置项有CONFIG_STATUS_LED、STATUS_LED_BOOT。
  • initr_ethaddr,Ethernet的初始化,涉及的配置项有CONFIG_CMD_NET。
  • board_late_init, 由板级代码实现,涉及的配置项有CONFIG_BOARD_LATE_INIT
  • initr_net。网络初始化,CONFIG_CMD_NET
  • run_main_loop/main_loop,主循环

3.5.2 main_loop

参考

http://www.wowotech.net/u-boot/boot_flow_1.html

https://blog.csdn.net/skyflying2012/article/details/37660265

https://blog.csdn.net/ooonebook/article/details/53047992

uboot1: 启动流程和移植框架的更多相关文章

  1. u-boot 编译,启动流程分析,移植

    分析u-boot-1.1.6 的启动流程 移植u-boot 2012.04版本到JZ2440开发板 源码百度云链接:https://pan.baidu.com/s/10VnxfDWBqJVGY3SCY ...

  2. 从0移植uboot (二) _uboot启动流程分析

    经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,同时,此时的uboot.bin也没有结合 ...

  3. [Abp vNext 源码分析] - 1. 框架启动流程分析

    一.简要说明 本篇文章主要剖析与讲解 Abp vNext 在 Web API 项目下的启动流程,让大家了解整个 Abp vNext 框架是如何运作的.总的来说 ,Abp vNext 比起 ABP 框架 ...

  4. [Abp 源码分析]一、Abp 框架启动流程分析

    Abp 不一定仅用于 Asp.Net Core 项目,他也可以在 Console 与 WinFrom 项目当中进行使用,所以关于启动流程可以分为两种,一种是 Asp.Net Core 项目的启动流程, ...

  5. ThinkPHP5.0源码学习之框架启动流程

    ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...

  6. linux 内核启动流程分析,移植

    分析 linux-2.6.22.6 内核启动流程 移植 linux-3.4.2 到 JZ2440 开发板 Linux内核源码百度云链接: https://pan.baidu.com/s/1m1ymGl ...

  7. u-boot移植随笔(7):u-boot启动流程简图【转】

    转自:http://www.latelee.org/porting-uboot/u-boot-porting-bootstrap.html u-boot移植随笔:u-boot启动流程简图 画上面这张图 ...

  8. 菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程

    菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  9. (转)从0移植uboot (二) _uboot启动流程分析

    ref:https://www.cnblogs.com/xiaojiang1025/p/6496704.html 经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够 ...

随机推荐

  1. 吃透 MQ

    本文主要讲解 MQ 的通用知识,让大家先弄明白:如果让你来设计一个 MQ,该如何下手?需要考虑哪些问题?又有哪些技术挑战? 有了这个基础后,我相信后面几篇文章再讲 Kafka 和 RocketMQ 这 ...

  2. 从设计模式角度看OkHttp源码

    前言 说到源码,很多朋友都觉得复杂,难理解. 但是,如果是一个结构清晰且完全解耦的优质源码库呢? OkHttp就是这样一个存在,对于这个原生网络框架,想必大家也看过很多很多相关的源码解析了. 它的源码 ...

  3. 关于java的访问修饰符权限

    作用域    public protected default private  同一个类   yes     yes      yes      yes 同一个包   yes     yes    ...

  4. 记录Java注解在JavaWeb中的一个应用实例

    概述 在学习注解的时候,学了个懵懵懂懂.学了JavaWeb之后,在做Demo项目的过程中,借助注解和反射实现了对页面按钮的权限控制,对于注解才算咂摸出了点味儿来. 需求 以"角色列表&quo ...

  5. P1223_排队接水(JAVA语言)

    思路 根据短作业优先平均等待时间最短的常识(默默感叹一句操作系统没白学),将Ti从小到大排序后,计算平均等待时间输出 //水题 题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请 ...

  6. [图论]剑鱼行动:prim

    剑鱼行动 目录 剑鱼行动 Description Input Output Sample Input Sample Output 解析 难点 代码 Description 给出N个点的坐标,对它们建立 ...

  7. Distributed | ZooKeeper

    ZooKeeper与之前看的论文不太一样,它主要是描述了一个分布式协调服务,提供了wait-free的api,可以让用户自己设计要求更高的原语.通过Zab协议保证sever之间的一致性,同时让读请求在 ...

  8. Java(41-55)【 流程控制语句】

    1. 2.练习题if语句的使用 3.选择语句 4. 5.循环结构 6.continue和break

  9. 聊聊 OAuth 2.0 的 Token 续期处理

    Token 校验逻辑 // CheckTokenEndpoint.checkToken @RequestMapping(value = "/oauth/check_token") ...

  10. Github仓库master分支到main分支迁移指南

    1 概述 2020年10月1日后,Github会将所有新建的仓库的默认分支从master修改为main,这就导致了一些旧仓库主分支是master,新仓库主分支是main的问题,这在有时候会带来一些麻烦 ...