UBOOT stage2 board_init_r();函数到引导内核流程

本文详细介绍了UBOOT的stage2引导流程,重点解析了board_init_r()函数如何启动内核。在board_init_r()中,通过main_loop()循环,当无按键输入时,执行autoboot_command()进入内核加载,否则进入命令行模式。通过cmd_call()调用cmd_tbl_s结构体中定义的处理函数,如do_bootm用于加载内核。
摘要由CSDN通过智能技术生成

转载 : http://blog.csdn.net/u014381531/article/details/52062257

本人用的是friendlyarm smart4418的板子,用的也是从其github clone下来的uboot-nanopi2的源码,感觉这个uboot特别的复杂,跟网上很多其余板子的教程有很多地方不同,此篇博客是学习的一点记录,欢迎广大网友指正。

上面的一篇博客给了很大帮助,也有别的很多优秀的博客,就没有一一列举。


UBOOT分为两个阶段,第一个阶段主要是汇编代码在START.S文件中实现。在stage1的最后初始化堆栈等操作为stage2C语言的运行提供了环境,最后程序跳入C语言。

ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
	bic	sp, sp, #7					/* 8-byte alignment for ABI compliance */
	sub	sp, #GD_SIZE				/* allocate one GD above SP */
	bic	sp, sp, #7					/* 8-byte alignment for ABI compliance */
	mov	r9, sp						/* GD is above SP */
	mov	r0, #0
	bl	board_init_f

	mov	sp, r9						/* SP is GD's base address */
	bic	sp, sp, #7					/* 8-byte alignment for ABI compliance */
	sub	sp, #GENERATED_BD_INFO_SIZE	/* allocate one BD above SP */
	bic	sp, sp, #7					/* 8-byte alignment for ABI compliance */

	mov	r0, r9						/* gd_t *gd */
	ldr r1, TEXT_BASE				/* ulong text */
	mov r2, sp						/* ulong sp */
	bl	gdt_reset

	/* call board_init_r(gd_t *id, ulong dest_addr) */
	mov	r0, r9							/* gd_t */
	ldr	r1,  =(CONFIG_SYS_MALLOC_END)	/* dest_addr for malloc heap end */
	/* call board_init_r */
	ldr	pc, =board_init_r				/* this is auto-relocated! */

#else	/* CONFIG_RELOC_TO_TEXT_BASE */

	bl	_main
#endif

上图是我所用的uboot-nanopi2下arch/arm/cpu/slsip/s5p4418/start.s文件,跟网上的很多教程相比很相似,但是细究起来差别也蛮大的,就上面的代码来说,在擦除了bss后设置可sp指针,然后就跳入board_init_f();函数,在board_init.f函数里面,完成了一系列初始化后再调回来。gdt_reset进行gd结构体的初始化,最后进入到了board_init_r();函数,这个函数就是最后载入内核或者开始uboot命令行的操作。

board_init_f();board_init_r();函数在arch/arm/lib/目录下,board_init_r();函数的一系列初始化操作就不说了,因为我也还没有弄懂具体的初始化机制和原由,直奔主题-------怎么进去的内核。

下图是我粘贴的board_init_r();的完整内容,可以直接略过。

/************************************************************************
 *
 * This is the next part if the initialization sequence: we are now
 * running from RAM and have a "normal" C environment, i. e. global
 * data can be written, BSS has been cleared, the stack size in not
 * that critical any more, etc.
 *
 ************************************************************************
 */

void board_init_r(gd_t *id, ulong dest_addr)
{
	ulong malloc_start;
#if !defined(CONFIG_SYS_NO_FLASH)
	ulong flash_size;
#endif

	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
	bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");

	monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start;

	/* Enable caches */
	enable_caches();

	debug("monitor flash len: %08lX\n", monitor_flash_len);
	board_init();	/* Setup chipselects */
	/*
	 * 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
	serial_initialize();

	debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);

#ifdef CONFIG_LOGBUFFER
	logbuff_init_ptrs();
#endif
#ifdef CONFIG_POST
	post_output_backlog();
#endif

	/* The Malloc area is immediately below the monitor copy in DRAM */
	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);

#ifdef CONFIG_ARCH_EARLY_INIT_R
	arch_early_init_r();
#endif

#ifndef CONFIG_PMIC_REG_DUMP
	power_init_board();
#endif

#if !defined(CONFIG_SYS_NO_FLASH)
	puts("Flash: ");

	flash_size = flash_init();
	if (flash_size > 0) {
# ifdef CON
uboot是一种常用的开源引导加载程序,用于嵌入式系统的引导启动。其中,board_init_r和board_init_f是uboot中的两个重要函数board_init_r函数是在uboot启动过程中执行的第一个函数。它负责执行一系列的初始化工作,例如初始化系统时钟、设置内存映射等。此函数被用于配置和初始化各个硬件模块,包括中断控制器、串口控制器、定时器等,以确保系统正常运行。该函数还读取并解析配置文件,加载设备树等操作,为后续的引导加载准备好必要的条件。 board_init_f函数是在board_init_r函数之后调用的。它用于进一步初始化系统,并执行一些与硬件相关的操作。例如,该函数可能会初始化网络接口、USB接口、存储设备等,并设置系统的默认环境变量。此外,board_init_f函数还负责将uboot的控制权交给操作系统的引导加载程序,从而完成uboot的使命。 通过调用board_init_r和board_init_f函数,uboot能够在系统启动时完成各种硬件的初始化和配置工作。这两个函数是uboot启动过程中的重要环节,确保系统能够顺利地加载操作系统并运行。同时,它们也为开发者提供了扩展uboot的接口,可以在这两个函数中添加自定义的初始化代码,以满足系统特定的需求。 总结来说,board_init_r和board_init_f是uboot中两个重要的函数,用于初始化和配置嵌入式系统的硬件,并为操作系统的加载做好准备。它们是uboot启动过程中不可或缺的一部分,保证系统的正常启动和运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值