踩坑啊啊啊啊啊啊!!!
目录
内核版本:
开始:
1、编写sys.c
/usr/src/linux-4.18.11/kernel/sys.c
添加:
#include <linux/linkage.h>
SYSCALL_DEFINE2(test_one, int, count, const char __user *, buf)
{
char *p;
printk("This is Syscall Test One.\n");
printk("buf addr is %p \n",buf);
if(count > 1024)
{
printk("Your input str is too long.\n");
return 1;
}
p = (char *)kmalloc(sizeof(char) * count, GFP_KERNEL);
if(!copy_from_user(p, buf, count))
{
printk("input is %s \n", p);
}
kfree(p);
return 1;
}
SYSCALL_DEFINE1(test_four, int, num)
{
printk("This is Syscall Test Four.\n");
printk("Four: Your input num is %d \n", num);
return 1;
}
2、编写syscalls.h
/usr/src/linux-4.18.11/include/linux/syscalls.h
添加:
asmlinkage long sys_test_one(int count, const char __user *buf);
asmlinkage long sys_test_four(int num);
3、编写syscall_64.tbl
/usr/src/linux-4.18.9/arch/x86/entry/syscalls/syscall_64.tbl
添加:
335 common test_one __x64_sys_test_one
338 common test_four __x64_sys_test_four
4、编译启动映像
make bzImage
5、编译模块
make modules
6.1、先安装模块
make modules_install
6.2、安装内核
make install
7、update-grub2 命令会帮我们自动修改grub
8、重启系统
sudo reboot
9、编写测试用例:
test_one.c
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main(int argc, char * argv[])
{
long ret;
char *buf = "335 syscall";
printf("buf addr is %p \n", buf);
ret = syscall(335, strlen(buf) + 1, buf);
if (ret == 1) {
printf("Syscall Succeed!\n");
} else {
printf("Syscall Failed!\n");
}
return 0;
}
test_four.c:
#include<stdio.h>
#include<unistd.h>
int main(int argc, char * argv[])
{
long ret;
int num = 338;
ret = syscall(338, num);
if (ret == 1) {
printf("Syscall Succeed!\n");
} else {
printf("Syscall Failed!\n");
}
return 0;
}
10、测试
./test_one
dmesg:
./test_four
dmesg:
成功!
参考:https://www.tldp.org/HOWTO/html_single/Implement-Sys-Call-Linux-2.6-i386/