修改内核源码
Linux系统为每一个系统调用赋予一个系统调用号。当应用程序执行一个系统调用时,应用程序就可以知道执行和调用到哪个系统调用了,从而不会造成混乱。系统调用号一旦分配之后就不会有任何变更,否则已经编译好的应用程序就不能运行了。对于ARM32系统来说,其系统调用号定义在arch/arm/include/uapi/asm/unistd.h头文件中。
添加的内容:arch\arm\include\uapi\asm\unistd.h文件
#define __NR_lkmao_hello (__NR_SYSCALL_BASE+388)
修改文件:arch\arm\include\asm\unistd.h
vi arch/arm/include/asm/unistd.h
/*
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
//#define __NR_syscalls (388)//原来的值
#define __NR_syscalls (392)//修改后的值
修改文件kernel/sys.c,添加内容
vi kernel/sys.c
SYSCALL_DEFINE0(lkmao_hello)
{
printk("%s:%s:%d -- sys_lkmao_hello is called\n",
__FILE__,__func__,__LINE__);
return 0;
}
修改文件include/linux/syscalls.h,添加如下内容:
asmlinkage long sys_hello_lkmao(void);
修改系统调用表,修改文件arch/arm/kernel/calls.S,添加CALL(sys_lkmao_hello)
修改的文件统计
1 arch/arm/include/uapi/asm/unistd.h
2 arch/arm/include/asm/unistd.h
3 kernel/sys.c
4 include/linux/syscalls.h
5 arch/arm/kernel/calls.S
应用测试代码
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
#define DEBUG_INFO(format, ...) printf("%s:%d -- "format"\n",\
__func__,__LINE__,##__VA_ARGS__)
#define __NR_lkmao_hello 388
int main(int argc, char**argv){
int ret = syscall(__NR_lkmao_hello);
DEBUG_INFO("ret = %d\n", ret);
return 0;
}
编译代码测试
在系统调用中打印PID和UID
在kernel/sys.c文件中,修改SYSCALL_DEFINE0(lkmao_hello)的定义,如下所示,修改后重新编译内核。
SYSCALL_DEFINE0(lkmao_hello)
{
const struct cred *cred = current_cred();
printk("%s:%s:%d -- sys_lkmao_hello is called\n",
__FILE__,__func__,__LINE__);
printk("%s:%s:%d -- pid = %d,%d,uid = %d\n",
task_pid_nr(current),
task_pid_nr_ns(current),
cred->uid;,
__FILE__,__func__,__LINE__);
return 0;
}
测试结果