网站首页 > 技术文章 正文
用OS通信
1.1 问题的提出
用户模式程序需要用OS进行通信来请求服务或访问有用的操作系统数据(如TOD)。
- 访问虚拟I/O设备
- 和其他进程通信
- ……
但是用户模式程序和操作系统分别在不同的MMU上下文中运行(操作系统是内核模式,不是用户模式的虚拟地址空间),用户模式的程序不可能直接访问操作系统代码和数据。
那么用户模式的程序该如何访问操作系统代码和数据?
1.2 解决办法
- 抽象:一个带有参数的超级用户调用(SVC),参数值在寄存器中,调用的结果在寄存器R0中或用户模式的内存UserMState 中返回。这种接口的一个实例是POSIX,它是由许多类似Unix操作系统的实现的标准接口。
- 实现:用户模式程序使用非法指令产生一个异常中断,操作系统的中断处理程序实现用户请求的代码或数据。这样用户程序只需要执行一条非法指令即可实现与操作系统的通信。我们将采用使用操作码为1(opcode=1)作为产生异常的非法指令,作为“唤起”超级用户调用的“电话”。这些SVC指令的低位将包含一个索引,指示使用哪一个SVC。
操作系统SVC的组织
上图是用户模式/内核模式图。
- 当执行SVC指令时,硬件会将1的操作码视为非法指令并触发OS非法指令异常处理程序,如我们在上一篇中讲的一样。如图中1
- 处理程序将进程状态保存到临时存储区,如图中2,然后分派到基于操作码字段的适当处理程序。
- 该处理程序可以访问临时存储区中的用户寄存器,也可以使用OS适当的子例程访问访问临时存储区。如图中3
- 如果要将信息返回给用户,则返回值可以保存在临时存储区的R0寄存器中,如图中4。
- 处理程序完成后,可能会更新的已保存寄存器值被重新加载到CPU的寄存器中以恢复用户模式进程的执行,如图中5。
SVC处理程序
在前面我们看到了非法指令处理程序如何使用调度表。
在下面的代码中,使用指令中的低位访问一个调度表已选择8个可能的SVCs中的每一个适当代码,选择完成后,通过JMP指令执行SVC子例程。
上面的SVC仅仅是示例少量简单的服务,真正的操作系统的SVC,用于访问文件、处理网络连接、管理虚拟内存、产生新进程…等等
返回用户模式
下面是当SVC处理程序恢复用户模式的代码。
在上述代码中,
- 黄底色的代码是当SVC处理程序恢复用户模式进程时的代码,只需恢复寄存器的保存值,并跳转到被中断的程序断点处处重新执行。
- 青底色的代码是由于某种原因SVC请求无法完成并且该请求会在未来重试。例如:ReadCH SVC返回用户键入的下一个字符,但是如果没有字符驶入,操作系统此时无法完成请求。在这种情况下,SVC处理程序应分支到I_Wait ,后者安排SVC指令在下次运行时重新执行,然后调用Scheduler运行下一个用户模式进程。这使所有其他进程会有机会在再次尝试SVC之前运行成功。
- 此处代码还可以用作两个不同的SVC实现:进程可以通过调用Yield() SVC命令放弃当前执行时间的剩余部分,这导致操作系统指示简单调用Scheduler(),从而暂停当前进程的执行,直到轮询调度过程中的下一轮
- 为了停止执行,进程可以调用Halt() SVC,看一下代码,可以看到“停止”有点用词不当,真正发生的是,系统安排每次重新执行Halt() SVC,然后使OS调度下一个要执行的进程。由于从未执行过Halt() SVC之后的指令,因此该进程似乎停止了。
添加新的SVC
添加新的SVC处理程序非常简单。
5.1 定义新的SVC宏
代码如下:
- 黄底色的代码定义新的SVC宏以用在用户模式的程序中。在上述例子中我们定义了获取和设置TOD的SVC。
- 这是第8和第9个SVC,见青底色代码和调度表 。因此我们要设置SVC调度代码,然后将各自代码的第一条指令的地址添加到调度表 的末尾
5.2 定义新的SVC处理程序
新的SVC处理程序同样简单明了,如下:
SVC小结
SVC机制为用户模式下的程序提供了对OS服务和数据的受控访问。
因为内核模式下禁止中断产生,利用这一特性,我们可以设计出不被其他进程干扰的功能模块。举个例子:
- 若需要用LD/ADDC/ST的指令序列增加主内存中的值,而且希望LD和ST之间的执行不被其他进程干预。在用户模式下是不可能做到的,因为中断可以发生在任何指令上。
- 我们可以将所需要的功能封装为SVC,然后再调用SVC,这样就可以确保LD和ST之间的执行不被中断。
猜你喜欢
- 2024-11-10 VMware中ESXI常用命令(vmware esxi使用教程)
- 2024-11-10 arm嵌入式考试题,大神精心总结(arm嵌入式知识点)
- 2024-11-10 ARM汇编教程(3): ARM指令集(arm汇编指令的基本格式)
- 2024-11-10 Cortex-A的通用寄存器和程序状态寄存器
- 2024-11-10 基于istio的mirror构建真实流量测试环境
- 2024-11-10 领先业界,中兴通讯首发两款双路4K超高清视讯终端
- 2024-11-10 arm 汇编指令 CPS(arm汇编器)
- 2024-11-10 Linux-2.6.37版:Linux内核启动全过程详解
- 2024-11-10 协处理器指令_开启ICache代码示例
- 2024-11-10 ADC触摸屏编程_定时器程序优化(触摸屏如何修改plc里时间定时值)
- 最近发表
-
- 使用Knative部署基于Spring Native的微服务
- 阿里p7大佬首次分享Spring Cloud学习笔记,带你从0搭建微服务
- ElasticSearch进阶篇之搞定在SpringBoot项目中的实战应用
- SpringCloud微服务架构实战:类目管理微服务开发
- SpringBoot+SpringCloud题目整理
- 《github精选系列》——SpringBoot 全家桶
- Springboot2.0学习2 超详细创建restful服务步骤
- SpringCloud系列:多模块聚合工程基本环境搭建「1」
- Spring Cloud Consul快速入门Demo
- Spring Cloud Contract快速入门Demo
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)