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。

 

以下是在 Windows 系统下构建 QEMU Cortex-A7 和 Visual Studio 虚拟开发和调试环境的步骤: 1. 下载 QEMU QEMU 是一个开源的虚拟机软件,可以模拟多种硬件平台,包括 ARM。在 QEMU 官网上下载最新版本的 QEMU:https://www.qemu.org/download/ 2. 下载 Cortex-A7 虚拟机镜像 可以在 Linaro 官网上下载预编译的 Cortex-A7 虚拟机镜像:https://www.linaro.org/downloads/ 3. 安装 Visual Studio 在官网上下载并安装 Visual Studio:https://visualstudio.microsoft.com/downloads/ 4. 安装 VisualGDB 插件 VisualGDB 是一个 Visual Studio 的插件,可以支持 ARM 开发和调试。在官网上下载并安装 VisualGDB:https://visualgdb.com/download/ 5. 配置 VisualGDB 打开 Visual Studio,点击“VisualGDB”菜单,选择“Project Wizard”,选择“Embedded Project”,选择“QEMU ARM Cortex-A7”,然后按照向导完成配置。 6. 启动 QEMU 使用以下命令启动 QEMU: ``` qemu-system-arm -machine virt -cpu cortex-a7 -smp 4 -m 2048 -kernel path/to/kernel -append "root=/dev/vda2 rootfstype=ext4 rw console=ttyAMA0,115200" -drive file=path/to/rootfs,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev user,id=net0 -device virtio-net-device,netdev=net0 ``` 其中,`path/to/kernel` 是内核镜像的路径,`path/to/rootfs` 是根文件系统的路径。 7. 调试应用程序 在 Visual Studio 中创建一个新的 ARM 项目,然后编写和调试应用程序。在调试配置中选择“VisualGDB QEMU Cortex-A7”,然后启动调试会话即可。 希望这些步骤能够帮助你构建 QEMU Cortex-A7 和 Visual Studio 虚拟开发和调试环境。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值