41 | 服务接口:如何搭建沟通桥梁?
LMOS
该思维导图由 AI 生成,仅供参考
你好,我是 LMOS。
一路走来,咱们的 Cosmos 系统已经有内存管理,进程、文件、I/O 了,这些重要的组件已经建立了,也就是说它们可以向应用程序提供服务了。
但就好像你去各政府部门办理业务证件一样,首先是前台工作人员接待你,对你的业务需求进行初级预判,然后后台人员进行审核并进行业务办理,最后由前台人员回复,并且给你开好相关业务证件。
服务接口的结构
我们先来设计一下服务接口的整体结构,即 Cosmos 的 API 结构。因为 Cosmos 的 API 数量很多,所以我们先来分个类,它们分别是进程类、内存类、文件类和时间类的 API。这些 API 还会被上层 C 库封装,方便应用程序调用。
为了帮你理解它们之间的关系,我为你准备了一幅图,如下所示。
API框架
结合上图可以看到,我们的应用程序库分为时间库、进程库、内存库、文件库这几种类型。
通常情况下,应用程序中调用的是一些库函数。库函数是对系统服务的封装,有的库函数是直接调用相应的系统服务;而有的库函数为了完成特定的功能,则调用了几个相应的系统服务;还有一些库函数完成的功能不需要调用相应的系统调用,这时前台接待人员也就是“库函数”,可以自行处理。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
文章介绍了在Cosmos系统中搭建服务接口的过程,作为应用程序与内核之间的通信桥梁。首先,文章详细介绍了服务接口的整体结构,包括API的设计和上层C库的封装,以及通过软中断指令实现应用程序进入内核的方法。其次,文章讲解了系统服务分发器的实现,通过中断描述符和系统服务号来区分不同的服务。最后,文章展示了具体的代码实现,包括系统服务分发器函数和中断处理的框架函数。整体而言,本文深入浅出地介绍了Cosmos系统中服务接口的搭建过程,为读者提供了清晰的技术指导。文章通过实例详细展示了时间服务的搭建过程,帮助读者理解了系统服务的实现原理和具体操作步骤。文章内容丰富,逻辑清晰,适合对系统服务接口感兴趣的读者阅读学习。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《操作系统实战 45 讲》,新⼈⾸单¥68
《操作系统实战 45 讲》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(10)
- 最新
- 精选
- neohope置顶一、数据结构 1、全局数据结构,保存系统时间,通过硬件中断更新时间 KRL_DEFGLOB_VARIABLE(ktime_t,osktime); 2、中断向量表,绑定中断编号32和hxi_hwint00,特权级别设置为PRIVILEGE_KRNL set_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate, hxi_hwint00, PRIVILEGE_KRNL); 3、中断向量表,绑定中断编号255和exi_sys_call,特权级别设置为PRIVILEGE_USER set_idt_desc(INT_VECTOR_SYSCALL, DA_386IGate, exi_sys_call, PRIVILEGE_USER); 4、全局变量osservicetab,保存了全部系统调用入口 KRL_DEFGLOB_VARIABLE(syscall_t, osservicetab) 5、全局变量osdrvetytabl,保存了全部驱动入口函数 驱动初始化时,设置了处理函数 osdrvetytabl->systick_entry krlnew_devhandle(devp, systick_handle, 0x20) 二、8254产生硬件 1、8254产生硬件中断0x20 2、CPU收到中断,通过中断处理表IDT,通过中断门门检查后,会找到中断处理入口hxi_hwint00,实际触发了HARWINT 然后调用了hal_hwint_allocator 调用硬件中断处理函数hal_do_hwint 3、hal_do_hwint 调用中断回调函数hal_do_hwint->hal_run_intflthandle 4、hal_run_intflthandle 先获取intfltdsc_t中断异常表 然后调用intfltdsc_t中,i_serlist上所有挂载intserdsc_t 结构中的中断处理的回调函数s_handle 5、8254回调函数为systick_handle 6、systick_handle->krlupdate_times_from_cmos 从CMOS读取时间信息,放到全局osktime中 三、时间API调用 1、用户态 time->api_time->API_ENTRY_PARE1(INR_TIME, rets, ttime) ->功能编号为INR_TIME ->设置返回值 ->设置参数 ->触发 int 255 2、产生255中断 3、内核态 CPU收到中断,通过中断处理表IDT,通过中断门门检查后,会找到中断处理入口exi_sys_call,实际触发了EXI_SCALL 调用了hal_syscl_allocator 第一个参数为功能编号rax,在rdi 第二个参数为中断发生时的栈指针rsp,在rsi,指向内核栈 通过强制类型转换,将内核栈地址,转换为stkparame_t,这样就可以获得参数了 然后找到系统调用处理函数krlservice ->osservicetab[inr](inr, (stkparame_t*)sframe),也就是调用了krlsvetabl_time ->->krlsve_time,把系统的时间数据读取出来,写入应用程序传入缓冲区中【用户内存】 4、在中断处理到最后,内核代码会执行RESTOREALL,返回到用户空间继续运行应用程序。 5、用户态 应用程序就可以在用户态,读取到返回结果了
作者回复: 对的 大佬 666
2021-08-167 - springXu在第五课中找到 产生中断后,CPU 首先会检查中断号是否大于最后一个中断门描述符,x86 CPU 最大支持 256 个中断源(即中断号:0~255) 在第十三课中找到 在 x86 CPU 上,最多支持 256 个中断,还记得前面所说的中断表和中断门描述符吗,这意味着我们要准备 256 个中断门描述符和 256 个中断处理程序的入口。 所以本课的答案就一目了然了。
作者回复: 哈哈 阅读加理解 正确
2021-08-116 - pedro每个中断向量都是一个4字节的值,中断向量表最多可以存放256个中断向量,所以int指令后面的常数不能大于255,因为目前压根就不支持257号中断。
作者回复: 是的 是的
2021-08-113 - 苏流郁宓那arm架构呢?基于linux内核进行二次开发的安卓系统,它的int指令后面的常数也是不能大于255吗?
作者回复: 这是x86 的情况
2021-08-121 - 罗 乾 林不能,INT imm8 ,机器码为2字节【CD ib】最大255
作者回复: 哈哈
2021-08-111 - tony系统是如何保证socket的recv接口buffer参数从内核态到用户态拷贝数据时的安全性的?如果buffer参数在传入时已经是被释放的内存块,内核为什么不崩溃?谢谢。
作者回复: 内核只会认为该进程 非法访问内存 从而终止进程
2022-12-01归属地:湖北 - UJoy申请内存: 用户态->int 255[参数1]->krlservice-> krlsvetabl_mallocblk->krlsve_mallocblk->....-> kmsob_new[内存对象] 这个返回的内核态的虚拟地址吧 【应该要返回用户态的虚拟地址吧】?
作者回复: 这是什么代码
2022-07-19 - kocgockohgoh王裒请问hal_syscl_allocator 的参数在栈上还是在寄存器啊 mov rdi,rax mov rsi,rsp 是把参数放到寄存器 可是怎么控制hal_syscl_allocator 到寄存器取参啊
作者回复: 取参数 c编译器自动处理的
2022-01-13 - 日就月将老师,自己制作的app文件怎么在Cosmos中使用啊,已经编译成了.app文件。但是输入xxx.app之后没有反应。
作者回复: 用41.1的代码
2021-11-03 - 苏流郁宓认为不能大于255
作者回复: 是的
2021-08-12
收起评论