2020.1 u-boot C-SKY T910 启动分析

本文详细分析了2020.1版u-boot在C-SKY T910处理器上的启动过程,从start.S开始,经过board_init_f()和board_init_r()的两个阶段,再到DM驱动的加载流程。启动过程中涉及了内存设置、串口初始化以及设备初始化等关键步骤。
摘要由CSDN通过智能技术生成

2020.1 u-boot C-SKY T910 启动分析

说在前面:

我参考了yanggx0929的博客,链接在下面。有些对不上的内容就只能自己看了。他的u-boot的版本是2015.1,我现在看的是2020.1
他分了十几篇,我只准备整理总结对我有用的部分。
链接: yanggx0929的博客

先定位一下是哪个start.S

通过xconfig来看下具体配置的是什么
(make ARCH=riscv CROSS_COMPILE=~/host/bin/riscv64-unknown-linux-gnu- xconfig)
在这里插入图片描述
从配置上看,定位到的是arch/riscv/cpu/start.S

这个文件里面会调用 board_init_f()

// arch/riscv/cpu/start.S
// lowlevel_init(); 并不会调用,因为配置内存等操作在别的地方做了
// 前面主要是做了一些CPU级别的初始化
// line 185 调用 board_init_f();
	mv	a0, zero		/* a0 <-- boot_flags = 0 */
	la	t5, board_init_f
	jalr	t5			/* jump to board_init_f() */
// line 394  看注释是要进行第二阶段的init
/*
 * 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
	mv	t4, t0			/* offset of board_init_r() */
	add	t4, t4, t6		/* real address of board_init_r() */

而board_init_f()是在下面的文件里面定义的。
里面主要是 initcall_run_list()来进行模块的顺序初始化,传入的init_sequence_f就是函数序列

common/board_f.c

// line 1017
void board_init_f(ulong boot_flags)
{
   
	gd->flags = boot_flags;
	gd->have_console = 0;
    //initcall_run_list主要作用是初始化函数数组init_sequence_f.
	if (initcall_run_list(init_sequence_f))
		hang();
// 省略了几行
}
 //board_init_f函数的功能也是遍历函数指针数组init_sequence_f,并调用init_sequence中的每一个函数,并判定函数返回值是否正确 
static inline int initcall_run_list(const init_fnc_t init_sequence[])
{
   
	const init_fnc_t *init_fnc_ptr; //定义函数指针init_fnc_ptr
	int wh=0;

	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
    //遍历函数指针数组init_sequence_f
		unsigned long reloc_ofs = 0;
		int ret;
		wh++;
		/*
		 * Sandbox is relocated by the OS, so symbols always appear at
		 * the relocated address.
		 */
		if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC))
			reloc_ofs = gd->reloc_off;
#ifdef CONFIG_EFI_APP
		reloc_ofs = (unsigned long)image_base;
#endif
		if (reloc_ofs)
			printf("initcall: %p (relocated to %p)\n",
					(char *)*init_fnc_ptr - reloc_ofs,
					(char *)*init_fnc_ptr);
		else
			printf("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs);

		ret = (*init_fnc_ptr)(); //调用init_fnc_ptr指向的函数
		if (ret) {
   
			printf("initcall sequence %p failed at call %p (err=%d)\n",
			       init_sequence,
			       (char *)*init_fnc_ptr - reloc_ofs, ret);
			return -1;
		}
	}
	return 0;
}
// common/board_f.c  line 868
static const init_fnc_t init_sequence_f[] = {
   
	setup_mon_len, //setup_mon_len功能是根据链接文件中的__bss_end 和_start标签计算uboot的大小,并初始化给gd->mon_len
#ifdef CONFIG_OF_CONTROL
	fdtdec_setup, // 将dtb文件的地址放入gd->fdt_blob处
#endif
#ifdef CONFIG_TRACE_EARLY
	trace_early_init,
#endif
	initf_malloc, // 设置gd->malloc_limit和gd->malloc_ptr参数
	log_init, // 是将.u_boot_list_2_log_driver_3和.u_boot_list_2_log_driver_1之间的所有struct log_driver结构体都加入到了gd->log_head的循环链表中,并初始化gd->default_log_level和gd->log_fmt
	initf_bootstage,	/* uses its own timer, so does not need DM */
	// 为gd->bootstage分配空间,并初始化gd->bootstage,增加两条gd->bootstage->record,一条是reset,一条是board_init_f
#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, // 初始化驱动树和uclass树,并绑定含有DM_FLAG_PRE_RELOC标志位和特殊设备树特性的节点
	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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔尊moon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值