• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 系统调用
2
3## 基本概念
4
5OpenHarmony LiteOS-A实现了用户态与内核态的区分隔离,用户态程序不能直接访问内核资源,而系统调用则为用户态程序提供了一种访问内核资源、与内核进行交互的通道。
6
7## 运行机制
8
9  如图1所示,用户程序通过调用System API(系统API,通常是系统提供的POSIX接口)进行内核资源访问与交互请求,POSIX接口内部会触发SVC/SWI异常,完成系统从用户态到内核态的切换,然后对接到内核的Syscall Handler(系统调用统一处理接口)进行参数解析,最终分发至具体的内核处理函数。
10
11  **图1** 系统调用示意图
12
13  ![zh-cn_image_0000001132856572](figures/zh-cn_image_0000001132856572.png)
14
15Syscall Handler的具体实现在kernel/liteos_a/syscall/los_syscall.c中OsArmA32SyscallHandle函数,在进入系统软中断异常时会调用此函数,并且按照kernel/liteos_a/syscall/syscall_lookup.h中的清单进行系统调用的入参解析,执行各系统调用最终对应的内核处理函数。
16
17> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
18> - 系统调用提供基础的用户态程序与内核的交互功能,不建议开发者直接使用系统调用接口,推荐使用内核提供的对外POSIX接口,若需要新增系统调用接口,详见开发指导。
19>
20> - 内核向用户态提供的系统调用接口清单详见[syscall_lookup.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/syscall/syscall_lookup.h),内核相应的系统调用对接函数清单详见[los_syscall.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/syscall/los_syscall.h)21
22## 开发指导
23
24### 开发流程
25
26新增系统调用的典型开发流程如下:
27
281. 在LibC库中确定并添加新增的系统调用号。
29
302. 在LibC库中新增用户态的函数接口声明及实现。
31
323. 在内核系统调用头文件中确定并添加新增的系统调用号及对应内核处理函数的声明。
33
344. 在内核中新增该系统调用对应的内核处理函数。
35
36### 编程实例
37
38**示例代码**:
39
401. 在LibC库syscall.h.in中新增系统调用号。
41
42   如下所示,其中__NR_new_syscall_sample为新增系统调用号:
43
44   ```
45   ...
46   /* 当前现有的系统调用清单 */
47   /* OHOS customized syscalls, not compatible with ARM EABI */
48   #define __NR_OHOS_BEGIN         500
49   #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0)
50   #define __NR_pthread_join       (__NR_OHOS_BEGIN + 1)
51   #define __NR_pthread_deatch     (__NR_OHOS_BEGIN + 2)
52   #define __NR_create_user_thread  (__NR_OHOS_BEGIN + 3)
53   #define __NR_processcreate       (__NR_OHOS_BEGIN + 4)
54   #define __NR_processtart        (__NR_OHOS_BEGIN + 5)
55   #define __NR_printf             (__NR_OHOS_BEGIN + 6)
56   #define __NR_dumpmemory         (__NR_OHOS_BEGIN + 13)
57   #define __NR_mkfifo             (__NR_OHOS_BEGIN + 14)
58   #define __NR_mqclose            (__NR_OHOS_BEGIN + 15)
59   #define __NR_realpath           (__NR_OHOS_BEGIN + 16)
60   #define __NR_format             (__NR_OHOS_BEGIN + 17)
61   #define __NR_shellexec          (__NR_OHOS_BEGIN + 18)
62   #define __NR_ohoscapget         (__NR_OHOS_BEGIN + 19)
63   #define __NR_ohoscapset         (__NR_OHOS_BEGIN + 20)
64
65   #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */
66
67   #define __NR_syscallend         (__NR_OHOS_BEGIN + 22)
68   ...
69   ```
70
712. 在LibC库中新增用户态接口的声明与实现。
72
73   ```
74   #include "stdio_impl.h"
75   #include "syscall.h"
76   ...
77   /* 新增系统调用用户态的接口实现 */
78   void newSyscallSample(int num)
79   {
80        printf("user mode: num = %d\n", num);
81        __syscall(SYS_new_syscall_sample, num);
82        return;
83   }
84   ```
85
863. 在内核系统调用头文件中新增系统调用号。
87
88   如下所示,在third_party/musl/porting/liteos_a/kernel/include/bits/syscall.h文件中,__NR_new_syscall_sample为新增系统调用号。
89
90   ```
91   ...
92   /* 当前现有的系统调用清单 */
93   /* OHOS customized syscalls, not compatible with ARM EABI */
94   #define __NR_OHOS_BEGIN         500
95   #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0)
96   #define __NR_pthread_join       (__NR_OHOS_BEGIN + 1)
97   #define __NR_pthread_deatch     (__NR_OHOS_BEGIN + 2)
98   #define __NR_create_user_thread  (__NR_OHOS_BEGIN + 3)
99   #define __NR_processcreate       (__NR_OHOS_BEGIN + 4)
100   #define __NR_processtart        (__NR_OHOS_BEGIN + 5)
101   #define __NR_printf             (__NR_OHOS_BEGIN + 6)
102   #define __NR_dumpmemory         (__NR_OHOS_BEGIN + 13)
103   #define __NR_mkfifo             (__NR_OHOS_BEGIN + 14)
104   #define __NR_mqclose            (__NR_OHOS_BEGIN + 15)
105   #define __NR_realpath           (__NR_OHOS_BEGIN + 16)
106   #define __NR_format             (__NR_OHOS_BEGIN + 17)
107   #define __NR_shellexec          (__NR_OHOS_BEGIN + 18)
108   #define __NR_ohoscapget         (__NR_OHOS_BEGIN + 19)
109   #define __NR_ohoscapset         (__NR_OHOS_BEGIN + 20)
110
111   #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */
112
113   #define __NR_syscallend         (__NR_OHOS_BEGIN + 22)
114   ...
115   ```
116
117kernel/liteos_a/syscall/syscall_lookup.h中,增加一行SYSCALL_HAND_DEF(__NR_new_syscall_sample, SysNewSyscallSample, void, ARG_NUM_1):
118
119   ```
120   ...
121   /* 当前现有的系统调用清单 */
122   SYSCALL_HAND_DEF(__NR_chown, SysChown, int, ARG_NUM_3)
123   SYSCALL_HAND_DEF(__NR_chown32, SysChown, int, ARG_NUM_3)
124   #ifdef LOSCFG_SECURITY_CAPABILITY
125   SYSCALL_HAND_DEF(__NR_ohoscapget, SysCapGet, UINT32, ARG_NUM_2)
126   SYSCALL_HAND_DEF(__NR_ohoscapset, SysCapSet, UINT32, ARG_NUM_1)
127   #endif
128   /* 新增系统调用 */
129   SYSCALL_HAND_DEF(__NR_new_syscall_sample, SysNewSyscallSample, void, ARG_NUM_1)
130   ...
131   ```
132
1334. 在内核中新增内核该系统调用对应的处理函数。
134
135   如下所示,在kernel/liteos_a/syscall/los_syscall.h中,SysNewSyscallSample为新增系统调用的内核处理函数声明:
136
137   ```
138   ...
139   /* 当前现有的系统调用内核处理函数声明清单 */
140   extern int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp);
141   extern int SysClockGettime64(clockid_t clockID, struct timespec64 *tp);
142   extern int SysClockGetres64(clockid_t clockID, struct timespec64 *tp);
143   extern int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem);
144   extern int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value);
145   extern int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue);
146   /* 新增的系统调用内核处理函数声明 */
147   extern void SysNewSyscallSample(int num);
148   ...
149   ```
150
151     新增的系统调用的内核处理函数实现如下:
152
153   ```
154   include "los_printf.h"
155   ...
156   /* 新增系统调用内核处理函数的实现 */
157   void SysNewSyscallSample(int num)
158   {
159       PRINTK("kernel mode: num = %d\n", num);
160       return;
161   }
162   ```
163
164**结果验证:**
165
166用户态程序调用newSyscallSample(10)接口,得到输出结果如下:
167
168```
169/* 用户态接口与内核态接口均有输出,证明系统调用已使能 */
170user mode: num = 10
171kernel mode: num = 10
172```
173