背景
对于运行L0系统的硬件一般是mcu,资源有限,L0系统没有区分内核态和用户态,所有的代码都在内核态运行,所以不需要系统调用
L2系统用的是Linux内核,所以系统调用跟Linux Kernel的是一样的。
所以我们主要来看看L1系统中系统调用机制的是怎么实现的。
后面的分析基于如下版本:
- OpenHarmony v3.3.2
- musl v1.2.0
L1系统调用
对于运行L1系统的硬件一般集成了MMU,而且CPU有特权级别状态(状态寄存器的某些位),可以实现进程之间的隔离、内核态和用户态的隔离。系统调用就是在有内核态和用户态隔离的操作系统上,用户态进程访问内核态资源的一种方式
用户态c库
通常我们的应用不会直接调用系统调用,而是通过c库的库函数来间接调用。
OpenHarmony上层使用的C库是musl libc
, c库的一些函数接口调到最下面就是系统调用接口了。
通过third_party/musl/src/internal/syscall.h
文件中,各种宏的展开,最终都会变成类似与__syscall3
等这样的函数(后面可能跟着不同的数字,代表传递参数的个数),而 musl libc 对于这些函数在不同硬件架构上有着不同的实现,这里以arm为例,
代码路径:third_party/musl/arch/arm/syscall_arch.h
主要代码:
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(r0) : __VA_ARGS__ : "memory"); \
return r0; \
} while (0)
#endif
这里调用了SVC
指令触发一个“特权调用”异常,并传递一些参数,这样会触发内核去处理该中断。
内核态中断处理
SVC中断后,内核就会去处理该中断。
中断异常处理的入口是在汇编代码:kernel/liteos_a/arch/arm/arm/src/los_hw_exc.S
SVC异常处理函数入口:_osExceptSwiHdl
,
最终会调用到所有系统调用的统一入口, 这里就是C代码实现了:OsArmA32SyscallHandle
(kernel/liteos_a/syscall/los_syscall.c
)
这里会根据系统调用号来查找对应的系统调用处理函数(syscall_lookup.h
中定义了对应的处理函数),然后通过这些处理函数和传递过来的参数,由此完成真正系统调用的过程,这里就不再一一分析了。
总结
本篇只是记录了一下OpenHarmony的L1系统系统调用实现的大致流程,梳理下整个脉络。
整个流程大致如下:
应用程序
--> c库函数 (musl libc)
--> 系统调用
--> 触发`SVC`中断
--> 内核态SVC异常处理函数
--> 系统调用具体实现及返回
这里也不列举例子了,具体的可以自己去撸下代码。
为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙 (Harmony OS)开发学习手册》
入门必看:https://qr21.cn/FV7h05
- 应用开发导读(ArkTS)
- 应用开发导读(Java)
HarmonyOS 概念:https://qr21.cn/FV7h05
- 系统定义
- 技术架构
- 技术特性
- 系统安全
如何快速入门:https://qr21.cn/FV7h05
- 基本概念
- 构建第一个ArkTS应用
- 构建第一个JS应用
- ……
开发基础知识:https://qr21.cn/FV7h05
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
基于ArkTS 开发:https://qr21.cn/FV7h05
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……