您的位置:首页 > 移动开发 > IOS开发

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

2017-05-10 15:31 531 查看
  通过以上章节明了了使用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镜像的编译》

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  TEE OP-TEE