目录
- 背景
- 平台启动
- 入口确认
- 启动源码
- DuoS_SG2000_RISCV
- Lubancat2_RK3568_ARM
- 初始化流程
- board_init_f
- board_init_r
- 参考
背景
-
设备:MilkV Duo S
-
版本:U-boot 2021.10
-
编译命令
# Milkv-DuoS SD卡版本,对应[board]与[config]分别为: # milkv-duo cv1800b_milkv_duo_sd # milkv-duos cv1813h_milkv_duos_sd # 拆解如下 CHIP=cv1813h VENDOR=milkv BOARD=duos BOOT=sd # 得到板级目录与配置文件 BOARD_FULL=${CHIP}-${VENDOR}-${BOARD}-${BOOT} CONFIG_FULL=${CHIP}_${VENDOR}_${BOARD}_${BOOT} # 加载板级配置与基础环境变量 source device/${BOARD_FULL}/boardconfig.sh source build/milkvsetup.sh # 加载板级配置 defconfig ${CONFIG_FULL} # 编译U-boot build_uboot
平台启动
入口确认
查看Kbuild生成的链接脚本u-boot-2021.10/build/cv1813h_milkv_duos_sd/u-boot.lds
,内容如下:
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = ALIGN(4);
.text : {
arch/riscv/cpu/start.o (.text)
}
...
其中,关键信息攫取:
OUTPUT_ARCH("riscv")
,目标平台为riscv;ENTRY(_start)
,入口为_start;arch/riscv/cpu/start.o (.text)
,入口可能存在于汇编文件arch/riscv/cpu/start.S中;
而生成该u-boot.lds
脚本的命令可以参考文件u-boot-2021.10/build/cv1813h_milkv_duos_sd/.u-boot.lds.cmd
,内容如下:
cmd_u-boot.lds := riscv64-unknown-linux-musl-gcc -E -Wp,-MD,./.u-boot.lds.d -D__KERNEL__ -D__UBOOT__ -DCONFIG_SKIP_RAMDISK=y -DCONFIG_USE_DEFAULT_ENV=y -DCVICHIP=cv1813h -DCVIBOARD=milkv_duos_sd -DCV1813H_MILKV_DUOS_SD -DMIPI_PANEL_HX8394 -ffixed-gp -fpic -fno-common -gdwarf-2 -ffunction-sections -fdata-sections -pipe -march=rv64imac -mabi=lp64 -mcmodel=medlow -Iinclude -I/home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include -I/home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include/cvitek -I/home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/arch/riscv/include -include /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include/linux/kconfig.h -nostdinc -isystem /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/host-tools/gcc/riscv64-linux-musl-x86_64/bin/../lib/gcc/riscv64-unknown-linux-musl/10.2.0/include -ansi -include /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include/u-boot/u-boot.lds.h -DCPUDIR=arch/riscv/cpu/generic -D__ASSEMBLY__ -x assembler-with-cpp -std=c99 -P -o u-boot.lds /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/arch/riscv/cpu/u-boot.lds
source_u-boot.lds := /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/arch/riscv/cpu/u-boot.lds
deps_u-boot.lds := \
/home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include/linux/kconfig.h \
$(wildcard include/config/booger.h) \
$(wildcard include/config/foo.h) \
$(wildcard include/config/spl/.h) \
$(wildcard include/config/tpl/build.h) \
$(wildcard include/config/spl/build.h) \
$(wildcard include/config/spl/foo.h) \
$(wildcard include/config/tpl/foo.h) \
$(wildcard include/config/option.h) \
$(wildcard include/config/acme.h) \
$(wildcard include/config/spl/acme.h) \
$(wildcard include/config/tpl/acme.h) \
/home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/u-boot-2021.10/include/u-boot/u-boot.lds.h \
u-boot.lds: $(deps_u-boot.lds)
其中,关键信息:
cmd_u-boot.lds
,u-boot.lds文件生成命令,其中有参数:riscv64-unknown-linux-musl-gcc
,使用GCC工具;.../u-boot-2021.10/arch/riscv/cpu/u-boot.lds
,源文件为arch/riscv/cpu/u-boot.lds
;-o u-boot.lds
,编译输出为u-boot.lds
;
查看相似文件,可以获知程序入口。
查看u-boot
编译命令文件u-boot-2021.10/build/cv1813h_milkv_duos_sd/.u-boot.cmd
,有如下内容:
cmd_u-boot := riscv64-unknown-linux-musl-ld.bfd -m elf64lriscv --gc-sections -static -pie -Bstatic --no-dynamic-linker --build-id=none -Ttext 0x80200000 -o u-boot -T u-boot.lds arch/riscv/cpu/start.o --whole-archive arch/riscv/cpu/built-in.o arch/riscv/cpu/generic/built-in.o arch/riscv/lib/built-in.o board/cvitek/cv181x/built-in.o cmd/built-in.o common/built-in.o disk/built-in.o drivers/built-in.o drivers/cvi_usb/built-in.o drivers/dma/built-in.o drivers/gpio/built-in.o drivers/net/built-in.o drivers/net/phy/built-in.o drivers/power/built-in.o drivers/power/battery/built-in.o drivers/power/domain/built-in.o drivers/power/fuel_gauge/built-in.o drivers/power/mfd/built-in.o drivers/power/pmic/built-in.o drivers/power/regulator/built-in.o drivers/serial/built-in.o drivers/spi/built-in.o drivers/usb/cdns3/built-in.o drivers/usb/common/built-in.o drivers/usb/dwc3/built-in.o drivers/usb/emul/built-in.o drivers/usb/eth/built-in.o drivers/usb/host/built-in.o drivers/usb/mtu3/built-in.o drivers/usb/musb-new/built-in.o drivers/usb/musb/built-in.o drivers/usb/phy/built-in.o drivers/usb/ulpi/built-in.o env/built-in.o fs/built-in.o lib/built-in.o net/built-in.o --no-whole-archive -L /home/gaoyang3513/Source/10-CV1800/01-MilkDuo/02-Project/CV180x_Milkv_Baseline/host-tools/gcc/riscv64-linux-musl-x86_64/bin/../lib/gcc/riscv64-unknown-linux-musl/10.2.0/lib64/lp64 -lgcc -Map u-boot.map; true
其中,有关键信息:
-Ttext 0x80200000
,入口地址为0x8020000,在DDR内存起始偏移128KB的位置;-o u-boot -T u-boot.lds
,依据链接脚本u-boot.lds编译输出u-boot文件;
启动源码
DuoS_SG2000_RISCV
查找入口_start
,有如下:
$ grep -wrn "_start" u-boot-2021.10/
...
u-boot-2021.10/arch/x86/cpu/start.S:65:_start:
...
u-boot-2021.10/arch/arm/cpu/armv8/start.S:20:_start:
...
u-boot-2021.10/arch/riscv/cpu/start.S:41:_start:
...
u-boot-2021.10/arch/mips/mach-jz47xx/start.S:20:_start:
...
有多个平台的汇编入口,由上一章节链接脚本的生成过程中可知,汇编实现源文件为u-boot-2021.10/arch/riscv/cpu/start.S
,内容如下:
.globl _start
_start:
...
/*
* Set stackpointer in internal/ex RAM to call board_init_f
*/
call_board_init_f:
li t0, -16
...
li t1, CONFIG_SYS_INIT_SP_ADDR // 栈指针
and sp, t1, t0 /* force 16 byte alignment */ // 栈寄存器初始化,16字节对齐
...
/* Enable cache */
jal icache_enable // I-Cache 使能
jal dcache_enable // D-Cache 使能
...
mv a0, zero /* a0 <-- boot_flags = 0 */
la t5, board_init_f
jalr t5 /* jump to board_init_f() */ // 调用 board_init_f
...
/*
* void relocate_code(addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
*/
.globl relocate_code // 定义函数 relocate_code
relocate_code:
mv s2, a0 /* save addr_sp */
mv s3, a1 /* save addr of gd */
mv s4, a2 /* save addr of destination */ // 重定向的目标地址
/*
*Set up the stack
*/
stack_setup: // 栈初始化
#if CONFIG_IS_ENABLED(SMP)
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, s2, t0
#else
mv sp, s2
#endif
la t0, _start // 计算重定向需要的偏移量,_start是入口地址,即:0x8020000;s4是重定向的目标地址
sub t6, s4, t0 /* t6 <- relocation offset */ // 重定向偏移量(t6) = 目标地址(s4, addr_moni) - 入口地址(t0,_start)
beq t0, s4, clear_bss /* skip relocation */ // 如果目标地址即是入口地址,即不需要搬移,跳转到BSS清零阶段运行
mv t1, s4 /* t1 <- scratch for copy_loop */
la t3, __bss_start
sub t3, t3, t0 /* t3 <- __bss_start_ofs */ // BSS段偏移量(t3) = 入口地址(t0,_start) - BSS地址(s3, __bss_start)
add t2, t0, t3 /* t2 <- source end address */ // 代码段末尾(t2) = 入口地址(t0,_start) + BSS段偏移量(t3)
copy_loop:
LREG t5, 0(t0)
addi t0, t0, REGBYTES
SREG t5, 0(t1)
addi t1, t1, REGBYTES
blt t0, t2, copy_loop
...
clear_bss:
la t0, __bss_start /* t0 <- rel __bss_start in FLASH */
add t0, t0, t6 /* t0 <- rel __bss_start in RAM */
la t1, __bss_end /* t1 <- rel __bss_end in FLASH */
add t1, t1, t6 /* t1 <- rel __bss_end in RAM */
beq t0, t1, relocate_secondary_harts
...
relocate_secondary_harts:
#if CONFIG_IS_ENABLED(SMP)
... // Duo S 单核,SMP内容忽略
#endif
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
call_board_init_r:
jal invalidate_icache_all
jal flush_dcache_all
la t0, board_init_r /* offset of board_init_r() */
add t4, t0, t6 /* real address of board_init_r() */ // board_init_r重定向后的地址 = 原地址 + 重定向偏移量(t6)
/*
* setup parameters for board_init_r
*/
mv a0, s3 /* gd_t */ // 参数{gd_t, dest_addr}
mv a1, s4 /* dest_addr */
/*
* jump to it ...
*/
jr t4 /* jump to board_init_r() */ // 调用board_init_r(重定向后)
其中,关键信息:
Lubancat2_RK3568_ARM
#--------------- u-boot/arch/arm/cpu/armv8/start.S
.globl _start
_start:
...
master_cpu:
bl _main
#--------------- u-boot/arch/arm/lib/crt0.S
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
...
ldr r0, =(CONFIG_SYS_INIT_SP_ADDR)
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
mov sp, r0
bl board_init_f_alloc_reserve
mov sp, r0
/* set up gd here, outside any C code */
mov r9, r0
bl board_init_f_init_reserve
bl board_init_f_boot_flags
bl board_init_f // 调用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 r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
mov sp, r0
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
adr lr, here
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
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 */
b relocate_code // 执行重定向
#endif
here:
...
/*
* now relocate vectors
*/
bl relocate_vectors
c_runtime:
/* Set up final (full) environment */
bl c_runtime_cpu_setup /* we still call old routine here */
... // C环境初始化
/* 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_r
/* we should not return here. */
-
执行前置的(front)初始化操作,调用board_init_f接口
- 清除BBS段
- 执行relocation操作
-
执行后置的(rear)初始化操作,调用board_init_r接口
初始化流程
board_init_f
u-boot/common/board_f.c:992:void board_init_f(ulong boot_flags)
u-boot/common/spl/spl.c:708: * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
u-boot/common/spl/Kconfig:135: stack available. Since SPL sets up DRAM while in its board_init_f()
u-boot/common/spl/Kconfig:139: board_init_f() completes, and before board_init_r() starts.
Binary file u-boot/common/built-in.o matches
# common/board_f.c
void board_init_f(ulong boot_flags)
{
if (initcall_run_list(init_sequence_f))
hang();
static const init_fnc_t init_sequence_f[] = {
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
#endif
#ifdef CONFIG_TRACE
trace_early_init,
#endif
initf_malloc,
log_init,
initf_bootstage, /* uses its own timer, so does not need DM */
#ifdef CONFIG_BLOBLIST
bloblist_init,
#endif
setup_spl_handoff,
initf_console_record,
#if defined(CONFIG_HAVE_FSP)
arch_fsp_init,
#endif
arch_cpu_init, /* basic arch cpu dependent setup */
mach_cpu_init, /* SoC/machine dependent CPU setup */
initf_dm,
arch_cpu_init_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
/* get CPU and bus clocks according to the environment variable */
get_clocks, /* get CPU and bus clocks (etc.) */
#endif
#if !defined(CONFIG_M68K)
timer_init, /* initialize timer */
#endif
#if defined(CONFIG_BOARD_POSTCLK_INIT)
board_postclk_init,
#endif
env_init, /* initialize environment */
init_baud_rate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_options, /* say that we are here */
display_text_info, /* show debugging info if required */
#if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
checkcpu,
#endif
#if defined(CONFIG_SYSRESET)
print_resetinfo,
#endif
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DTB_RESELECT)
embedded_dtb_select,
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
show_board_info,
#endif
INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
misc_init_f,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
#if defined(CONFIG_VID) && !defined(CONFIG_SPL)
init_func_vid,
#endif
announce_dram_init,
dram_init, /* configure available RAM banks */
#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,
#ifdef CONFIG_PRAM
reserve_pram,
#endif
reserve_round_4k,
#ifdef CONFIG_ARM
reserve_mmu,
#endif
reserve_video,
reserve_trace,
reserve_uboot,
reserve_malloc,
reserve_board,
setup_machine,
reserve_global_data,
reserve_fdt,
reserve_bootstage,
reserve_bloblist,
reserve_arch,
reserve_stacks,
dram_init_banksize,
show_dram_config,
#if defined(CONFIG_M68K) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || \
defined(CONFIG_SH)
setup_board_part1,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
INIT_FUNC_WATCHDOG_RESET
setup_board_part2,
#endif
display_new_sp,
#ifdef CONFIG_OF_BOARD_FIXUP
fix_fdt,
#endif
INIT_FUNC_WATCHDOG_RESET
reloc_fdt,
reloc_bootstage,
reloc_bloblist,
setup_reloc,
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
copy_uboot_to_ram,
do_elf_reloc_fixups,
clear_bss,
#endif
#if defined(CONFIG_XTENSA)
clear_bss,
#endif
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
!CONFIG_IS_ENABLED(X86_64)
jump_to_copy,
#endif
NULL,
};
board_init_r
# common/board_r.c
static init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
/* TODO: could x86/PPC have this also perhaps? */
#ifdef CONFIG_ARM
initr_caches,
/* 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 available
* until board_init() is called below to remap IFC to high
* region.
*/
#endif
initr_reloc_global_data,
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
initr_unlock_ram_in_cache,
#endif
initr_barrier,
initr_malloc,
log_init,
initr_bootstage, /* Needs malloc() but has its own timer */
initr_console_record,
#ifdef CONFIG_SYS_NONCACHED_MEMORY
initr_noncached,
#endif
bootstage_relocate,
#ifdef CONFIG_OF_LIVE
initr_of_live,
#endif
#ifdef CONFIG_DM
initr_dm,
#endif
#ifdef CONFIG_BSP_SPEC
initr_func_bsp,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \
defined(CONFIG_SANDBOX)
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
#ifdef CONFIG_EFI_LOADER
efi_memory_init,
#endif
stdio_init_tables,
initr_serial,
initr_announce,
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_NEEDS_MANUAL_RELOC
initr_manual_reloc_cmdtable,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
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_POST
initr_post_backlog,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
* Do early PCI configuration _before_ the flash gets initialised,
* because PCU resources are crucial for flash access on some boards.
*/
initr_pci,
#endif
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r,
#endif
power_init_board,
#ifdef CONFIG_MTD_NOR_FLASH
initr_flash,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86)
/* initialize higher level parts of CPU like time base and timers */
cpu_init_r,
#endif
#ifdef CONFIG_CMD_NAND
initr_nand,
#endif
#ifdef CONFIG_CMD_ONENAND
initr_onenand,
#endif
#ifdef CONFIG_MMC
initr_mmc,
#endif
initr_env,
#ifdef CONFIG_SYS_BOOTPARAMS_LEN
initr_malloc_bootparams,
#endif
INIT_FUNC_WATCHDOG_RESET
initr_secondary_cpu,
#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
mac_read_from_eeprom,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
* Do pci configuration
*/
initr_pci,
#endif
stdio_add_devices,
initr_jumptable, // standalone 相关跳转表
#ifdef CONFIG_API
initr_api,
#endif
console_init_r, /* fully init console as a device */
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
console_announce_r,
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,
#endif
interrupt_init,
#ifdef CONFIG_ARM
initr_enable_interrupts,
#endif
#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K)
timer_init, /* initialize timer */
#endif
#if defined(CONFIG_LED_STATUS)
initr_status_led,
#endif
/* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NET
initr_ethaddr,
#endif
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
#if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI)
INIT_FUNC_WATCHDOG_RESET
initr_scsi,
#endif
#ifdef CONFIG_BITBANGMII
initr_bbmii,
#endif
#ifdef CONFIG_CMD_NET
INIT_FUNC_WATCHDOG_RESET
initr_net,
#endif
#ifdef CONFIG_POST
initr_post,
#endif
#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_IDE)
initr_pcmcia,
#endif
#if defined(CONFIG_IDE) && !defined(CONFIG_BLK)
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)
initr_mem,
#endif
run_main_loop,
};
参考
- u-boot启动流程分析(2)_板级(board)部分;
- 内存分布