一,前言
之前已经配置nontrust的app且进行了无板仿真调试通过,继续看下源码深入理解下针对这块内容的配置,又多了哪些主要变量及在哪里切换的psw权限。
二,分析源码
- tmask就是和psw相关的设置值。0x800就是特权下的任务,0x1000就是不可信的user权限任务。
typedef struct Os_ApplicationConfigurationType_s {
ApplicationType app_id;
uint8 access;
Os_tmaskType tmask;
} Os_ApplicationConfigurationType;
CONST(Os_ApplicationConfigurationType, OS_CONST_FAST) Os_const_applications[1U + OS_NUM_APPLICATIONS] = {
{0U,
0U,
0x800U,
}, /* INVALID_OSAPPLICATION */
{1U,
2U,
0x800U,
}, /* ApplicationCore0 */
{2U,
4U,
0x1000U,
}, /* NonTrustedAppCore0 */
};
2.Os_Cbk_SetMemoryAccess仅在切换为不可信任务才会调用
if (app->tmask != 0x800U) { /* [$UKS 2050] */
Os_ApplicationContext.Address = (MemoryStartAddressType)0U; /*lint !e923 !e9078 : really an address */
Os_ApplicationContext.Size = 0U;
Os_ApplicationContext.TaskID = Os_RunningTask;
Os_ApplicationContext.ISRID = INVALID_ISR;
Os_ApplicationContext.Application = app->app_id;
Os_ApplicationContext.Trusted = (app->tmask != 0x1000U) ? TRUE : FALSE;
Os_Cbk_SetMemoryAccess(&Os_ApplicationContext); /* [$UKS 1755] */
}
-
切换psw是在保存了上下文后,且执行用户task前进行切换为user模式。MTCR写入psw为user权限就这么一个地方。
image.png
- 写入psw为特权模式是调用SYSCALL(0),比如上图的task运行完成又切换为os内核的地方,也包括汇编的恢复现场也会判断非特权则csa的psw位置也改成特权。Os_TerminateTask恢复现场为什么要特别修改psw为特权呢?我想了下,应该是中断了不可信任务,此时保存了psw为user权限,因为isr_dispatch中也有保存当前任务的csa,之前没配置nontrust的时候,没有这部分代码。
if (app->tmask == 0x1000U) {
{
Os_VoidVoidFunctionType task_entry = Os_RunningTask->entry_function; /* [$EHI 417525] */
OS_MTCR(0xfe04, 0x1000U | (OS_MFCR(0xfe04) & 0xFFFF43FFU));
task_entry(); //应该是此时来了中断
OS_SYSCALL(0);
}
}
- 有很多读取psw为非特权,就转换为特权模式。为什么os源码多了这些呢,想了下应用场景,比如isr中断可以打断任务,若任务是user模式的,那么进入os内核中需要重新改成特权模式才可以有权限实现某些函数任务。
Os_tmaskType previous_tmask = OS_MFCR(0xfe04);
if (0U == (previous_tmask & 0x800U)) { OS_SYSCALL(0); }
-
关于SYSCALL(0)是先psw的值为特权模式,然后放入csa中,最后ret将csa的现场恢复。如下汇编把d7的psw修改后的值放入a14的csa第二个u32,也就是psw的位置。
image.png
三,小结
这样分析了下源码,对相关变量理解的更加深入了。也了解了切换psw的具体位置,便于今后出问题后能快速排查调试。Os_Cbk_SetMemoryAccess我之前看帮助文档还以为是任何权限变换的task间切换都会调用,原来仅仅是切换为不可信权限任务的时候才会调用。看源码来学习真的很高效,可以做细节的及精准的理解,比起看文档猜来猜去快多了~
网友评论