7.OP-TEE+qemu的启动过程分析--加载optee_os和rootfs

   

  

启动过程中entry.S文件通过汇报调用main_init_sec函数将optee-os image. kernel image和rootfs加载到RAM中,并定位device tree地址信息,以备kernel和OP-TEE启动使用,这些操作是由main_init_sec函数,该函数定义在bios_qemu_tz_arm/bios/main.c文件中,本文将介绍main_init_sec函数的执行流程和具体操作。

main_init_sec的完整的流程图如下:

main_init_sec函数内容和代码注释如下

void main_init_sec(struct sec_entry_arg *arg)
{
	void *fdt;
	int r;
	const uint8_t *sblob_start = &__linker_secure_blob_start;	//定义OP-TEE OS image的存放的起始地址
	const uint8_t *sblob_end = &__linker_secure_blob_end; //定义OP-TEE OS image的存放的末端地址
	struct optee_header hdr;    //存放OP-TEE OS image头的信息
	size_t pg_part_size;    //OP-TEE OS image除去初始化头部的信息的大小
	uint32_t pg_part_dst;    //OP-TEE OS image除去初始化头部信息后在RAM中的起始地址

	msg_init();    //初始化uart

	/* Find DTB */
/* 加载device tree 信息,在qemu工程中,并未将device tree信息编译到Bios.bin中,而默认存放在DTB_START地址中 */
	fdt = open_fdt(DTB_START, &__linker_nsec_dtb_start,
			&__linker_nsec_dtb_end);
	r = fdt_pack(fdt);
	CHECK(r < 0);

	/* Look for a header first */
/* 判定OP-TEE OS image的大小是否大于image header的大小 */
	CHECK(((intptr_t)sblob_end - (intptr_t)sblob_start) <
		(ssize_t)sizeof(hdr));

/* 将OP-TEE OS image header信息拷贝到hdr变量中 */
	copy_bios_image("secure header", (uint32_t)&hdr, sblob_start,
			sblob_start + sizeof(hdr));

/* 校验OP-TEE OS image header中的magic和版本信息是否合法 */
	CHECK(hdr.magic != OPTEE_MAGIC || hdr.version != OPTEE_VERSION);

	msg("found secure header\n");
	sblob_start += sizeof(hdr);	//将sblob_start的值后移到除去image header的位置
	CHECK(hdr.init_load_addr_hi != 0);	//检查OP-TEE OS的初始化加载地址是否为零

/* 获取OP-TEE OS除去 image header和ini操作部分代码的大小 */
	pg_part_size = sblob_end - sblob_start - hdr.init_size;

/* 确定存放OP-TEE OS除去image header和init操作部分代码后存放在RAM中的地址 */
	pg_part_dst = (size_t)TZ_RES_MEM_START + TZ_RES_MEM_SIZE - pg_part_size;

/* 将存放OP-TEE OS除去image header和init操作部分后的内容拷贝到RAM中 */
	copy_bios_image("secure paged part",
			pg_part_dst, sblob_start + hdr.init_size, sblob_end);

	sblob_end -= pg_part_size;	//重新计算sblo_end的地址,剔除page part

	arg->paged_part = pg_part_dst;	//将pg_part_dst赋值给arg中的paged_part以备跳转执行OP-TEE OS使用
	arg->entry = hdr.init_load_addr_lo;    //将hdr.init_load_addr_lo赋值给arg中的entry,该地址为op-TEE OS的入口地址

	/* Copy secure image in place */
/* 将OP-TEE OS的实际image拷贝到其实地址为hdr.init_load_addr_l的RAM地址中 */
	copy_bios_image("secure blob", hdr.init_load_addr_lo, sblob_start,
			sblob_end);

	/*
	 * Copy NS images as while we can read the secure flash from where
	 * we load them.
	 */
/* 拷贝kernel image, rootfs到RAM,并拷贝device tree到对应地址,以备被kernel使用 */
	copy_ns_images();、

/* 将device tree的地址赋值给arg->fdt变量,以备OP-TEE OS启动使用 */
	arg->fdt = dtb_addr;

	msg("Initializing secure world\n");
}

Note:在qemu.mk工程中,OP-TEE image中是没有paged part部分的,这点从启动log就而已看出


  该函数执行完成之后,将会返回结构体为sec_entry_arg的变量,该变量在接下来启动OP-TEE OS的时候很重要,该变量将会告诉CPU OP-TEE OS的入口地址,device tree的地址以及paged_part的地址。

  main_init_sec函数执行完成之后会返回到entry.S中继续执行,接下来所执行的汇编代码如下:

pop {r0, r1, r2}
mov ip, r0  /* entry address */
mov r0, r1  /* argument (address of pagable part if != 0) */ 
blx ip 

  在执行完main_init_sec函数自后, OP-TEE OS的entry地址将会被存放在r0寄存器中,而paged part部分的起始地址将会被存放咋r1寄存器中。使用pop指令执行出栈操作,然后使用mov指令,将存放了OP-TEE OS image的entry address的值赋值给ip寄存器,将paged part的起始地址赋值给r0寄存器,最后调用blx ip指令,进入OP-TEE OS的启动操作。等OP-TEE OS启动完成之后,则会再次跳转会entry.s文件中继续执行,接下来会通过调用main_init_ns函数去启动Linux kernel。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值