第四季-专题8-LINUX系统调用
专题8-Linux系统调用
1. 作用介绍
在前面的学习中,我们涉及到许多的系统调用函数,如:open、close、read、write等等,但是我们对其调用机制不是太了解。
我们知道linux系统存在内核空间与用户空间,内核空间中的程序需要被用户空间的应用程序引用到,能完成这个调用过程的函数就叫做系统调用函数
2. 工作流程分析
应用程序中运行swi,内核的调用函数有很多,它们之间进行编号,所编的号码放在寄存器R7中。我们读取R7中的编号,就明白了调用的函数是什么。sys_call_table就是我们用到的存放系统调用函数的一段汇编代码。
3. 实现新的系统调用
我们实现的功能就是打印信息。
我们在开发板的内核程序中找到,printk.c,在其中插入下面的程序:
void sys_pk()
{
printk(“this is a new sys_call!\n”);
}
我们内核文件夹中,找到arch-arm-kernel,我们可以看到call.s文件,进入其中,我们会看到一系列的列表,我们在列表的最下面加上CALL(sys_pk),这样我们的内核就能在表中找到我们写的函数。
我们在arch-arm-include下面找到我们的unistd.h文件,在文件的最下面加上:
#define _NR_pk (_NR_SYSCALL_BASE+376),这对应的是我的TQ210的内核,我们在内核文件中,进行删除和编译,形成新的内核。
下面我们编写一个应用程序,使得我们的内核文件可以使用:syscall.c
void pk()
{
__asm__ (
"ldr r7,=376 \n" //伪指令标号
"swi \n" //调用swi
:
:
:"memory");
}
void main()
{
pk();
}
我们这里进行了内嵌汇编语言,由于我们的376超过了8位,这里我们使用ldr伪指令。、
我们使用静态编译,因为在linux内核文件中,我们并没有进行动态库的移植:
arm-linux-gcc –static syscall.c –o syscall
将编译好的文件,复制到我们的根文件系统之中。运行该程序,打印this is a new sys_call!