一、系统调用的概念
现代操作系统,处理器的运行模式通常分成两个空间:一个内核空间,一个用户空间。大部分的应用程序都是运行在用户空间的,而内核和设备驱动程序运行在内核空间。如果应用程序需要访问硬件资源或者需要内核提供服务时,就需要通过系统调用来实现。如图为系统架构:
二、系统调用有什么作用
1、为用户空间程序提供一层硬件抽象接口。应用程序在读写一个文件时,无需关心底层硬件信息。
2、保证系统稳定和安全。
3、可移植性。可以让应用程序在不加修改下,可以在不同的操作系统或者不同的硬件体系结构的系统中重新编译运行。
三、系统调用实现原理
linux系统用一个文件来维护系统调用号。系 统 调 用 号 的 定 义 是 实 现 在arch/arm/include/uapi/asm/unistd.h 头文件中。
我们知道open对应的系统调用函数是sys_open,那么内核是如何知道这个函数的呢?在 arch/arm/kernel/calls.S 汇编中,通过 CALL 宏来定义具体的系统调用要实现的接口函数
最后, 在 arch/arm/kernel/sys_arm.c 文件中实现对应的系统函数接口。还有一个问题:自己增加的系统调用函数,谁来调用呢?直接使用 libc 中 syscall 函数来调用我们新加的系统调用函数。
相信到这里,应该就可以自己写一个简单的系统调用函数了:
1、在arch/arm/include/uapi/asm/unistd.h 头文件中增加一项
2、在 arch/arm/include/asm/unistd.h 头文件中修改全局变量__NR_syscalls,__NR_syscalls 表示一共有多少的系统调用
3、在 arch/arm/kernel/calls.S 汇编中增加函数接口
4、在 arch/arm/kernel/sys_arm.c 文件中实现函数
5、在应用程序中调用syscall();