Uboot启程:移植框架与启动之路。

摘要

uboot1:运行步骤和移植架构,融入自然环境,展开壮丽征程。从start.S到__main,再到board_init_f()和init_sequence_f[],最后到relocate和board_init_r(),一路奋斗,不断前行。参照ARMV…,感受移植的魅力。

正文

uboot1: 运行步骤和移殖架构

文件目录

  • 0 自然环境
  • 1 移殖架构
  • 3 实行步骤
    • 3.0 连接详细地址
    • 3.1 start.S, 通道
    • 3.2 __main
    • 3.3 board_init_f()和init_sequence_f[]
    • 3.4 relocate
    • 3.5 board_init_r()
      • 3.5.1 init_sequence_r
      • 3.5.2 main_loop
  • 参照

0 自然环境

ARMV8,uboot 2020.10,rpi3服务平台

1 移殖架构

  • board,别说了,板级,uboot应用dts后,这方面编码应尽可能简单化
  • machine, SOC级,主要是一些外接设备
  • ARCH, 如arm(包括armv7和armv8)
  • CPU, 如armv8

各架构运作时的关联:

配备有关文档:

configs/xxx_defconfig: 服务平台的默认设置配备,make ***_defconfig的时候会采用
include/conigs/***.h: 各服务平台的一些附加CONFIG_配备项,写在头文件里

3 实行步骤

3.0 连接详细地址

Makefile中:

LDFLAGS_u-boot  = -Ttext $(CONFIG_SYS_TEXT_BASE)

链接文件

ENTRY(_start)
SECTIONS
{
 . = 0x00000000; /*text段在lds文档的偏位0*/
 . = ALIGN(8);
 .text :
 {
  *(.__image_copy_start)
  arch/arm/cpu/armv8/start.o (.text*)
 }
 ...
  • CONFIG_SYS_TEXT_BASE: lds文档中偏位为0,再融合-Ttext选择项, 因此 CONFIG_SYS_TEXT_BASE是重精准定位以前,最开始的uboot起止详细地址

3.1 start.S, 通道

此环节的CONFIG_

已界定:
CONFIG_SYS_TEXT_BASE: uboot realocate以前的起止详细地址,编码里 _TEXT_BASE = CONFIG_SYS_TEXT_BASE

未定义:
CONFIG_SYS_RESET_SCTRL, 设定 little endian, 关cache, 关MMU
CONFIG_ARMV8_SET_SMPEN, 若为EL3,也就能SMPEN, EL2/1无姿势
CONFIG_ARMV8_SPIN_TABLE和CONFIG_ARMV8_MULTIENTRY,好像二种解决slave core的方法,但是rpi3应当仅有core0实行uboot,因此 也没有界定

编码加注解:arch/arm/cpu/armv8/start.S

/*************************************************************************
 *
 * Startup Code (reset vector)
 *
 *************************************************************************/

.globl	_start
_start:
#if defined(CONFIG_LINUX_KERNEL_IMAGE_HEADER)
#include <asm/boot0-linux-kernel-header.h>
#elif defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
/*
 * Various SoCs need something special and SoC-specific up front in
 * order to boot, allow them to set that in their boot0.h file and then
 * use it here.
 */
#include <asm/arch/boot0.h>
#else
	b	reset     // 实行此支系
#endif

	.align 3    #  2^3 = 8 Bytes两端对齐

/*
 * 测算好多个自变量的值,并载入bin文档里,这种自变量后边会采用
 */
.globl	_TEXT_BASE
_TEXT_BASE:
	.quad	CONFIG_SYS_TEXT_BASE

/*
 * These are defined in the linker script.
 */
.globl	_end_ofs
_end_ofs:
	.quad	_end - _start

.globl	_bss_start_ofs
_bss_start_ofs:
	.quad	__bss_start - _start

.globl	_bss_end_ofs
_bss_end_ofs:
	.quad	__bss_end - _start

reset:
	/* Allow the board to save important registers */
	b	save_boot_params    // 一般为空,立即跳到save_boot_params_ret
.globl	save_boot_params_ret
save_boot_params_ret:

#if CONFIG_POSITION_INDEPENDENT // 未定义
	/*
	 * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
	 * executed at a different address than it was linked at.
	 */
pie_fixup:
	adr	x0, _start		/* x0 <- Runtime value of _start */
	ldr	x1, _TEXT_BASE		/* x1 <- Linked value of _start */
	sub	x9, x0, x1		/* x9 <- Run-vs-link offset */
	adr	x2, __rel_dyn_start	/* x2 <- Runtime &__rel_dyn_start */
	adr	x3, __rel_dyn_end	/* x3 <- Runtime &__rel_dyn_end */
pie_fix_loop:
	ldp	x0, x1, [x2], #16	/* (x0, x1) <- (Link location, fixup) */
	ldr	x4, [x2], #8		/* x4 <- addend */
	cmp	w1, #1027		/* relative fixup? */
	bne	pie_skip_reloc
	/* relative fix: store addend plus offset at dest location */
	add	x0, x0, x9
	add	x4, x4, x9
	str	x4, [x0]
pie_skip_reloc:
	cmp	x2, x3
	b.lo	pie_fix_loop
pie_fixup_done:
#endif

// 未定义此宏,设定 little endian, 关cache、 关MMU
#ifdef CONFIG_SYS_RESET_SCTRL  
	bl reset_sctrl
#endif

#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
.macro	set_vbar, regname, reg
	msr	\regname, \reg
.endm
	adr	x0, vectors     # vectors是中断向量表,在arch/arm/cpu/armv8/exception.S中界定
#else
.macro	set_vbar, regname, reg
.endm
#endif
	/*
	 * Could be EL3/EL2/EL1, Initial State:
	 * Little Endian, MMU Disabled, i/dCache Disabled
	 */
	switch_el x1, 3f, 2f, 1f
3:	set_vbar vbar_el3, x0
	mrs	x0, scr_el3
	orr	x0, x0, #0xf			/* SCR_EL3.NS|IRQ|FIQ|EA */
	msr	scr_el3, x0
	msr	cptr_el3, xzr			/* Enable FP/SIMD */
#ifdef COUNTER_FREQUENCY
	ldr	x0, =COUNTER_FREQUENCY
	msr	cntfrq_el0, x0			/* Initialize CNTFRQ */
#endif
	b	0f
2:	set_vbar	vbar_el2, x0
	mov	x0, #0x33ff
	msr	cptr_el2, x0			/* Enable FP/SIMD */
	b	0f
1:	set_vbar	vbar_el1, x0    /* 设定中断向量表,x0 = vectors */
	mov	x0, #3 << 20
	msr	cpacr_el1, x0			/* Enable FP/SIMD */
0:
	isb

	/*
	 * Enable SMPEN bit for coherency.
	 * This register is not architectural but at the moment
	 * this bit should be set for A53/A57/A72.
	 */
#ifdef CONFIG_ARMV8_SET_SMPEN   // 未定义
	switch_el x1, 3f, 1f, 1f
3:
	mrs     x0, S3_1_c15_c2_1               /* cpuectlr_el1 */
	orr     x0, x0, #0x40
	msr     S3_1_c15_c2_1, x0
	isb
1:
#endif

	/* Apply ARM core specific erratas,解决一些已经知道的集成icbug */
	bl	apply_core_errata

	/*
	 * Cache/BPB/TLB Invalidate
	 * i-cache is invalidated before enabled in icache_enable()
	 * tlb is invalidated before mmu is enabled in dcache_enable()
	 * d-cache is invalidated before enabled in dcache_enable()
	 */

	/* Processor specific initialization */
	// 复位临时性sp, 完成一个weak涵数s_init,给每个服务平台一个初期复位的机遇
    // 但是再次完成s_init的生产商很少
	bl	lowlevel_init

#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
	branch_if_master x0, x1, master_cpu
	b	spin_table_secondary_jump
	/* never return */
#elif defined(CONFIG_ARMV8_MULTIENTRY)
	branch_if_master x0, x1, master_cpu

	/*
	 * Slave CPUs
	 */
slave_cpu:
	wfe
	ldr	x1, =CPU_RELEASE_ADDR
	ldr	x0, [x1]
	cbz	x0, slave_cpu
	br	x0			/* branch to the given address */
#endif /* CONFIG_ARMV8_MULTIENTRY */
master_cpu:
	bl	_main   /*  自动跳转后不回到*/

3.2 __main


此环节的CONFIG_

已界定:
CONFIG_SYS_INIT_SP_ADDR: 启用board_init_f和relocate_code以前用的SP
CONFIG_SYS_MALLOC_F_LEN: 初期用以malloc的室内空间尺寸

未定义:
CONFIG_TPL_BUILD:TPL跟SPL类似,是第三级程序流程加载器,也是一个精简的u-boot,非常少采用,参照 doc/README.TPL

编码加注解:arch/arm/lib/crt0_64.S

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 * 先分派SP详细地址(CONFIG_SYS_INIT_SP_ADDR), 在sp上分派赫赫有名的gd_t室内空间,gd_t是关键的全局性数据信息,详细地址储存在X18里,全部uboot都是在应用
 */
#if defined(CONFIG_TPL_BUILD) && defined(CONFIG_TPL_NEEDS_SEPARATE_STACK)
	ldr	x0, =(CONFIG_TPL_STACK)
#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
	ldr	x0, =(CONFIG_SPL_STACK)
#elif defined(CONFIG_INIT_SP_RELATIVE)
	adr	x0, __bss_start
	add	x0, x0, #CONFIG_SYS_INIT_SP_BSS_OFFSET
#else
	ldr	x0, =(CONFIG_SYS_INIT_SP_ADDR)      // 进此支系, CONFIG_SYS_INIT_SP_ADDR一般在include/configs/****.h中界定
#endif
	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance */
	mov	x0, sp
	bl	board_init_f_alloc_reserve    // 从sp顶部分派初期malloc室内空间(受CONFIG_SYS_MALLOC_F_LEN操纵),分派global_data(gd)室内空间
	mov	sp, x0
	/* set up gd here, outside any C code, 把global_data的详细地址赋给X18,X18自始至终储存着gd的详细地址 */
	mov	x18, x0
	bl	board_init_f_init_reserve      // gd复位为0, gd->malloc_base取值(受CONFIG_SYS_MALLOC_F_LEN操纵)

	mov	x0, #0
	bl	board_init_f                // front, 外置复位.实行涵数指针数组init_sequence_f里的多个复位涵数,会把重精准定位时必须的多个信息内容写給gd

#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	x0, [x18, #GD_START_ADDR_SP]	/* x0 <- gd->start_addr_sp, 获得重精准定位后的sp详细地址*/
	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance ,将重精准定位后的详细地址赋给sp */
	ldr	x18, [x18, #GD_NEW_GD]		/* x18 <- gd->new_gd, 将重精准定位后的gd详细地址赋给X18 */

   /* 先把relocation_return给lr,这时lr的详细地址是为主精准定位前的relocation_return
    * 后边会给lr提升重精准定位的offset,确保重精准定位实行结束回到lr时,能寻找重精准定位后的relocation_return
    */
	adr	lr, relocation_return       
#if CONFIG_POSITION_INDEPENDENT      // 未定义
	/* Add in link-vs-runtime offset */
	adr	x0, _start		/* x0 <- Runtime value of _start */
	ldr	x9, _TEXT_BASE		/* x9 <- Linked value of _start */
	sub	x9, x9, x0		/* x9 <- Run-vs-link offset */
	add	lr, lr, x9
#endif
	/* Add in link-vs-relocation offset */
	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */
	add	lr, lr, x9	/* new return address after relocation, 给lr再加上重精准定位offset,这时lr早已偏向重精准定位后的relocation_return */
	ldr	x0, [x18, #GD_RELOCADDR]	/* x0 <- gd->relocaddr, 重精准定位后的起止详细地址 */
	b	relocate_code               /* 重精准定位,复制text、data、rodata段, 复制并调用rel_dyn段,实际基本原理独立叙述 */

relocation_return:

/*
 * Set up final (full) environment
 */
	bl	c_runtime_cpu_setup		/* still call old routine, 设定中断向量表vbar_elX */
#endif /* !CONFIG_SPL_BUILD */
#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
#if defined(CONFIG_SPL_BUILD)
	bl	spl_relocate_stack_gd           /* may return NULL */
	/* set up gd here, outside any C code, if new stack is returned */
	cmp	x0, #0
	csel	x18, x0, x18, ne
	/*
	 * Perform 'sp = (x0 != NULL) ? x0 : sp' while working
	 * around the constraint that conditional moves can not
	 * have 'sp' as an operand
	 */
	mov	x1, sp
	cmp	x0, #0
	csel	x0, x0, x1, ne
	mov	sp, x0
#endif

/*
 * Clear BSS section
 */
	ldr	x0, =__bss_start		/* this is auto-relocated! */
	ldr	x1, =__bss_end			/* this is auto-relocated! */
clear_loop:
	str	xzr, [x0], #8
	cmp	x0, x1
	b.lo	clear_loop

	/* call board_init_r(gd_t *id, ulong dest_addr) */
	mov	x0, x18				/* gd_t */
	ldr	x1, [x18, #GD_RELOCADDR]	/* dest_addr */
	b	board_init_r			/* PC relative jump,重精准定位后的复位和main loop, rear后置摄像头复位 */

	/* NOTREACHED - board_init_r() does not return */
#endif

ENDPROC(_main)

3.3 board_init_f()和init_sequence_f[]

此环节的CONFIG_选择项:

已界定:
CONFIG_OF_CONTROL:应用device tree
CONFIG_OF_EMBED: dts与uboot集成化到一起,一般都用此方法。makefile联接的时候会把dtb放进__dtb_dt_begin的部位
CONFIG_DM: 也就能driver model,驱动器实体模型,一套抽象性且统一的驱动器架构,繁杂了,也为规范化
CONFIG_BAUDRATE, 默认设置串口波特率
CONFIG_SERIAL_PRESENT,存有串口通信
CONFIG_DM_VIDEO,

未定义:
CONFIG_OF_SEPARATE:dts与uboot分离,一般无需
CONFIG_TIMER_EARLY:尽快应用timer
CONFIG_BOARD_EARLY_INIT_F: 初期board复位,给board给予一个hook
CONFIG_SYSRESET
CONFIG_DISPLAY_CPUINFO
CONFIG_DISPLAY_BOARDINFO
CONFIG_SYS_I2C
CONFIG_SYS_DRAM_TEST
CONFIG_SYS_MEM_TOP_HIDE: 让uboot对上边的运行内存不由此可见,将ram_size -= CONFIG_SYS_MEM_TOP_HIDE
CONFIG_SYS_SDRAM_BASE: DDR的起止详细地址,没啥实际意义,0
CONFIG_PRAM: protected RAM, 能够 预埋一段不被uboot应用
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(),设定:
	gd->bd->bi_dram[bank].start
	gd->bd->bi_dram[bank].size
    gd->ram_size
	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)
-objdump -D u-boot > uboot_objdump.txt可获得:

Disassembly of section .rela.dyn:
00000000000f6940 <__image_copy_end>:
   ...
   f6970:	00082ad0 	.inst	0x00082ad0 ; undefined
   f6974:	00000000 	udf	#0       // 8B, lable 详细地址
   f6978:	00000403 	udf	#1027
   f697c:	00000000 	udf	#0       // 8B, 标识
   f6980:	00102070 	.inst	0x00102070 ; undefined
   f6984:	00000000 	udf	#0      // 8B, lable中储存的数据信息,即详细地址0x00082ad0里储存的值(全局变量详细地址)
   ...
  f69a0:	000d71b8 	.inst	0x000d71b8 ; undefined
   f69a4:	00000000 	udf	#0
   f69a8:	00000403 	udf	#1027
   f69ac:	00000000 	udf	#0
   f69b0:	000e85e6 	.inst	0x000e85e6 ; undefined
   f69b4:	00000000 	udf	#0

rel_dyn的文件格式为:

long lable_addr;        label详细地址
long flag = 1027;
long val_in_lable;      labal里存的內容,即全局变量详细地址

因此 rel_dyn重精准定位就非常简单了, [lable_addr rel_off] = val_in_lable rel_off,, 段.rela.dyn自身沒有复制,重精准定位后就不需要了。

源代码剖析:

/*
 * void relocate_code(addr_moni)
 *
 * This function relocates the monitor code.
 * x0 holds the destination address.
 */
ENTRY(relocate_code)
	stp	x29, x30, [sp, #-32]!	/* create a stack frame */
	mov	x29, sp
	str	x0, [sp, #16]
	/*
	 * Copy u-boot from flash to RAM
	 * __image_copy_start = _TEXT_BASE = CONFIG_SYS_TEXT_BASE = 0x80000, 原始载入详细地址
	 */
	adrp	x1, __image_copy_start		/* x1 <- address bits [31:12] */
	add	x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
	subs	x9, x0, x1			/* x9 <- Run to copy offset, X9 = 重精准定位前后左右详细地址的offset */
	b.eq	relocate_done			/* skip relocation */
	/*
	 * Don't ldr x1, __image_copy_start here, since if the code is already
	 * running at an address other than it was linked to, that instruction
	 * will load the relocated value of __image_copy_start. To
	 * correctly apply relocations, we need to know the linked value.
	 *
	 * Linked &__image_copy_start, which we know was at
	 * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
	 * relocated value, since it isn't a symbol reference.
	 */
	ldr	x1, _TEXT_BASE		/* x1 <- Linked &__image_copy_start */
	subs	x9, x0, x1		/* x9 <- Link to copy offset, X9 = 重精准定位前后左右详细地址的offset */

	adrp	x1, __image_copy_start		/* x1 <- address bits [31:12] */
	add	x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
	adrp	x2, __image_copy_end		/* x2 <- address bits [31:12] */
	add	x2, x2, :lo12:__image_copy_end	/* x2 <- address bits [11:00] */
copy_loop:
	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */
	stp	x10, x11, [x0], #16	/* copy to   target address [x0] */
	cmp	x1, x2			/* until source end address [x2] */
	b.lo	copy_loop
	str	x0, [sp, #24]
	/* 上边编码进行__image_copy_start、__image_copy_end中间的编码复制,包含text和data段 */
	/*
	 * Fix .rela.dyn relocations
	 * rela.dyn里一个LABEL构造是:
	 * 8 Bytes 详细地址
	 * 8 Bytes 标识
	 * 8 Bytes addend
	 */
	adrp	x2, __rel_dyn_start		/* x2 <- address bits [31:12] */
	add	x2, x2, :lo12:__rel_dyn_start	/* x2 <- address bits [11:00] */
	adrp	x3, __rel_dyn_end		/* x3 <- address bits [31:12] */
	add	x3, x3, :lo12:__rel_dyn_end	/* x3 <- address bits [11:00] */
fixloop:
	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup), X0是label详细地址,X1存标识 */
	ldr	x4, [x2], #8		/* x4 <- label详细地址里的值 */
	and	x1, x1, #0xffffffff
	cmp	x1, #R_AARCH64_RELATIVE
	bne	fixnext

	/* relative fix: store addend plus offset at dest location */
	add	x0, x0, x9       
	add	x4, x4, x9
	str	x4, [x0]       /* label值   offset =  lable里的值(全局变量详细地址)  offset */
fixnext:
	cmp	x2, x3
	b.lo	fixloop

relocate_done:
	switch_el x1, 3f, 2f, 1f
	bl	hang
3:	mrs	x0, sctlr_el3
	b	0f
2:	mrs	x0, sctlr_el2
	b	0f
1:	mrs	x0, sctlr_el1
0:	tbz	w0, #2, 5f	/* skip flushing cache if disabled */
	tbz	w0, #12, 4f	/* skip invalidating i-cache if disabled */
	ic	iallu		/* i-cache invalidate all */
	isb	sy
4:	ldp	x0, x1, [sp, #16]
	bl	__asm_flush_dcache_range
	bl     __asm_flush_l3_dcache
5:	ldp	x29, x30, [sp],#32
	ret
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,各种各样I/O机器设备的复位,如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

关注不迷路

扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!

温馨提示:如果您访问和下载本站资源,表示您已同意只将下载文件用于研究、学习而非其他用途。
文章版权声明 1、本网站名称:宇凡盒子
2、本站文章未经许可,禁止转载!
3、如果文章内容介绍中无特别注明,本网站压缩包解压需要密码统一是:yufanbox.com
4、本站仅供资源信息交流学习,不保证资源的可用及完整性,不提供安装使用及技术服务。点此了解
5、如果您发现本站分享的资源侵犯了您的权益,请及时通知我们,我们会在接到通知后及时处理!提交入口
0

评论0

请先

站点公告

🚀 【宇凡盒子】全网资源库转储中心

👉 注册即送VIP权限👈

👻 全站资源免费下载✅,欢迎注册!

记得 【收藏】+【关注】 谢谢!~~~

立即注册
没有账号?注册  忘记密码?

社交账号快速登录