uboot启动流程分析之六

本文主要分析UBoot启动过程中bootm_load_os方法,该方法负责内核镜像的解压和加载。在加载内核之前,UBoot会设定一系列开发板参数,包括设置特定的CPU寄存器值,如R0置0,R1设为板子ID,R2设为启动参数地址。此外,还会确保CPU处于SVC模式,关闭MMU,禁用中断,并根据需求管理缓存。设备方面,DMA设备需停止工作以确保安全启动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  上一篇还有bootm_load_os没讲,这个方法主要就是对内核镜像解压

static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;     //压缩格式
	ulong load = os.load;       //加载地址
	ulong blob_start = os.start; 
                  //blob=bootloader object起始地址
	ulong blob_end = os.end;     //blob结束地址
	ulong image_start = os.image_start;   //镜像起始地址
	ulong image_len = os.image_len;    //镜像长度

	ulong image_end;

	const char *type_name = genimg_get_type_name (os.type);                  //镜像类型
	int boot_sp;

	__asm__ __volatile__(
		"mov    %0, sp\n"
		:"=r"(boot_sp)
		:
		:"cc"
		);

	/* Check whether kernel zImage overwrite uboot,
	 * which will lead to kernel boot fail. */
	image_end = load + image_len;   
    //检查镜像是否覆盖了uboot引导
	/* leave at most 32KByte for move image stack */
	boot_sp -= BOOTM_STACK_GUARD; 
                //将栈顶指针后移,镜像栈需要32K
	if( !((load > _bss_end) || (image_end < boot_sp)) ) {
		printf("\nkernel image will overwrite uboot! kernel boot fail!\n");
		return BOOTM_ERR_RESET;
	}

	switch (comp) {         //选择解压格式
	case IH_COMP_NONE:  //未压缩
		if (load == blob_start || load == image_start) {
			printf ("   XIP %s ... ", type_name);
		} else {  //是否需要移动镜像
			printf ("   Loading %s ... ", type_name);
			memmove_wd ((void *)load, (void *)image_start,
					image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:     //gzip解压
		printf ("   Uncompressing %s ... ", type_name);
		if (gunzip ((void *)load, unc_len,
					(uchar *)image_start, &image_len) != 0) {
			puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
				"- must RESET board to recover\n");
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:    //bzip2解压
		printf ("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress ((char*)load,
					&unc_len, (char *)image_start, image_len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf ("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA:       //lzma解压
		printf ("   Uncompressing %s ... ", type_name);

		int ret = lzmaBuffToBuffDecompress(
			(unsigned char *)load, &unc_len,
			(unsigned char *)image_start, image_len);
		if (ret != SZ_OK) {
			printf ("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			show_boot_progress (-6);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO:           //lzo解压
		printf ("   Uncompressing %s ... ", type_name);

		int ret = lzop_decompress((const unsigned char *)image_start,
					  image_len, (unsigned char *)load,
					  &unc_len);
		if (r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值