用户控件应用程序通过swi软中断指令进入内核空间实现系统调用,我们也可以重新编译内核实现自己设计的的系统的调用,以ok6410开发板为例,实现一个简单的打印信息的功能:
1、打开ok6410内核源代码的目录,因为实现的是打印信息的功能,所以将这个函数实现到printk.c中去,找到kernel文件夹,进入找到并打开printk.c,找个适当的位置编写系统调用的函数体 如下:
void sys_pk()
{
printk("this is a new sys call!\n");
}
有了函数体之后,为了让内核能找得到这个函数,还需修改一些相应的代码,进入arch/arm/kernel/ 打开calls.S 每一个系统调用的函数都在这个表里列出来了,再加一个新的系统调用的时候,一定把它加在最后面。加入CALL(sys_pk),这样内核就能从这张表里面找到sys_pk()函数了,还需要再修还、arch/arm/include/asm/ 下的unistd.h 加入以下一行 #define __NR_pk (__NR_SYSCALL_BASE+376) 即可,至于376是按已有的顺序往下排即可,取决于开发板及内核。至此,内核修改完毕,重新编译,make clean 一次,然后make uImage ARCH=arm CROSS_COMPILE=arm-linux- ,编译成功后通过tftp下载到开发板,成功运行后,编写应用程序,使用新加的系统调用.
1、打开ok6410内核源代码的目录,因为实现的是打印信息的功能,所以将这个函数实现到printk.c中去,找到kernel文件夹,进入找到并打开printk.c,找个适当的位置编写系统调用的函数体 如下:
void sys_pk()
{
printk("this is a new sys call!\n");
}
有了函数体之后,为了让内核能找得到这个函数,还需修改一些相应的代码,进入arch/arm/kernel/ 打开calls.S 每一个系统调用的函数都在这个表里列出来了,再加一个新的系统调用的时候,一定把它加在最后面。加入CALL(sys_pk),这样内核就能从这张表里面找到sys_pk()函数了,还需要再修还、arch/arm/include/asm/ 下的unistd.h 加入以下一行 #define __NR_pk (__NR_SYSCALL_BASE+376) 即可,至于376是按已有的顺序往下排即可,取决于开发板及内核。至此,内核修改完毕,重新编译,make clean 一次,然后make uImage ARCH=arm CROSS_COMPILE=arm-linux- ,编译成功后通过tftp下载到开发板,成功运行后,编写应用程序,使用新加的系统调用.
编写应用程序如下:
void pk()
{
__asm__ (
"ldr r7,=376 \n" //将系统调用的编号装入r7寄存器中去 之所以不用mov指令,是因为376长度已经超过8位了,所以用伪指令
"swi \n" //调用swi命令
:
:
:"memory");
}
void main()
{
pk();
}
因为没有在根文件系统创建动态链接库,所以用静态链接库编译 arm-linux-gcc -static syscall.c -o syscall,编译好了之后通过NFS文件系统传至开发板,运行。
打印出 this is a new sys call!