学习笔记:
在学习《linux内核设计与实现》过程中,了解到:
在Linux中,系统调用是用户空间访问内核的唯一手段(除异常和陷入之外)。
系统调用主要有三个作用:
①:为用户空间提供一个硬件的抽象接口。
②:系统调用保证了系统的稳定和安全。
③:为了实现多任务和虚拟内存(应用程序不可以随意访问硬件)
具体理论知识,可以自己看书了解,本帖子主要介绍基于iTOP-4412的3.0.15版本内核,增加自己系统调用的过程。
需要注意的是,建立一个系统调用非常简单,但绝不提倡。
大家可以使用一些替代方法,如,“设备节点”、“信号量”和“文件描述符”等
内核修改过程
1、使用如下命令
vi arch/arm/kernel/calls.S
在397行添加如下内容,并保存退出。
CALL(sys_foo)
如下图所示:
2、使用如下命令
vi arch/arm/kernel/sys_arm.c
在文件最后,添加如下内容
asmlinkage long sys_foo(void)
{
printk("this is kernel sys_foo ! \n");
return THREAD_SIZE;
}
返回每个进程的内核栈大小。
如下图所示。
3、使用如下命令
vi arch/arm/include/asm/unistd.h
在405行,添加如下内容
#define __NR_foo (__NR_SYSCALL_BASE+376)
后面添加的数字是递增的,不可以和之前的系统调用号重复,并且之后的应用测试程序也要和该数字对应。
如下图所示
添加完成之后,重新编译烧写到板子。
应用程序
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
int main (void)
{
long return_foo = syscall(376,NULL);
printf("this is user and sys_foo() return : %ld \n",return_foo);
return 0;
}
syscall()函数的第一个参数为系统调用号,与“arch/arm/include/asm/unistd.h ”中的定义统一。
运行测试:
~ # ./test
[ 118.131030] this is kernel sys_foo !
this is user and sys_foo() return : 8192
~ #
由打印信息可知,可以成功调用刚才增加的sys_foo()系统调用函数。
参考链接:
https://blog.csdn.net/liduxun/article/details/48119849