前言

我们知道BL31提供smc这个。前面也知道了在atf中。这个smc是怎么执行的。

这篇文章我们来看看这个到底是什么?以及我么如果想要使用的话怎么去注册一个自定义的服务。

参考文档:《SMC CALLING CONVENTION System Software on ARM® Platforms》

SMCCC定义了每个SMC请求功能的ID以及入参和返回值。

下面逐一介绍运行在EL3固件的运行服务框架的注册、初始化和使用。

SMCCC定义了每个运行服务框架的SMC功能ID、OEN(Owning Entity Numbers)、Fast和Standard调用、SMC32和SMC64调用转换。

需要优先实现的功能有:

  • Standard服务调用:
  • Secure-EL1 Payload Dispatcher service:如果存在TOS或者S.EL1 Payload,则需要EL3
  • Secure Monitor负责切换NS.EL1/2和S.EL1。Secure Monitor和S.EL1 Payload之间接口被称为+ SPD(S.EL1 Payload Dispatcher)。ATF还提供了TSP(Test S.EL1 Payload)和TSPD。
  • CPU特有服务:提供CPU特有的的功能服务。

1、运行服务注册

DECLARE_RT_SVC()用于注册一个运行服务,指定服务名称、OEN范围、服务类型(SMC_TYPE_FAST/SMC_TYPE_STD)、初始化和调用函数。

通过DECLARE_RT_SVC()注册的每个服务都会在ELF的rt_svc_descs段中存在,__RT_SVC_DESCS_START__和__RT_SVC_DESCS_END__是此段的起始结束地址,并可以通过地址范围计算服务数量RT_SVC_DECS_NUM。

/** Convenience macro to declare a service descriptor*/
#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 }typedef struct rt_svc_desc {uint8_t start_oen;-------------------service内部启动oenuint8_t end_oen;---------------------service内部末尾oenuint8_t call_type;-------------------smc类型,是fast call还是standard callconst char *name;--------------------service名称rt_svc_init_t init;------------------service初始化函数rt_svc_handle_t handle;--------------对应function id的调用函数
} rt_svc_desc_t;
start_oen:该service的起始内部numberend.oen: 该service的末尾numbercall_type: 调用的smc的类型name: 该service的名字init: 该service在执行之前需要被执行的初始化操作handle: 当触发了call type的调用时调用的handle该请求的函数

据给举个例子这里:以OP-TEE为例从bl31跳转到OP-TEE,实现从bl31到OP-TEE的跳转是通过执行opteed_setup函数来实现的,
该函数在执行runtime_svc_int中对各service做service->init()函数来实现,
而OPTEE这个service就是通过DECALARE_RT_SVC被注册到tr_svc_descs段中,代码存在service/spd/opteed/opteed_main.c文件中,内容如下:

所以咱们定义的service函数会在编译的时候,放到tr_svc_descs这个全局的数组中,然后这个DECALARE_RT_SVC就是将你设置的SMC-ID与对应的service进行绑定。等以后用到这个ID的时候,通过汇编,然后计算这个数组的偏移最后找到这个service入口去执行。具体还是要看看代码体会。

SMC ID

SMCCC定义了每个SMC请求功能的ID以及入参和返回值。

SMCCC定义了每个运行服务框架的SMC功能ID、OEN(Owning Entity Numbers)、Fast和Standard调用、SMC32和SMC64调用转换。

这个解释太繁琐了,就你用的时候去看看其他的,然后设置一个不一样的ID,这个ID的范围在合适的范围即可。

/******************************************************************************** Owning entity number definitions inside the function id as per the SMC* calling convention******************************************************************************/
#define OEN_ARM_START            0
#define OEN_ARM_END            0
#define OEN_CPU_START            1
#define OEN_CPU_END            1
#define OEN_SIP_START            2
#define OEN_SIP_END            2
#define OEN_OEM_START            3
#define OEN_OEM_END            3
#define OEN_STD_START            4    /* Standard Calls */
#define OEN_STD_END            4
#define OEN_TAP_START            48    /* Trusted Applications */
#define OEN_TAP_END            49
#define OEN_TOS_START            50    /* Trusted OS */
#define OEN_TOS_END            63
#define OEN_LIMIT            64

上面的定义根据如下图片:

什么是合适的范围?

根据自己的SMCID功能进行设计

MAX_RT_SVCS为128,是因为OEN有64个,SMC类型有Standard和Fast两种类型,所以一共有128种。rt_svc_descs_indices[]一共有128个。

handler

当注册进去之后,当你的smc命令从optee或者是kernel来的,都会到异常的入口(这个异常指的是类似于中断的东西)-sync_exception_aarch64。然后这个异常会根据smc fid进行选择,然后选择那个rt_svc_descs里面的回调函数。

这个部分的查找是在汇编语言中实现的。

最好是去看一个源码逻辑,你就会发现自己注册做的东西就是实现handler函数、setup函数、起个名字、定义好ID、确定好ID的类型和段的位置。

如果你对这个smc运行机制存在疑惑,可以看看上文的runtime_svc_init()那部分的东西。

重复内容

bl31_main()是ATF主体,runtime_svc_init()是 bl31_main()的东西。其作为BL31初始化一部分,初始化了运行在主CPU上的运行服务框架。这必须在TOS和普通世界软件启动之前执行,因为安全和非安全软件可能需要使用这部分内容。(安全态的切换都是通过这个runtime service)

runtime_svc_init()主要对注册的服务进行有限性验证,调用各自服务的初始化函数init(),以及将不同SMC OEN转换到注册服务ID。

在实际使用中,注册一个服务可能对应一系列SMC调用。(因为有的服务可能功能较多,都可以满足)

runtime_svc_init()是初始化这个服务框架

当EL3 Firmware接收到一个SMC时,SMC功能ID通过W0传递到EL3 Firmware。这是根据寄存位宽和W0进行检查,如果两者不匹配则返回错误。

其中Bit[31]和bits[29:24]共7bit组成一个0~127范围数值,在rt_svc_descs_indices[]所对应具体的软件服务rt_svc_descs[]索引。

进而调用具体软件服务的handle()函数:
handle_runtime_svc()就是判断处理这个,让smc id和service对上。

小结

到这里回想你是否知道了以下三点:

你知道了服务是怎么创建注册的,

知道了你这个服务是怎么被注册加进去的(runtime_svc_init()),

也知道了怎么让你的注册id和service对上的(handle_runtime_svc())。

下面咱们接着上文BL31来看看BL32

ATF启动(五):服务注册相关推荐

  1. SpringCloud系列(一)、服务注册中心Eureka基础

    启动Eureka服务注册中心 1.微服务的注册中心 1.1.注册中心的主要作用 1.2.常见的注册中心 1.3.常见注册中心的异同点 2.Eureka概述 2.1.Eureka的基础知识 2.2.Eu ...

  2. java版spring cloud+spring boot 社交电子商务平台(二)Eureka(服务注册和服务发现基础篇)

    一:Eureka简介 Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一.用于云端服务发现,一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移. ...

  3. Spring Cloud第一篇:服务注册与发现Eureka

    一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...

  4. Spring Cloud构建微服务架构:服务注册与发现(Eureka、Consul)【Dalston版】

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...

  5. Spring Cloud构建微服务架构(一)服务注册与发现

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  6. SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载)

    场景 SpringCloud学习之运行第一个Eureka程序: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/90611451 S ...

  7. java spring cloud版b2b2c社交电商spring cloud分布式微服务:服务注册与发现(Eureka、Consul)...

    Spring Cloud简介 电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配 ...

  8. eureka 之前的服务如何关闭_干货分享 | 服务注册中心Spring Cloud Eureka部分源码分析...

    友情提示:全文13000多文字,预计阅读时间10-15分钟 Spring Cloud Eureka作为常用的服务注册中心,我们有必要去了解其内在实现机制,这样出现问题的时候我们可以快速去定位问题.当我 ...

  9. SpringCloud(二) 服务注册与发现Eureka

    1.eureka是干什么的? 上篇说了,微服务之间需要互相之间通信,那么通信就需要各种网络信息,我们可以通过使用硬编码的方式来进行通信,但是这种方式显然不合适,不可能说一个微服务的地址发生变动,那么整 ...

  10. (一)Eureka搭建服务注册中心

    首先,创建一个基础的Spring Boot工程,命名为eureka-server, 并在pom.xml 中引入必要的依赖内容, 代码如下: <modelVersion>4.0.0</ ...

最新文章

  1. docker服务启动:service docker start和systemctl start docker两种命令有什么区别?
  2. 如何解包/编辑/打包boot.img文件
  3. 银联在线支付---利用测试案例代码模拟支付应用(修改)
  4. mysql+两天前+函数_Mysql 日期函数
  5. Python编程一定要注意的那些“坑”(九):0与False
  6. Python-OpenCV基本操作
  7. 苹果阻止上架的这款软件,到底有多可恶?
  8. 再谈 Formsville
  9. Docker+SVN
  10. Scala可变参数列表
  11. 事件mousseenter和mouseover的区别
  12. 【立创开源】RGBW调光台灯
  13. python +高德地图API调用
  14. 大型电商平台设计实例:电商平台总体设计和业务模型设计
  15. 霹雳吧啦Wz语义分割学习笔记P5
  16. 颠覆你想象的企业报表软件——思迈特软件Smartbi
  17. 在云服务器重装系统后vscode连不上服务器的解决
  18. oracle无法加载库单元,PLS-00907: 无法加载库单元 是什么错误啊??
  19. AVD Nexus_5X_API_P is already running. If that is not the case, delete the files at ...
  20. 【多线程】多线程的六种状态

热门文章

  1. LabVIEW基础-程序发布至web
  2. pdb文件及其作用(转)
  3. 建立二叉树:已知层次遍历顺序建立二叉树、已知先序遍历顺序建立二叉树
  4. 企业钉钉重点功能使用说明
  5. 万字长文---手把手教你加固内核安全配置
  6. rk3568 修改开机动画
  7. 新保险时代,技术即是保险,如水滋养万物——新保险
  8. 四川大学计算机学院现代软件工程(双语 百度云,四川大学2012软件工程导论(双语) (A 闭 )...
  9. 【愚人特稿】数学家应该重新设计角度制--(转自果壳网)
  10. 百练noi 20:反反复复