optee的generic_boot_init_primary 分析
来源:互联网 发布:手机移动网络dns被劫持 编辑:程序博客网 时间:2024/06/14 15:53
generic_boot_init_primary是optee os初始化的主要函数
#if defined(CFG_WITH_ARM_TRUSTED_FW)
struct thread_vector_table *
generic_boot_init_primary(unsigned long pageable_part, unsigned long u __unused,
unsigned long fdt)
{
init_primary_helper(pageable_part, PADDR_INVALID, fdt);
return &thread_vector_table;
}
unsigned long generic_boot_cpu_on_handler(unsigned long a0 __maybe_unused,
unsigned long a1 __unused)
{
DMSG("cpu %zu: a0 0x%lx", get_core_pos(), a0);
init_secondary_helper(PADDR_INVALID);
return 0;
}
#else
void generic_boot_init_primary(unsigned long pageable_part,
unsigned long nsec_entry, unsigned long fdt)
{
init_primary_helper(pageable_part, nsec_entry, fdt);
}
void generic_boot_init_secondary(unsigned long nsec_entry)
{
init_secondary_helper(nsec_entry);
}
#endif
可见optee针对是否有ATF 提供不同的generic_boot_init_primary 函数,这里我们只讨论enable CFG_WITH_ARM_TRUSTED_FW的情况
generic_boot_init_primary 中仅仅是调用init_primary_helper
static void init_primary_helper(unsigned long pageable_part,
unsigned long nsec_entry, unsigned long fdt)
{
/*
* Mask asynchronous exceptions before switch to the thread vector
* as the thread handler requires those to be masked while
* executing with the temporary stack. The thread subsystem also
* asserts that the foreign interrupts are blocked when using most of
* its functions.
*/
// 设定thread支持的所有异常,主要是写THREAD_EXCP_ALL到寄存器
thread_set_exceptions(THREAD_EXCP_ALL);
//初始化cfp用于浮点运算,arm64 在init_vfp_sec 中disable vfp。要用vfp的话,需要通过thread_kernel_enable_vfp打开
init_vfp_sec();
//只要是清零bss段,并设定heap的范围为__heap1_start~__heap1_end。初始化ta用的memory
init_runtime(pageable_part);
//初始化thread用到的线程栈
thread_init_primary(generic_boot_get_handlers());
//初始化pcpu结构
thread_init_per_cpu();
init_sec_mon(nsec_entry);
//初始化fdt,如果没有定义CFG_DT则为null函数
init_fdt(fdt);
//从fdt中配置console
configure_console_from_dt(fdt);
IMSG("OP-TEE version: %s", core_v_str);
//初始化gic 各大厂商要自己实现
main_init_gic();
//如果定义CFG_WITH_ARM_TRUSTED_FW 的话,init_vfp_nsec 为null 函数
init_vfp_nsec();
//初始化共享内存并执行存放在__initcall_start段的其他初始化函数
if (init_teecore() != TEE_SUCCESS)
panic();
DMSG("Primary CPU switching to normal world boot\n");
}
我们重点看一下init_teecore
TEE_Result init_teecore(void)
{
static int is_first = 1;
/* (DEBUG) for inits at 1st TEE service: when UART is setup */
if (!is_first)
return TEE_SUCCESS;
is_first = 0;
#ifdef CFG_WITH_USER_TA
tee_svc_uref_base = CFG_TEE_LOAD_ADDR;
#endif
/* init support for future mapping of TAs */
teecore_init_pub_ram();
//初始化timmer
/* time initialization */
time_source_init();
//调用initcall ,类似kernel
/* call pre-define initcall routines */
call_initcalls();
IMSG("Initialized");
return TEE_SUCCESS;
}
static void call_initcalls(void)
{
initcall_t *call;
for (call = &__initcall_start; call < &__initcall_end; call++) {
TEE_Result ret;
ret = (*call)();
if (ret != TEE_SUCCESS) {
EMSG("Initial call 0x%08" PRIxVA " failed",
(vaddr_t)call);
}
}
}
可以看到call_initcalls 会调用__initcall_start到__initcall_end 中定义的函数
inincalls的定义如下:
#ifndef INITCALL_H
#define INITCALL_H
#include <tee_api_types.h>
typedef TEE_Result (*initcall_t)(void);
#define __define_initcall(level, fn) \
static initcall_t __initcall_##fn __attribute__((used)) \
__attribute__((__section__(".initcall" level))) = fn
#define service_init(fn) __define_initcall("1", fn)
#define service_init_late(fn) __define_initcall("2", fn)
#define driver_init(fn) __define_initcall("3", fn)
#define driver_init_late(fn) __define_initcall("4", fn)
#endif
在程序中通过调用service_init/service_init_late/driver_init/driver_init_late 来注册initcall的函数,可见总共有四个优先级
static TEE_Result init_tzc400(void)
{
void *va;
DMSG("Initializing TZC400");
va = phys_to_virt(TZC400_BASE, MEM_AREA_IO_SEC);
if (!va) {
EMSG("TZC400 not mapped");
panic();
}
tzc_init((vaddr_t)va);
tzc_dump_state();
return TEE_SUCCESS;
}
service_init(init_tzc400);
例如这个例子中,就会在call_initcalls 中调用init_tzc400
#if defined(CFG_WITH_ARM_TRUSTED_FW)
struct thread_vector_table *
generic_boot_init_primary(unsigned long pageable_part, unsigned long u __unused,
unsigned long fdt)
{
init_primary_helper(pageable_part, PADDR_INVALID, fdt);
return &thread_vector_table;
}
unsigned long generic_boot_cpu_on_handler(unsigned long a0 __maybe_unused,
unsigned long a1 __unused)
{
DMSG("cpu %zu: a0 0x%lx", get_core_pos(), a0);
init_secondary_helper(PADDR_INVALID);
return 0;
}
#else
void generic_boot_init_primary(unsigned long pageable_part,
unsigned long nsec_entry, unsigned long fdt)
{
init_primary_helper(pageable_part, nsec_entry, fdt);
}
void generic_boot_init_secondary(unsigned long nsec_entry)
{
init_secondary_helper(nsec_entry);
}
#endif
可见optee针对是否有ATF 提供不同的generic_boot_init_primary 函数,这里我们只讨论enable CFG_WITH_ARM_TRUSTED_FW的情况
generic_boot_init_primary 中仅仅是调用init_primary_helper
static void init_primary_helper(unsigned long pageable_part,
unsigned long nsec_entry, unsigned long fdt)
{
/*
* Mask asynchronous exceptions before switch to the thread vector
* as the thread handler requires those to be masked while
* executing with the temporary stack. The thread subsystem also
* asserts that the foreign interrupts are blocked when using most of
* its functions.
*/
// 设定thread支持的所有异常,主要是写THREAD_EXCP_ALL到寄存器
thread_set_exceptions(THREAD_EXCP_ALL);
//初始化cfp用于浮点运算,arm64 在init_vfp_sec 中disable vfp。要用vfp的话,需要通过thread_kernel_enable_vfp打开
init_vfp_sec();
//只要是清零bss段,并设定heap的范围为__heap1_start~__heap1_end。初始化ta用的memory
init_runtime(pageable_part);
//初始化thread用到的线程栈
thread_init_primary(generic_boot_get_handlers());
//初始化pcpu结构
thread_init_per_cpu();
init_sec_mon(nsec_entry);
//初始化fdt,如果没有定义CFG_DT则为null函数
init_fdt(fdt);
//从fdt中配置console
configure_console_from_dt(fdt);
IMSG("OP-TEE version: %s", core_v_str);
//初始化gic 各大厂商要自己实现
main_init_gic();
//如果定义CFG_WITH_ARM_TRUSTED_FW 的话,init_vfp_nsec 为null 函数
init_vfp_nsec();
//初始化共享内存并执行存放在__initcall_start段的其他初始化函数
if (init_teecore() != TEE_SUCCESS)
panic();
DMSG("Primary CPU switching to normal world boot\n");
}
我们重点看一下init_teecore
TEE_Result init_teecore(void)
{
static int is_first = 1;
/* (DEBUG) for inits at 1st TEE service: when UART is setup */
if (!is_first)
return TEE_SUCCESS;
is_first = 0;
#ifdef CFG_WITH_USER_TA
tee_svc_uref_base = CFG_TEE_LOAD_ADDR;
#endif
/* init support for future mapping of TAs */
teecore_init_pub_ram();
//初始化timmer
/* time initialization */
time_source_init();
//调用initcall ,类似kernel
/* call pre-define initcall routines */
call_initcalls();
IMSG("Initialized");
return TEE_SUCCESS;
}
static void call_initcalls(void)
{
initcall_t *call;
for (call = &__initcall_start; call < &__initcall_end; call++) {
TEE_Result ret;
ret = (*call)();
if (ret != TEE_SUCCESS) {
EMSG("Initial call 0x%08" PRIxVA " failed",
(vaddr_t)call);
}
}
}
可以看到call_initcalls 会调用__initcall_start到__initcall_end 中定义的函数
inincalls的定义如下:
#ifndef INITCALL_H
#define INITCALL_H
#include <tee_api_types.h>
typedef TEE_Result (*initcall_t)(void);
#define __define_initcall(level, fn) \
static initcall_t __initcall_##fn __attribute__((used)) \
__attribute__((__section__(".initcall" level))) = fn
#define service_init(fn) __define_initcall("1", fn)
#define service_init_late(fn) __define_initcall("2", fn)
#define driver_init(fn) __define_initcall("3", fn)
#define driver_init_late(fn) __define_initcall("4", fn)
#endif
在程序中通过调用service_init/service_init_late/driver_init/driver_init_late 来注册initcall的函数,可见总共有四个优先级
static TEE_Result init_tzc400(void)
{
void *va;
DMSG("Initializing TZC400");
va = phys_to_virt(TZC400_BASE, MEM_AREA_IO_SEC);
if (!va) {
EMSG("TZC400 not mapped");
panic();
}
tzc_init((vaddr_t)va);
tzc_dump_state();
return TEE_SUCCESS;
}
service_init(init_tzc400);
例如这个例子中,就会在call_initcalls 中调用init_tzc400
阅读全文
0 0
- optee的generic_boot_init_primary 分析
- optee thread的初始化
- optee 的helloworld ta
- <OPTEE>Trusted Application结构分析
- optee的同步机制总结
- optee中的fiq的执行
- optee开源项目的学习
- optee os 的启动和初始化
- optee 中静态memory的管理
- linaro optee os官网的几张架构图
- 初识optee 在QEMU平台上的编译、运行
- optee fvp
- optee os中的console driver
- optee os 中的系统调用
- 1.在UBUNTU下搭建OPTEE环境
- optee代码配置cscope和ctags
- core 分析的分析
- 数据分析的重要性分析
- ImageLoader
- -- 公共操作类,用户管理,可添加缓存
- 页面布局基础信息简介
- Android 自定义View实现圆形环绕效果
- Power shell装箱与拆箱
- optee的generic_boot_init_primary 分析
- git将本地项目通过SSH来 push 到自己的GitHub仓库
- 进程隐藏与进程保护(SSDT Hook 实现)(三)
- 从比特币到区块链:新的账本技术如何实现按揭贷款行业的蜕变
- linux的time命令
- iOS开发工具Charles Proxy的使用教程
- Openstack的学习之路
- mysql悲观锁总结和实践
- docker mysql5.7操作命令