optee userpace TA程序中的栈的设置
文章目录
- 1、openssession结构体
- 2、user TA栈的地址获取
- 3、invoke的流程:
- 4、thread_enter_user_mode中设置栈地址
★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★
思考:
- TA怎样被装载到内存?
- TTA是在共享内存中运行的,还是在TEE内存中运行的?
- TTA的第一条指令是怎样执行的?
- TTA的栈、堆如何分配的?
- TCA调用TA的共享内存,在TA中如何map的?
- T切换TA时,系统都做了哪些事情?
1、openssession结构体
在opensession的时候,会将session注册到TEE内存中,以链表方式存在
struct tee_ta_session {TAILQ_ENTRY(tee_ta_session) link;TAILQ_ENTRY(tee_ta_session) link_tsd;struct tee_ta_ctx *ctx; /* TA context */TEE_Identity clnt_id; /* Identify of client */bool cancel; /* True if TAF is cancelled */bool cancel_mask; /* True if cancel is masked */TEE_Time cancel_time; /* Time when to cancel the TAF */void *user_ctx; /* ??? */uint32_t ref_count; /* reference counter */struct condvar refc_cv; /* CV used to wait for ref_count to be 0 */struct condvar lock_cv; /* CV used to wait for lock */int lock_thread; /* Id of thread holding the lock */bool unlink; /* True if session is to be unlinked */
#if defined(CFG_TA_GPROF_SUPPORT)struct sample_buf *sbuf; /* Profiling data (PC sampling) */
#endif
};
2、user TA栈的地址获取
堆和栈的大小,都是在User_ta_header_defines.h文件种定义的:
#define TA_STACK_SIZE (2 * 1024)
#define TA_DATA_SIZE (4 * 1024 * 1024 + 32 * 1024)
在opensession的时候,将栈的地址map到TA虚拟地址空间
/* Add stack segment */utc->stack_addr = 0;res = vm_map(utc, &utc->stack_addr, utc->mobj_stack->size,TEE_MATTR_URW | TEE_MATTR_PRW, utc->mobj_stack,0);
3、invoke的流程:
先看一个枚举数组,这是kernel mode与TA通信的三个接口,仅此三个.
或者也可以说,这是CA和TA通信的3个接口
enum utee_entry_func {UTEE_ENTRY_FUNC_OPEN_SESSION = 0,UTEE_ENTRY_FUNC_CLOSE_SESSION,UTEE_ENTRY_FUNC_INVOKE_COMMAND,
};
invoke的流程:
tee_entry_std -->tee_ta_invoke_command()---->user_ta_enter_invoke_cmd()—>user_ta_enter()
分析invoke函数:
static TEE_Result user_ta_enter_open_session(struct tee_ta_session *s,struct tee_ta_param *param, TEE_ErrorOrigin *eo)
{return user_ta_enter(eo, s, UTEE_ENTRY_FUNC_OPEN_SESSION, 0, param); -------//这里cmd是invoke
}
从下面函数可以看出, TA运行时的stack是从TA binray解析出来的
static TEE_Result user_ta_enter(TEE_ErrorOrigin *err,struct tee_ta_session *session,enum utee_entry_func func, uint32_t cmd,struct tee_ta_param *param)
{TEE_Result res;struct utee_params *usr_params;uaddr_t usr_stack;struct user_ta_ctx *utc = to_user_ta_ctx(session->ctx);TEE_ErrorOrigin serr = TEE_ORIGIN_TEE;struct tee_ta_session *s __maybe_unused;void *param_va[TEE_NUM_PARAMS] = { NULL };/* Map user space memory */res = tee_mmu_map_param(utc, param, param_va); //---------------将param参数(共享内存)map到TEE中if (res != TEE_SUCCESS)goto cleanup_return;/* Switch to user ctx */tee_ta_push_current_session(session);/* Make room for usr_params at top of stack */usr_stack = utc->stack_addr + utc->mobj_stack->size; //----------------解析栈地址usr_stack -= ROUNDUP(sizeof(struct utee_params), STACK_ALIGNMENT);usr_params = (struct utee_params *)usr_stack;init_utee_param(usr_params, param, param_va);res = thread_enter_user_mode(func, tee_svc_kaddr_to_uref(session),//----------------进入userspace,并跳转到entry_func(vaddr_t)usr_params, cmd, usr_stack,utc->entry_func, utc->is_32bit,&utc->ctx.panicked, &utc->ctx.panic_code);clear_vfp_state(utc);/** According to GP spec the origin should allways be set to the* TA after TA execution*/serr = TEE_ORIGIN_TRUSTED_APP;if (utc->ctx.panicked) {DMSG("tee_user_ta_enter: TA panicked with code 0x%x\n",utc->ctx.panic_code);serr = TEE_ORIGIN_TEE;res = TEE_ERROR_TARGET_DEAD;}/* Copy out value results */update_from_utee_param(param, usr_params);s = tee_ta_pop_current_session();assert(s == session);
cleanup_return:/** Clear the cancel state now that the user TA has returned. The next* time the TA will be invoked will be with a new operation and should* not have an old cancellation pending.*/session->cancel = false;/** Can't update *err until now since it may point to an address* mapped for the user mode TA.*/*err = serr;return res;
}
4、thread_enter_user_mode中设置栈地址
uint32_t thread_enter_user_mode(unsigned long a0, unsigned long a1,unsigned long a2, unsigned long a3, unsigned long user_sp,unsigned long entry_func, bool is_32bit,uint32_t *exit_status0, uint32_t *exit_status1)
{uint32_t spsr;tee_ta_update_session_utime_resume();if (!get_spsr(is_32bit, entry_func, &spsr)) {*exit_status0 = 1; /* panic */*exit_status1 = 0xbadbadba;return 0;}return __thread_enter_user_mode(a0, a1, a2, a3, user_sp, entry_func,spsr, exit_status0, exit_status1);
}
/** uint32_t __thread_enter_user_mode(unsigned long a0, unsigned long a1,* unsigned long a2, unsigned long a3, unsigned long user_sp,* unsigned long user_func, unsigned long spsr,* uint32_t *exit_status0, uint32_t *exit_status1)**/
FUNC __thread_enter_user_mode , :ldr x8, [sp]/** Create the and fill in the struct thread_user_mode_rec*/sub sp, sp, #THREAD_USER_MODE_REC_SIZEstore_xregs sp, THREAD_USER_MODE_REC_EXIT_STATUS0_PTR, 7, 8store_xregs sp, THREAD_USER_MODE_REC_X19, 19, 30/** Switch to SP_EL1* Disable exceptions* Save kern sp in x19*/msr daifset, #DAIFBIT_ALLmov x19, sp ------------------------将kernel mode下的 sp(sp_el0)保存到X19中msr spsel, #1 ------------------------从此刻开始,kernel mode下sp使用sp_el1/** Save the kernel stack pointer in the thread context*//* get pointer to current thread context */get_thread_ctx sp, 21, 20, 22/** Save kernel stack pointer to ensure that el0_svc() uses* correct stack pointer*/str x19, [x21, #THREAD_CTX_KERN_SP] ---------- 将栈地址保存到全局变量中,因为userspace程序可能会主动调用kernel mode,然后使用kernel mode下的栈/** Initialize SPSR, ELR_EL1, and SP_EL0 to enter user mode*/msr spsr_el1, x6/* Set user sp */mov x13, x4 /* Used when running TA in Aarch32 */ --------------------将栈地址写入到R13msr sp_el0, x4 /* Used when running TA in Aarch64 */ --------------------将栈地址写入到sp_el0/* Set user function */msr elr_el1, x5/* Set frame pointer (user stack can't be unwound past this point) */mov x29, #0 --------------------------------------------------------- ELR清0/* Jump into user mode */store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 1b eret_to_el0
END_FUNC __thread_enter_user_mode
optee userpace TA程序中的栈的设置相关推荐
- 人脸识别客户端应用程序_如何在应用程序中使用功能识别设置人脸检测
人脸识别客户端应用程序 by Rohit Ramname 由Rohit Ramname 如何在应用程序中使用功能识别设置人脸检测 (How you can set up face detection ...
- 微信小程序中这么简单的设置页面背景图及字体颜色的方法,你还不会?
在微信小程序中,我们不免的要设置背景图片和字体颜色. 那怎么样才能做到简单的设置背景图片和字体颜色呢? 话不多说,直接开讲 首先先说怎么设置页面背景图片: 这是博主准备的照片. 下面是在wxml中的代 ...
- 小程序中圆角边框的设置
与CSS一样,小程序中的圆角可以通过border-radius来设置. 以input为例,想要设置圆角边框,只需加上如下样式: border-radius: 5px 1 即可实现如下效果: 不 ...
- MATLAB slider中的数值,在微信小程序中如何使用slider设置数据值
这篇文章主要介绍了微信小程序使用slider设置数据值及switch开关组件功能,结合实例形式分析了slider组件及switch组件的功能与使用方法,并附带源码供读者下载参考,需要的朋友可以参考下 ...
- 小程序剖析 | 小程序中Page的数据设置
先上一个例子,例子作为本文的依据: Page()函数用于构建一个页面. 还有一系列函数 下面为大家一一介绍. // pages/Java/java.js Page({/*** 页面的初始数据*/dat ...
- 【C语言进阶深度学习记录】三十五 程序中的堆、栈以及静态存储区(数据区)
学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 在我之前学习底层的知识的时候,也写过相关的内容.可以对比的学习:[软 ...
- 【C深入】程序中的三国天下,栈,堆,静态内存
1 栈 1.1 程序中的栈 栈是现代计算机程序里最重要的概念之一. 栈在程序中用于维护函数调用上下文. 函数中的参数和局部变量存储在栈上. 栈是一种后进先出的行为. 1.2 函数调用过程 栈保存了一个 ...
- Java虚拟机中的栈和堆
Java虚拟机中的栈和堆 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,J ...
- 浅谈Java中的栈和堆
人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...
最新文章
- 踩坑了,JDK8中HashMap依然会产生死循环问题!
- Hadoop 4、Hadoop MapReduce的工作原理
- Eclipse实现hibernate反向工程:从数据库逆向生成实体类和hbm文件
- datetimepicker控件怎么改变hover颜色_VBA入门课程,ActiveX控件系列知识,复合框的属性与常见VBA代码...
- 【收藏】wiztree大文件查找软件
- bootstrat 设置 select option 选项的值
- java launcher_JAR清单类路径不仅适用于Java Application Launcher
- opencv9-膨胀和腐蚀
- 详解mysql事务_详解MySQL执行事务的语法和流程
- dorehtml.php,帝国cms后台实现刷新多栏目内容页的方法详解
- 最通俗易懂的JavaScript入门教程
- Web前端开发-网页制作零基础入门-Dreamweaver2019+HTML+CSS视频教程
- Linux reboot全过程
- APP跟网址最常见的攻击和防守
- 图论总结 for noip
- 名字空间的含义及作用
- C51学习笔记 9.蜂鸣器
- IR Cut Filter主要作用分别是什么?_安防 | 说说监控摄像头中IR-CUT双滤光片哪些事...
- Kinect v2 Examples with-SDK 提示 技巧和示例简介
- 【基于Arduino自动水位指示器和控制器】
热门文章
- python资源百度云_Python Selenium 百度云分享链接资源 批量保存
- 博野哪里学计算机呢,@博野大学生 2021年征兵开始了!
- DL之ShuffleNetV2:ShuffleNetV2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
- CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别脸部表情检测
- 成功解决tensorboard调用events.out.tfevents文件得到网址出现No dashboards are active for the current data set问题
- 蓝桥杯_算法训练_关联矩阵
- 决策树-基于不同算法的决策树模型对比
- 决策树-特征属性选择划分
- Xshell-密钥登录
- iview area 遇到的坑