1. 引言
本文档解释了怎样在Linux2.6中实现一个新的系统调用。一个系统调用被应用程序用来向操作系统请求服务。
2. 系统调用
一个系统调用被应用程序用来向操作系统请求服务。下面的语句阐述了为什么需要
系统调用。一个操作系统可以直接访问一个系统的硬件,但是一个用户程序没有直接访问硬件的权限。这样做是为了使系统免于遭受恶意的用户程序的破坏,保证系统的安全和保密。但是,经常,一个用户程序需要一些硬件相关的信息(例如,从一个摄像头中获取数据以显示图像),但是,它不能直接获取信息。因此,它请求操作系统提供它这些信息。这个请求是通过使用一个合适的系统调用来完成的。
一个系统调用可以在内核模式下执行。每个系统调用有一个与之关联的数字。这个数字被传递给内核,内核是根据这个数字来决定该执行哪个系统调用。当一个用户程序发出一个系统调用时,它实现上是调用一个库函数。该库函数通过执行汇编指令INT0x80向Linux操作系统发出一个陷阱。它同时也通过EAX寄存器将系统调用号传递给内核。系统调用的参数通过其他的寄存器(EBX,ECX,etc)也传递给内核。内核执行该系统调用,并通过一个寄存器将执行结果返回给用户程序。如果该系统调用需要返回给用户程序大量的数据,它会使用其他的机制(例如,copy_to_user调用)。
3. 需要修改或创建的文件列表
假设你的Linux源码的基目录是/usr/src/linux.需要修改的内核文件如下所示:
1./usr/src/linux/arch/i386/kernel/syscall_table.S
2./usr/src/linux/include/asm-i386/unistd.h
3./usr/src/linux/include/linux/syscalls.h
4. /usr/src/linux/Makefile
需要新创建的文件/目录如下所示:
1. /usr/src/linux/mycall –包含我们自己的系统调用的源文件,头文件和Makefile的目录(你也可以在一个已存在的文件中实现自己的系统调用).
2. /usr/src/linux/mycall/mycall.c–实现我们自已的系统调用的源码.
3. /usr/src/linux/mycall/Makefile- Makefile
新创建的用户空间文件以及用于测试我们的系统调用的文件列表如下所示:
1. testmycall.c –调用我们自己的系统调用的源码.
2. testmycall.h –头文件.
4. 需要修改的内核文件
文件的全路径-/usr/src/linux/arch/i386/kernel/syscall_table.S
该文件包含系统调用的名字.
1.在该文件的后面添加一行(假设我们的系统调用名是mycall).
2. 添加".longsys_mycall"列表的尾部.
4. 2. unistd.h
文件全路径-/usr/src/linux/include/asm-i386/unistd.h
该文件包含系统调用号,当一个系统调用被调用时通过寄存器(EAX)将其传递给内核.
在列表后面添加"#define__NR_mycall Last_System_Call_Num + 1 "
如果上一个系统调用定义在这里:
"#define__NR_vmsplice 316",那么在列表后面添加:
"#define__NR_mycall 317".
将"NR_syscalls"增1.这样,如果NR_syscalls定义如下:
"#defineNR_syscalls 317",那么将其改为:
"#defineNR_syscalls 318"
4. 3. syscalls.h
文件全路径-/usr/src/linux/include/linux/syscalls.h
该文件包含了系统调用的声明.
在该文件的末尾加入如下语句:
"asmlinkagelong sys_mycall(int i);"
4.4. Makefile
文件全路径-/usr/src/linux/Makefile
Add mycall/ to core-y (Search for regex: core-y.*+=). You will be creating this directory.
This directory will contain the source file, header file and the Makefile for our system call.