broadcom学习心得

broadcom学习心得

路由器启动流程学习心得:

  • bootloader启动流程

Bootloader启动大多数都分为两个阶段。第一阶段主要包含依赖于CPU的体系结构硬件初始化的代码,通常都用汇编语言来实现。这个阶段的任务有:
基本的硬件设备初始化(屏蔽所有的中断、关闭处理器内部指令/数据Cache等)。
为第二阶段准备RAM空间。
如果是从某个固态存储媒质中,则复制Bootloader的第二阶段代码到RAM。
设置堆栈。
跳转到第二阶段的C程序入口点。
第二阶段通常用C语言完成,以便实现更复杂的功能,也使程序有更好的可读性和可移植性。这个阶段的任务有:
初始化本阶段要使用到的硬件设备。
检测系统内存映射。
将内核映像和根文件系统映像从Flash读到RAM。
为内核设置启动参数。
调用内核。(借鉴)

broadcom芯片引导系统属于自己修改的bootloader,简称CFE。在具体的代码上可以细分为三部分:Bootrom、Cferom、Cfeam。
启动流程可以分为三阶段:
1. 上电或复位之后,CPU执行的最初指令即Bootrom,进行基本的硬件的硬件检查和初始化。
2、Cferom包含两个阶段,第一阶段属于汇编语言,初始化环境,拷贝Cferom到SRAM;第二阶段进行CPU和DDR的初始化,并将Cferam从FLASH加载到DDR中,并跳转到Cferam的地址上。
3、Cferam同样会执行两个阶段,第一阶段初始化相关的硬件环境,配置硬件设备;第二阶段加载kernel、dtb、rootfs、logfs等到DDR中。

详细分析
1、Cferom启动流程:
HELO
CPU0
PMCM
PMCS
PMCD
CODE
L1CD
MMUI
ZBBS
MAIN

执行arch/arm/common/src/init_arm.S.
切到系统模式,关中断;
判断CPU类型;
初始化缓存;
拷贝cferom到SRAM,配置堆栈;
开启MMU,清BSS段;
在内部 RAM 中设置堆栈指针以调用cferom的c_main函数;

PASS
FPS0
CFE1
BT00
0156
NAN3
RFS3
NAN5

c_main函数: board/bcm63xx_rom/src/bcm63xx_main.c
函数主体包含bootInit、ddrInit、boot_media,主要进行CPU和DDR的初始化工作。
bootInit主要进行CPU一些引导寄存器、LDO、时钟、flash等的初始化。针对一些特殊的板极会有其他不同的操作,如拷贝NVRAM到ddr相应地址,PMC初始化等。
ddrInit主要进行ddr的初始化工作,其中会根据ulMemoryConfig这个标志位判断是否进行DDR的格式化操作。
boot_media根据当前要启动的image,计算需要拷贝的cferam对应的flash的位置和大小,拷贝到DDR中,最后跳转到cferam对应的位置。

2、Cferam启动流程

2.1、执行arch/arm/common/src/init_arm.S.
根据宏控配置Cferom未执行的相关操作;
从FLASH拷贝cferam到SRAM;
在内部 DDR中设置堆栈指针以调用Cferam的c_main函数;

备注:
1、这个文件属于Cferom和Cferam的通用代码,利用宏控进行区分具体的操作;
2、从FLASH中拷贝拷贝Cferom时,未进行FLASH的初始化,主要是因为Cferom位于FLASH的起始位置,且内存较小,同时博通的另外做法是直接将FLASH中Cferom映射到SRAM上;

2.2、Cferam跳转到board/bcm63xx_ram/src/bcm63xx_main.c中。
完成硬件的初始化,包括外部设备的初始化,image更新,引导kernel等。
calculateCpuSpeed(); /* 通过读取 PLL 配置寄存器计算CPU 速度 */
cfe_timer_init(); /* 初始化定时器 */
board_console_init(); /* 初始化串口 */
cfe_setup_exceptions(); /* 配置异常处理 */
cfe_say_hello(); /* CFE开始信息 */
cfe_startup_info(); /* 输出环境信息,例如存储空间使用情况 */
board_device_init(); /* 配置LED、phy、pinmux等 */
cfe_setup_default_env(); /* 初始化CFE默认环境 */
ui_init_cmddisp();
getBootLine(0);
getBoardParam(); /* 根据command输入更新信息 */
board_final_init(rc); /* 硬件部分初始化,配置pinmux,判断cfe模式下是否操作,无操作直接从flash加载kernel */
cfe_command_loop(); /* CFE终端循环等待 */

其中重点解释下board_final_init的流程,因为涉及的流程较多,系统升级之后出现问题,大多都在里面。
board_final_init
|
bcm63xx_run
|
bcm63xx_run_ex /* 更新ulMemoryConfig,初始化cfe下相关命令 */
|
auto_run /* 根据cfe终端输入加载网络端或是本地image */
|
bootNandImage /* 根据当前启动的image配置start_blk和end_blk */
|
bootNandImageFromRootfs /* 从flash拷贝image,进行解压操作,并设置好跳转指针 */
|
cfe_go(la)
|
cfe_start(la->la_entrypt)
|
cfe_launch(ept) /* 跳转到kernel */

bootNandImageFromRootf会进行kernel和rootfs的拷贝,并在DDR中进行解压,其中会根据当前FLASH打包的魔数判断读取格式。

猜你喜欢

转载自blog.csdn.net/lx19920701/article/details/82350001