内核是根据 linux-5.6.13 的源码自己编译的内核,虚拟机+Centos7 64 位
代码如下
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <asm/uaccess.h>
#include <linux/sched.h>
#define my_syscall_num 336
/*此处我也不知道为啥,执行
cat /proc/kallsyms | grep sys_call_table
结果如下
0000000000000000 R sys_call_table
0000000000000000 R ia32_sys_call_table
*/
#define sys_call_table_adress 0x00000000
unsigned int clear_and_return_cr0(void);
void setback_cr0(unsigned int val);
asmlinkage long sys_mycall(long long num);
int orig_cr0;
unsigned long *sys_call_table = 0;
static int (*anything_saved)(void);
MODULE_AUTHOR("GuoShuSong");
MODULE_LICENSE("GPL");
unsigned int clear_and_return_cr0(void){
unsigned int cr0 = 0;
unsigned int ret;
asm("movl %%cr0,%%eax":"=a"(cr0));
ret = cr0;
cr0 &= 0xfffeffff;
asm("movl %%eax,%%cr0"::"a"(cr0));
return ret;
}
void setback_cr0(unsigned int val){
asm volatile("movl %%eax,%%cr0"::"a"(val));
}
static int __init init_addsyscall(void){
printk("hello,kernel");
sys_call_table=(unsigned long *)sys_call_table_adress;
anything_saved = (int(*)(void))(sys_call_table[my_syscall_num]);
orig_cr0 = clear_and_return_cr0();
sys_call_table[my_syscall_num]= (unsigned long)&sys_mycall;
setback_cr0(orig_cr0);
return 0;
}
asmlinkage long sys_mycall(long long num){
int res =0;
long long r = num;
if(do_div(num,2)== 0){
res = do_div(r,1000000);
}else{
res = do_div(r,100000);
}
return res;
}
static void __exit exit_addsyscall(void){
orig_cr0 = clear_and_return_cr0();
sys_call_table[my_syscall_num]= (unsigned long)anything_saved;
setback_cr0(orig_cr0);
printk("call exit \n");
}
module_init(init_addsyscall);
module_exit(exit_addsyscall);
MakeFile 代码如下
ifneq ($(KERNELRELEASE),)
EXTRA_CFLAGS = -O0
obj-m := gss.o
else
KDIR = /lib/modules/$(shell uname -r)/build
#KDIR = /lib/modules/5.6.1318130500093-GuoShuSong/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.symvers *.cmd *.cmd.o
endif
执行 make 时报错如下
make -C /lib/modules/5.6.1318130500093-GuoShuSong/build M=/home/gssplus/桌面 /test/os3 modules
make[1]: 进入目录“/home/gssplus/桌面 /test/linux-5.6.13”
CC [M] /home/gssplus/桌面 /test/os3/gss.o
In file included from /home/gssplus/桌面 /test/os3/gss.c:5:0:
./arch/x86/include/asm/uaccess.h: 在函数‘set_fs’中:
./arch/x86/include/asm/uaccess.h:31:9: 错误:提领指向不完全类型的指针
current->thread.addr_limit = fs;
^
In file included from ./include/linux/init.h:5:0,
from /home/gssplus/桌面 /test/os3/gss.c:1:
./arch/x86/include/asm/uaccess.h: 在函数‘user_access_begin’中:
./arch/x86/include/asm/uaccess.h:37:33: 错误:提领指向不完全类型的指针
#define user_addr_max() (current->thread.addr_limit.seg)
^
./include/linux/compiler.h:78:42: 附注:in definition of macro ‘unlikely’
# define unlikely(x) __builtin_expect(!!(x), 0)
^
./arch/x86/include/asm/uaccess.h:96:2: 附注:in expansion of macro ‘likely’
likely(!__range_not_ok(addr, size, user_addr_max())); \
^
./arch/x86/include/asm/uaccess.h:96:10: 附注:in expansion of macro ‘__range_not_ok’
likely(!__range_not_ok(addr, size, user_addr_max())); \
^
./arch/x86/include/asm/uaccess.h:96:37: 附注:in expansion of macro ‘user_addr_max’
likely(!__range_not_ok(addr, size, user_addr_max())); \
^
./arch/x86/include/asm/uaccess.h:714:16: 附注:in expansion of macro ‘access_ok’
if (unlikely(!access_ok(ptr,len)))
^
make[3]: *** [/home/gssplus/桌面 /test/os3/gss.o] 错误 1
make[2]: *** [/home/gssplus/桌面 /test/os3] 错误 2
make[1]: *** [sub-make] 错误 2
make[1]: 离开目录“/home/gssplus/桌面 /test/linux-5.6.13”
make: *** [all] 错误 2
有没有大佬知道是怎么回事儿
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.