6.OP-TEE+qemu的启动过程分析--加载bios.bin

    通过以上章节明了了使用qemu运行OP-TEE需要的相关image的编译过程以及如何启动。本文将开始介绍启动过程中bios.bin的加载过程。

  通过调用qemu-system-arm启动qemu的时候,最终会去加载从bios_qemu_tz_arm目录中编译出来的bios.bin文件,bios.bin镜像是由linux kernel image, OP-TEE os image, rootfs image以及bios_qemu_tz_arm目录中的其他.o文件组成。而qemu执行bios.bin镜像的时候的入口函数是reset函数,该函数由汇编代码编写,在bior_qemu_tz_arm/bios/entry.S文件中。该文件主要内容如下:

.section .text.boot
//定义 _start函数,设定第一条指令跳转到reset函数执行
FUNC _start , :
	b	reset
	b	.	/* Undef */
	b	.	/* Syscall */
	b	.	/* Prefetch abort */
	b	.	/* Data abort */
	b	.	/* Reserved */
	b	.	/* IRQ */
	b	.	/* FIQ */
END_FUNC _start

/*
 * Binary is linked against BIOS_RAM_START, but starts to execute from
 * address 0. The branching etc before relocation works because the
 * assembly code is only using relative addressing.
 */
/* reset 函数 */
LOCAL_FUNC reset , :
	read_sctlr r0
	orr	r0, r0, #SCTLR_A
	write_sctlr r0

	/* Setup vector */
/* 设置中断向量表 */
	adr	r0, _start
	write_vbar r0

	/* Relocate bios to RAM */
/* 重新设定bios在RAM中的地址 */
	mov	r0, #0
	ldr	r1, =__text_start
	ldr	r2, =__data_end
	sub	r2, r2, r1
	bl	copy_blob

	/* Jump to new location in RAM */
/* 跳转到上面重新定位的Bios在RAM中的地址 */
	ldr	ip, =new_loc
	bx	ip
new_loc:
	/* Setup vector again, now to the new location */
/* 重新设定中断向量 */
	adr	r0, _start
	write_vbar r0

	/* Zero bss */
/* 清空BSS段的数据 */
	ldr	r0, =__bss_start
	ldr	r1, =__bss_end
	sub	r1, r1, r0
	bl	zero_mem

	/* Setup stack */
/* 设定堆栈空间 */
	ldr	ip, =main_stack_top;
	ldr	sp, [ip]

	push	{r0, r1, r2}
	mov	r0, sp
	ldr	ip, =main_init_sec	//获取main_init_sec函数地址
	blx	ip	//跳转到main_init_sec函数中执行,加载OP-TEE OS的image
	pop	{r0, r1, r2}
	mov	ip, r0	/* entry address */ // OP-TEE OS的入口地址
	mov	r0, r1	/* argument (address of pagable part if != 0) */
	blx	ip	//跳转到OP-TEE OS的启动地址

	/*
	 * Setup stack again as we're in non-secure mode now and have
	 * new registers.
	 */
	ldr	ip, =main_stack_top;
	ldr	sp, [ip]

	ldr	ip, =main_init_ns	//获取main_init_ns函数的地址
	bx	ip		//跳转到main_init_ns函数,加载Linux kernel的image
END_FUNC reset

LOCAL_FUNC copy_blob , :
	ldrb	r4, [r0], #1
	strb	r4, [r1], #1
	subs	r2, r2, #1
	bne	copy_blob
	bx	lr
END_FUNC copy_blob

LOCAL_FUNC zero_mem , :
	cmp	r1, #0
	bxeq	lr
	mov	r4, #0
	strb	r4, [r0], #1
	sub	r1, r1, #1
	b	zero_mem
END_FUNC zero_mem


  main_init_sec函数用来将linux kernel image, OP-TEE OS image, rootfs从镜像文件加载到RAM的对应位置。并且解析出OP-TEE OS的入口地址,linux kernel的加载地址,rootfs在RAM中的地址和其他相关信息。main_init_sec函数执行完成之后将会返回OP-TEE OS的入口地址以及device tree的地址。然后在汇编代码中通过调用blx指令进入OP-TEE OS的启动。

  main_init_ns函数是用来启动linux kernel,在main_init_sec函数中将会设定Linux kernel的入口函数地址,device tree的相关信息。

上述两个函数都定义在bios_qemu_tz_arm/bios/main.c文件中。将各种Image拷贝到RAM的操作都是通过解析bios.bin镜像来实现,通过寻找特定的section来确定各image在bios.bin镜像中的位置。各section与各image之间的对应关系请参考

《4. OP-TEE+qemu的编译--bios.bin镜像的编译》

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值