当前位置: 首页 > 工具软件 > ARMboot > 使用案例 >

u-boot之start_armboot分析(三)

卜弘文
2023-12-01

略过没有定义的部分

  • CFG_NO_FLASH(NandFlash和NorFlash都是Flash,但是一般NandFlash会简称为Nand而不是Flash,一般讲Flash都是指的NorFlash。这里这里的代码是NorFlash相关的),我们硬件中并没有。
  • CONFIG_VFD
  • CONFIG_LCD

mem_malloc_init

static void mem_malloc_init (ulong dest_addr)
{
	mem_malloc_start = dest_addr;
	mem_malloc_end = dest_addr + CFG_MALLOC_LEN;
	mem_malloc_brk = mem_malloc_start;

	memset ((void *) mem_malloc_start, 0,
			mem_malloc_end - mem_malloc_start);
}
  • 初始化堆管理器
  • 传入值为CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE,则是0xc3e00000 + 2*1024*1024 - (0x4000 + 896*1024) - 512*1024,最终结果为0xc3e9c000
  • 从代码可以看到堆的大小为896K
  • 这个地址在u-boot之start_armboot分析(一)中的内存分布一节中画出了大概位置

mmc初始化

int mmc_initialize(bd_t *bis)
{
	struct mmc *mmc;
	int err;

	INIT_LIST_HEAD(&mmc_devices);
	cur_dev_num = 0;

	if (board_mmc_init(bis) < 0)
		cpu_mmc_init(bis);

#if defined(DEBUG_S3C_HSMMC)
	print_mmc_devices(',');
#endif

#ifdef CONFIG_CHECK_X210CV3
	mmc = find_mmc_device(1);//lqm
#else
	mmc = find_mmc_device(0);
#endif
	if (mmc) {
		err = mmc_init(mmc);
		if (err)
			err = mmc_init(mmc);
		if (err) {
			printf("Card init fail!\n");
			return err;
		}
	}
	printf("%ldMB\n", (mmc->capacity/(1024*1024/(1<<9))));
	return 0;
}
  • 初始化一些SoC内部的控制器
  • 最后打印容量,capacity以扇区为单位的,一个扇区是512字节。1左移9位也就是512。本应该先将扇区转换为字节,即capacity*(1<<9),然后再除以1M(1024*1024),但是capacity*512后可能超过了范围,因此按照上面的写法

环境变量重定位env_relocate

  • 此功能完成从SD卡中将环境变量读取到DDR中的任务
  • SD卡有独立的扇区作为环境变量的存储区域。但是我们烧录系统时,只是烧录了uboot,kernel以及rootfs分区。所以当我们烧录完第一次启动时环境变量分区是空的,本次启动uboot尝试去SD卡的环境变量分区读取数据时失败(读取回来后进行CRC校验时失败),uboot选择从uboot内部代码中设置的一套默认的环境变量出发来使用(这就是默认环境变量),然后通过saveenv命令写入环境变量分区
  • 真正的从SD卡到DDR中重定位ENV的代码是在env_relocate_spec内部的movi_read_env

IP与MAC地址的确定

/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

/* MAC Address */
{
	int i;
	ulong reg;
	char *s, *e;
	char tmp[64];

	i = getenv_r ("ethaddr", tmp, sizeof (tmp));
	s = (i > 0) ? tmp : NULL;

	for (reg = 0; reg < 6; ++reg) {
		gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
		if (s)
			s = (*e) ? e + 1 : e;
	}
  • 通过读取环境变量来确定IP与MAC地址

硬件设备初始化

  • 通过函数devices_init ();完成

初始化loadaddr、bootfile

	/* Initialize from environment */
	if ((s = getenv ("loadaddr")) != NULL) {
		load_addr = simple_strtoul (s, NULL, 16);
	}
#if defined(CONFIG_CMD_NET)
	if ((s = getenv ("bootfile")) != NULL) {
		copy_filename (BootFile, s, sizeof (BootFile));
	}
#endif
  • 从环境变量中获取这两个值,在启动Linux内核时会参考它们

LCD初始化和显示Logo

  • 接近最后了,用来初始化屏幕并显示Logo

系统升级

  • 最后提供了通过SD卡升级本地系统的机制

完成

/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
	main_loop ();
}
  • 最后进入死循环,提供与用户的交互功能
 类似资料: