实例:基于4412-实现添加自己的系统调用函数(学习《Linux内核设计与实现》 记录)

学习笔记:
在学习《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

猜你喜欢

转载自blog.csdn.net/weixin_38184741/article/details/84932246