机器从上电后先运行BROM中一段固定的代码,BROM会读取外部引脚来决定从何种介质来启动系统,BROM的作用是初始化储存启动系统的介质,如flash,emmc等。然后从启动介质中读取boot0代码到芯片内部的SRAM中,然后跳到boot0的boot0_entry.S(sunxi_spl/boot0/main/)


代码流程:
1. boot0阶段调用的函数(注册函数,编译在代码中)
SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
2.boot0阶段启动
void main(void) //位置:spl-pub/nboot/main/boot0_main.c
//SUNXI板子初始化,全志未提供源码
sunxi_board_init_early()
//初始化串口
sunxi_serial_init(BT0_head.prvt_head.uart_port, (void *)BT0_head.prvt_head.uart_ctrl, 6);
//打印boot0启动信息
print_commit_log();
printf("HELLO! BOOT0 is starting!\n");
printf("BOOT0 commit : %s\n", BT0_head.hash);
sunxi_set_printf_debug_mode(BT0_head.prvt_head.debug_mode, 0);
//SUNXI板子初始化,全志未提供源码
sunxi_board_init()
//检测到串口输入为2,可以阻止当前运行
char uart_input_value = get_uart_input(); /* Prevent DRAM jamming */
if (uart_input_value == '2')
printf("detected_f user input 2\n");
dram_size = init_DRAM(0, (void *)BT0_head.prvt_head.dram_para)
pr_emerg("dram size =%d\n", dram_size);
uart_input_value = get_uart_input();
if (uart_input_value == '2') {
sunxi_set_printf_debug_mode(3, 0);
printf("detected_r user input 2\n");
goto _BOOT_ERROR;
} else if (uart_input_value == 'd') {
sunxi_set_printf_debug_mode(8, 1);
printf("detected user input d\n");
} else if (uart_input_value == 'q') {
printf("detected user input q\n");
sunxi_set_printf_debug_mode(0, 1);
}
malloc_init(CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE);
status = sunxi_board_late_init();
status = load_package();
if (status == 0)
load_image(&uboot_base, &optee_base, &monitor_base, &rtos_base, &opensbi_base, &cpus_rtos_base);
//输出跳转信息
printf("Jump to second Boot.\n");
文章详细描述了嵌入式设备上电后的启动过程,从BROM加载固定代码开始,初始化存储介质,如flash和emmc,接着执行boot0阶段。boot0主要功能包括初始化板级设置,设置串口,检测用户输入,并加载后续的启动映像。此外,提到了sunxi系列芯片的特定操作,如sunxi_board_init和dram初始化。
891

被折叠的 条评论
为什么被折叠?



