首页 >> 大全

AM335X启动(转)

2023-11-10 大全 28 作者:考证青年

参考文件:

1、TI..pdf

2、.pdf

芯片到uboot启动流程 :ROM→ MLO(SPL)→uboot.img。

rom为芯片内部的固化的程序,用户不能修改。内部rom程序流程:

的方式可以通过引脚[15...0]来配置。[15...0]=[15...0]引脚,这些引脚的状态会被上电复位后获取。

中被分成了 3 个部分:

第一级 :引导加载程序,板子上电后会自动执行这些代码,如选择哪种方式启动(NAND,,UART。。。),然后跳转转到第二级 。这些代码应该是存放在 176KB 的 ROM 中。

第二级 :MLO(SPL),用以硬件初始化:关闭看门狗,关闭中断,设置 CPU 时钟频率、速度等操作。然后会跳转到第三级。MLO文件应该会被映射到 64 KB的 SRAM 中。

第三级 :uboot.img,C代码的入口。

其中第一级 是板子固化的,第二级和第三级是通过编译 uboot 所得的。

u-boot-SPL编译

也就是说spl的编译是编译uboot的一部分,和uboot.bin走的是两条编译流程,这个要重点注意。正常来说,会先编译主体uboot,也就是uboot.bin.再编译uboot-spl,也就是uboot-spl.bin,虽然编译命令是一起的,但是编译流程是分开的。

在uboot的顶层目录中有:

spl/u-boot-spl.bin: spl/u-boot-spl

@:

spl/u-boot-spl: tools (if(if(),dts/dt.dtb)(Q)(Q)(MAKE) obj=spl -f $()//.spl all

指出编译u-boot-spl.bin的链接是在u-boot的顶层目录下的/make.spl里定义的,且要编译u-boot-spl.bin首先要定义(在u-boot的顶层目录下的目录对应的有定义)

在文件/.spl中:

spl/u-boot-spl.bin依赖如下

||

spl/u-boot-spl-nodtb.bin

||

spl/u-boot-spl

||

u-boot-spl-init, u-boot-spl-main, spl/u-boot-spl.ld 最后通过cmd_u-boot-spl来生成spl/u-boot-spl。

重点定义:

1、:/,用于指定是否需要编译SPL,也就是是否需要编译出uboot-spl.bin文件

2、 定义在板子的对应的文件中

3、

U-boot-spl代码流程

通过u-boot-spl编译的脚本(.spl)知u-boot-spl入口:u-boot-2016.03/arch/arm/cpu/armv7/u-boot-spl.lds

ENTRY(_start)

所以uboot-spl的代码入口函数是

对应于路径-X/u-boot/arch/arm/lib/.S的,后续就是从这个函数开始分析。

uboot-spl需要做的事情

CPU初始刚上电的状态。需要小心的设置好很多状态,包括cpu状态、中断状态、MMU状态等等。

在armv7架构的uboot-spl,主要需要做如下事情

加载u-boot.img,跳转到u-boot.img.

上述工作,也就是uboot-spl代码流程的核心。

代码流程 1、代码整体流程

代码整体流程如下,以下列出来的就是spl核心函数。

———–>reset————–>关闭中断

………………………………|

启动转换6136什么意思_启动机一直转_

………………………………———->———–>关闭MMU,TLB

………………………………|

………………………………———->————->————->CPU级初始化

………………………………|

………………………………———->_main————–> & serve & ———->加载u-boot.img,跳转到u-boot.img.

,执行时已经是C语言环境了。在这里需要结束掉SPL的工作,跳转到u-boot.img中。

2、

上述已经说明了是整个spl的入口,其代码如下:

arch/arm/lib/.S

_start:#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG.word   CONFIG_SYS_DV_NOR_BOOT_CFG
#endifb   reset

会跳转到reset中。注意,spl的流程在reset中就应该被结束,也就是说在reset中,就应该转到到BL2,也就是uboot中了。

后面看reset的实现。

3、reset

建议先参考[ 启动流程] (第二章)第一阶段之——设置SVC、关闭中断,了解一下为什么要设置SVC、关闭中断以及如何操作。目的:svc模式主要用于软件中断和OS操作系统。若是中断未关闭,CPU在初始化阶段有可能产生中断,但是中断处理函数还未就绪(未对中断进行处理),容易使CPU halt停止工作。

代码如下:

arch/arm/cpu/armv7/start.S

.globl  reset.globl  save_boot_params_retreset:/* 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, cpsrand r1, r0, #0x1f       @ mask mode bitsteq r1, #0x1a       @ test for HYP modebicne   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 @@ 以上通过设置CPSR寄存器里设置CPU为SVC模式,禁止中断 @@ 具体操作可以参考《[kernel 启动流程] (第二章)第一阶段之——设置SVC、关闭中断》的分析 /* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_cp15 @@ 调用cpu_init_cp15,初始化协处理器CP15,从而禁用MMU和TLB。 @@ 后面会有一小节进行分析 bl cpu_init_crit @@ 调用cpu_init_crit,进行一些关键的初始化动作,也就是平台级和板级的初始化 @@ 后面会有一小节进行分析 #endif bl _main @@ 跳转到主函数,也就是要加载BL2以及跳转到BL2的主体部分

4、

建议先参考[ 启动流程] (第六章)第一阶段之——打开MMU两篇文章的分析。

主要用于对cp15协处理器进行初始化,其主要目的就是关闭其MMU和TLB。

代码如下(去掉无关部分的代码):

arch/arm/cpu/armv7/start.S

ENTRY(cpu_init_cp15)/** Invalidate L1 I/D*/mov r0, #0          @ set up for MCRmcr p15, 0, r0, c8, c7, 0   @ invalidate TLBsmcr 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 @@ 这里只需要知道是对CP15处理器的部分寄存器清零即可。 @@ 将协处理器的c7\c8清零等等,各个寄存器的含义请参考《ARM的CP15协处理器的寄存器》 /* * 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 #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 @@ 通过上述的文章的介绍,我们可以知道cp15的c1寄存器就是MMU控制器 @@ 上述对MMU的一些位进行清零和置位,达到关闭MMU和cache的目的,具体的话去看一下上述文章吧。 ENDPROC(cpu_init_cp15)

5、

,进行一些关键的初始化动作,也就是平台级和板级的初始化。其代码核心就是,如下

arch/arm/cpu/armv7/start.S

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)

所以说就是这个函数的核心。一般是由板级代码自己实现的。但是对于某些平台来说,也可以使用通用的,其定义在arch/arm/cpu/armv7/.S中

以为例,在移植过程中,就需要在.S里加入一些简单的板级初始化,例如在.s------->中:

arch/arm/cpu/armv7//board.c

void s_init(void)
{
/*
* The ROM will only have set up sufficient pinmux to allow for the
* first 4KiB NOR to be read, we must finish doing what we know of
* the NOR mux in this space in order to continue.
*/
#ifdef CONFIG_NOR_BOOT
enable_norboot_pin_mux();
#endif
watchdog_disable();               //arch/arm/cpu/armv7/am33xx/board.cset_uart_mux_conf();            // xx/board/ti/am335x/board.c
setup_clocks_for_console();   // arch/arm/cpu/armv7/am335x/Clock_am33xx.c
uart_soft_reset();                 // arch/arm/cpu/armv7/am33xx/board.c
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)  // include/configs/ti_am335x_common.h
/* Enable RTC32K clock */
rtc32k_enable();                  // arch/arm/cpu/armv7/am33xx/board.c
#endif
}

(其实只要实现了了就好,没必要说在哪里是实现,但是通常规范都是创建了.S来专门实现函数)。

6、_main

spl的main的主要目标是调用进行先前的板级初始化动作,板级初始化之后调用主要设计为,加载u-boot.img到DDR上并且跳转到u-boot.img中。DDR在板级初始化中完成--。

由于是以C语言的方式实现,所以需要先构造C语言环境。

注意:uboot-spl和uboot的代码是通用的,其区别就是通过宏来进行区分的。

所以以下代码中,我们只列出spl相关的部分,也就是被包含的部分。

arch/arm/lib/crt0.S

ENTRY(_main)/*
* Set up initial C runtime environment and call board_init_f(0). 因为后面是C语言环境,首先是设置堆栈
*/#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr    sp, =(CONFIG_SPL_STACK)                                                   //设置堆栈为后边调用board_init_f做准备
#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                                     //2. 为gd_t结构体保留空间理论上有些函数可以用了,例如:preloader_console_init()初始化串口,common/init/board_init.cmov    sp, r0
/* set up gd here, outside any C code */
mov    r9, r0
bl    board_init_f_init_reserve                      //3. 初始化gd_t(清零)  common/init/board_init.c//gd_t的地址存在r9寄存器中,结构体中存放的是全局参数                 
mov r0, #0
bl    board_init_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 */
sub    r9, r9, #GD_SIZE    /* new GD is below bd */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
here:
/*
* now relocate vectors
*/bl    relocate_vectors/* Set up final (full) environment */bl    c_runtime_cpu_setup    /* we still call old routine here */
#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
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 */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
bl 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! */
#endif
/* we should not return here. */
#endifENDPROC(_main)

代码拆分如下:

(1)因为后面是C语言环境,首先是设置堆栈

ldr sp, =(CONFIG_SPL_STACK)
@@ 设置堆栈为CONFIG_SPL_STACKbic sp, sp,#7  /* 8-byte alignment for ABI compliance */
@@ 堆栈是8字节对齐,2^7bit=2^3byte=8byte mov r0, sp @@ 把堆栈地址存放到r0寄存器中

关于,我们通过前面的文章

我们已经知道的BL1(spl)是运行在RAM的,并且RAM的地址空间是-,RAM前面的部分放的是BL1的代码部分,所以把RAM最后的空间用来当作堆栈。

所以定义如下:

//.h

--->.h

---->.h

#define CONFIG_SPL_STACK    (0x402F0400+32*1024+32*1024+8*1024-4)//自己计算结果可能不正确

注意:上述还不是最终的堆栈地址,只是暂时的堆栈地址!!!

(2)为GD分配空间

bl  board_init_f_alloc_reserve
@@ 把堆栈的前面一部分空间分配给GD使用mov sp, r0
@@ 重新设置堆栈指针SP/* set up gd here, outside any C code */mov r9, r0
@@ 保存GD的地址到r9寄存器中

注意:虽然sp的地址和GD的地址是一样的,但是堆栈是向下增长的,而GD则是占用该地址后面的部分,所以不会有冲突的问题。关于GD,也就是 ,可以简单的理解为uboot的全局变量都放在了这里,比较重要,所以后续有会写篇文章说明一下。这里只需要知道在开始C语言环境的时候需要先为这个结构体分配空间。

实现如下

/init/.c

ulong board_init_f_alloc_reserve(ulong top)
{/* Reserve early malloc arena *//* LAST : reserve GD (rounded up to a multiple of 16 bytes) */top = rounddown(top-sizeof(struct global_data), 16); // 现将top(也就是r0寄存器,前面说过存放了暂时的指针地址),减去sizeof(struct global_data),也就是预留出一部分空间给sizeof(struct global_data)使用。 // rounddown表示向下16个字节对其 return top; // 到这里,top就存放了GD的地址,也是SP的地址 //把top返回,注意,返回后,其实还是存放在了r0寄存器中。 }

还有一点,其实GD在spl中没什么使用,主要是用在uboot中,但在uboot中的时候还需要另外分配空间,在讲述uboot流程的时候会说明。

(3)初始化GD空间

前面说了,此时r0寄存器存放了GD的地址。

bl  board_init_f_init_reserve

serve实现如下

/init/.c

编译SPL的时候宏没有打开,所以我们去掉了的无关部分。

void board_init_f_init_reserve(ulong base)
{struct global_data *gd_ptr;int *ptr;/** clear GD entirely and set it up.* Use gd_ptr, as gd may not be properly set yet.*/gd_ptr = (struct global_data *)base; // 从r0获取GD的地址 /* zero the area */ for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); ) *ptr++ = 0; // 对GD的空间进行清零 }

(4)跳转到板级前期的初始化函数中

u-boot-2016.03/arch/arm/cpu/armv7//board.c

如下代码

bl  board_init_f

需要由板级代码自己实现。

u-boot-2016.03/arch/arm/cpu/armv7//board.c

1 void board_init_f(ulong dummy)
2 {
3 board_early_init_f();
4 preloader_console_init();  //初始化uart,使用Puts函数
5 sdram_init();
6 }

u-boot-2016.03/arch/arm/cpu/armv7//board.c

1 int board_early_init_f(void)
2 {
3     prcm_init();    //系统外设时钟初始化使能,SPI,I2C,uart,gpio.....
4     set_mux_conf_regs();  //系统外设引功能配置,spi,I2C,uart,gpio.
5     return 0;
6 }

u-boot-2016.03/arch/arm/cpu/armv7//clock.c

1 void prcm_init()
2 {
3     enable_basic_clocks();
4     scale_vcores();
5     setup_dplls();
6 }

u-boot-2016.03/board/ti//board.c

void set_mux_conf_regs(void)
{__maybe_unused struct am335x_baseboard_id header;if (read_eeprom(&header) < 0)puts("Could not get board ID.\n");enable_board_pin_mux(&header);puts("enable_board_pin.\n");
}

u-boot-2016.03/board/ti//MUX.c

void enable_board_pin_mux(struct am335x_baseboard_id *header)
{/* Do board-specific muxes. */if (board_is_bone(header)) {/* Beaglebone pinmux */configure_module_pin_mux(mii1_pin_mux);configure_module_pin_mux(mmc0_pin_mux);
#if defined(CONFIG_NAND)configure_module_pin_mux(nand_pin_mux);
#elif defined(CONFIG_NOR)configure_module_pin_mux(bone_norcape_pin_mux);
#elseconfigure_module_pin_mux(mmc1_pin_mux);
#endif} else if (board_is_gp_evm(header)) {/* General Purpose EVM */unsigned short profile = detect_daughter_board_profile();configure_module_pin_mux(rgmii1_pin_mux);configure_module_pin_mux(mmc0_pin_mux);/* In profile #2 i2c1 and spi0 conflict. */if (profile & ~PROFILE_2)configure_module_pin_mux(i2c1_pin_mux);/* Profiles 2 & 3 don't have NAND */
#ifdef CONFIG_NANDif (profile & ~(PROFILE_2 | PROFILE_3))configure_module_pin_mux(nand_pin_mux);
#endifelse if (profile == PROFILE_2) {configure_module_pin_mux(mmc1_pin_mux);configure_module_pin_mux(spi0_pin_mux);}} else if (board_is_idk(header)) {/* Industrial Motor Control (IDK) */configure_module_pin_mux(mii1_pin_mux);configure_module_pin_mux(mmc0_no_cd_pin_mux);} else if (board_is_evm_sk(header)) {/* Starter Kit EVM */configure_module_pin_mux(i2c1_pin_mux); // 配置I2C1对应的引脚为功能引脚,u-boot-2016.03/board/ti/am335x/mux.cconfigure_module_pin_mux(gpio0_7_pin_mux);configure_module_pin_mux(rgmii1_pin_mux);configure_module_pin_mux(mmc0_pin_mux_sk_evm);} else if (board_is_bone_lt(header)) {/* Beaglebone LT pinmux */configure_module_pin_mux(mii1_pin_mux);configure_module_pin_mux(mmc0_pin_mux);
#if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT)configure_module_pin_mux(nand_pin_mux);
#elif defined(CONFIG_NOR) && defined(CONFIG_EMMC_BOOT)configure_module_pin_mux(bone_norcape_pin_mux);
#elseconfigure_module_pin_mux(mmc1_pin_mux);
#endif} else {puts("Unknown board, cannot configure pinmux.");hang();}
}

也就是说

void (ulong dummy)

1、------>(u-boot-2016.03/arch/arm/cpu/armv7//clock.c)------->(u-boot- 使能CPU各外设包括gpio时钟 2016.03/arch/arm/cpu/armv7//.c)

------>(u-boot-2016.03/board/ti//board.c)------>(&)配置板级各外设引脚功能(UART,MMC,SPI,)u-boot-2016.03/board/ti//Mux.c

2、()--------------》(u-boot-2016.03/board/ti//board.c)

--------->未完待续

SDRAM初始化,只有SDRAM初始化完成了,才能为下一步的u-boot运行提供运行环境,这一部分也是要根据板上的SDRAM芯片型号来初始化的。

u-boot-2016.03/board/ti//board.c

void sdram_init(void)
{__maybe_unused struct am335x_baseboard_id header;if (read_eeprom(&header) < 0)puts("Could not get board ID.\n");if (board_is_evm_sk(&header)) {/** EVM SK 1.2A and later use gpio0_7 to enable DDR3.* This is safe enough to do on older revs.*/gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en"); //请求GPIO0_7脚是否有效,AM335x共有GPIO=32*4.如果GPIO_DDR_VTT_EN的数值在0~127之间,返回0gpio_direction_output(GPIO_DDR_VTT_EN, 1);//使GPIO的第8脚,GPIO0_7输出1,使能SDRAM芯片的电源}if (board_is_evm_sk(&header))config_ddr(303, &ioregs_evmsk, &ddr3_data,&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);else if (board_is_bone_lt(&header))config_ddr(400, &ioregs_bonelt,&ddr3_beagleblack_data,&ddr3_beagleblack_cmd_ctrl_data,&ddr3_beagleblack_emif_reg_data, 0);else if (board_is_evm_15_or_later(&header))config_ddr(303, &ioregs_evm15, &ddr3_evm_data,&ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);elseconfig_ddr(266, &ioregs, &ddr2_data,&ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);debug(">>spl:SDRAM_init()\n");puts(">>spl:SDRAM_init()\n");}

板级的初级初始化之后()会为后续的调用()函数提供更多的堆栈的空间(放在了SDRAM中)

bl d

u-boot-2016.03//spl/spl.c

ulong spl_relocate_stack_gd(void)
{
#ifdef CONFIG_SPL_STACK_Rgd_t *new_gd;ulong ptr = CONFIG_SPL_STACK_R_ADDR;#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLEif (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {if (!(gd->flags & GD_FLG_SPL_INIT))panic_str("spl_init must be called before heap reloc");ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;gd->malloc_base = ptr;gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;gd->malloc_ptr = 0;}
#endif/* Get stack position: use 8-byte alignment for ABI compliance */ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);new_gd = (gd_t *)ptr;memcpy(new_gd, (void *)gd, sizeof(gd_t));
#if !defined(CONFIG_ARM)gd = new_gd;
#endifreturn ptr;
#elsereturn 0;
#endif
}

堆栈空间分配好之后就可以用了。

u-boot-2016.03//spl/spl.c

board_init_r
{1、经行memory的malloc池的初始化2、timer_init() 初始化时钟 arch/arm/cpu/armv7/omap_common3、spl_board_init() arch/arm/cpu/armv7/omap_common/boot-common.c4、jump_to_image_no_args(&spl_image) // 跳转u-boot入口地址 entry_point,entry_point是由u-boot.img头部信息提供的
5、SPL结束其生命,将控制权交给u-boot/Linux
}

arch/arm/cpu/armv7/omap_common/boot-common.c

void spl_board_init(void)
{/** Save the boot parameters passed from romcode.* We cannot delay the saving further than this,* to prevent overwrites.*/save_omap_boot_params(); // 这里讲boot_device的参数传递给spl_boot_list(自己理解),确定以什么方式加载u-boot.img(uart or spi or mmc or nand....)/* Prepare console output */// preloader_console_init();#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)gpmc_init();
#endif
#ifdef CONFIG_SPL_I2C_SUPPORTi2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
#endif
#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)arch_misc_init();
#endif
#if defined(CONFIG_HW_WATCHDOG)hw_watchdog_init();
#endif
#ifdef CONFIG_AM33XXam33xx_spl_board_init();
#endif
}

更加详细的启动顺序,及相关内存地址分配参考:

链接: 密码: m9ci

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了