该函数主要用来建立安全监控模式调用处理函数的索引表,并执行EL3中提供的服务项的初始化操作,获取TEE OS的入口地址并赋值给bl32_init变量,以备启动TEE OS。
而这些处理函数是通过DECLARE_RT_SVC宏定义被编译到镜像文件的rt_svc_descs段中的。
void runtime_svc_init(void)
{
int rc = 0, index, start_idx, end_idx;
/*判定rt_svc_descs段中service条数的是否超出MAX_RT_SVCS条*/
assert((RT_SVC_DESCS_END >= RT_SVC_DESCS_START) &&
(RT_SVC_DECS_NUM < MAX_RT_SVCS));
if (RT_SVC_DECS_NUM == 0)
return;
/* 初始化t_svc_descs_indices数组中的数据成-1,表示当前所有的service无效*/
memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices));
/* 获取第一条EL3 service在RAM中的起始地址,通过获取RT_SVC_DESCS_START的值来确定,
该值在链接文件中有定义 */
rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START;
/* 遍历整个rt_svc_des段,将其call type与rt_svc_descs_indices中的index建立对应
关系 */
for (index = 0; index < RT_SVC_DECS_NUM; index++) {
rt_svc_desc_t *service = &rt_svc_descs[index];
/* 判定在编译时注册的service是否有效 */
rc = validate_rt_svc_desc(service);
if (rc) {
ERROR("Invalid runtime service descriptor %pn",
(void *) service);
panic();
}
/* 执行当前service的init的操作 */
if (service- >init) {
rc = service- >init();
if (rc) {
ERROR("Error initializing runtime service %sn",
service- >name);
continue;
}
}
/* 根据该service的call type以及start oen来确定唯一的index,并且将该service
中支持的所有call type生成唯一的标识映射到同一个index中 */
start_idx = get_unique_oen(rt_svc_descs[index].start_oen,
service- >call_type);
assert(start_idx < MAX_RT_SVCS);
end_idx = get_unique_oen(rt_svc_descs[index].end_oen,
service- >call_type);
assert(end_idx < MAX_RT_SVCS);
for (; start_idx <= end_idx; start_idx++)
rt_svc_descs_indices[start_idx] = index;
}
}
该宏用来在编译时将EL3中的service编译进rt_svc_descs段中。该宏定义如下:
#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
static const rt_svc_desc_t __svc_desc_ ## _name
__section("rt_svc_descs") __used = {
.start_oen = _start,
.end_oen = _end,
.call_type = _type,
.name = #_name,
.init = _setup,
.handle = _smch }
该宏中的各种参数说明如下:
全部0条评论
快来发表一下你的评论吧 !