|
我在2.6.15内核下以模块方式添加系统调用,出现了一些问题,结果不对,谁能知道错在那?
模块如下:
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/unistd.h>
#include<linux/time.h>
#include<asm/uaccess.h> // for copy_to_user
#include<linux/sched.h> // for current macro
#define __NR_pedagogictime 223
static int (*oldsaved)(void);
// 中断描述符表寄存器结构
struct {
unsigned short limit;
unsigned int base;
} __attribute__((packed)) idtr;
// 中断描述符表结构
struct {
unsigned short off1;
unsigned short sel;
unsigned char none, flags;
unsigned short off2;
} __attribute__((packed)) idt;
// 查找sys_call_table的地址
unsigned long * get_sys_call_table(void)
{
unsigned int sys_call_off;
unsigned long *sys_call_table=NULL;
char* p;
int i;
// 获取中断描述符表寄存器的地址
asm("sidt %0":"=m"(idtr));
printk("中断描述符表寄存器的地址 idtr: %x\n", &idtr);
// 获取0x80中断处理程序的地址
memcpy(&idt, idtr.base+8*0x80, sizeof(idt));
sys_call_off=((idt.off2<<16)|idt.off1);
printk("0x80中断处理程序的地址: %x\n", sys_call_off);
// 从0x80中断服务例程中搜索sys_call_table的地址
p=(char *)sys_call_off;
for (i=0; i<1000; i++)
{
if (p=='\xff' && p[i+1]=='\x14' && p[i+2]=='\x85')
{
sys_call_table=*(unsigned int*)(p+i+3);
printk("1: Address of sys_call_table: %x\n", (unsigned int)sys_call_table);
break;
}
}
if(i==100)printk("没有找到!");
return sys_call_table;
}
asmlinkage int sys_pedagogictime(struct timeval *tv)
{
struct timeval ktv;
do_gettimeofday(&ktv);
copy_to_user(tv,&ktv,sizeof(ktv));
printk("ktv_sec: %ld \n",ktv.tv_sec);
return 0;
}
int init_syscall(void)
{
unsigned long *sys_call_table=NULL;
sys_call_table=get_sys_call_table();
printk("2: address of sys_call_table : %x\n", (unsigned int)sys_call_table);
oldsaved=(int(*)(void))(sys_call_table[__NR_pedagogictime]);
sys_call_table[__NR_pedagogictime]=(unsigned long)sys_pedagogictime;
return 0;
}
void exit_syscall(void)
{
unsigned long *sys_call_table=NULL;
sys_call_table=get_sys_call_table();
sys_call_table[__NR_pedagogictime]=(unsigned long)oldsaved;
}
module_init(init_syscall);
module_exit(exit_syscall);
MODULE_LICENSE("GPL");
调用程序为:
#include<linux/unistd.h>
#include<sys/time.h>
#define __NR_pedagogictime 223
_syscall1(int,pedagogictime,struct timeval *,tv)
int main()
{
struct timeval tv,dtv;
pedagogictime(&tv);
gettimeofday(&dtv,NULL);
printf("tv_sec:%ld dtv_sec:%ld\n",tv.tv_sec,dtv.tv_sec);
printf("tv_usec:%ld dtv_usec:%ld\n",tv.tv_usec,dtv.tv_usec);
printf("em...,let me sleep for 2 second.\n");
sleep(2);
pedagogictime(&tv);
printf("tv_sec:%ld\n",tv.tv_sec);
printf("tv_usec:%ld\n",tv.tv_usec);
}
make文件为:
obj-m := pedagogictime.o
KERNELDIR = /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.mod *.mod.o *.o
编译和调用时出现的问题:
[root@localhost zjf]# make
make -C /lib/modules/2.6.15-1.2054_FC5/build SUBDIRS=/zjf modules
make[1]: Entering directory `/usr/src/redhat/BUILD/kernel-2.6.15/linux-2.6.15.i6 86'
CC [M] /zjf/pedagogictime.o
/zjf/pedagogictime.c: 在函数 ‘get_sys_call_table’ 中:
/zjf/pedagogictime.c:42: 警告:格式 ‘%x’ 需要类型 ‘unsigned int’,但实参 2 的类 型为 ‘struct <anonymous> *’
/zjf/pedagogictime.c:45: 警告:传递参数 2 (属于 ‘__constant_memcpy’)时将整数赋给 指针,未作类型转换
/zjf/pedagogictime.c:45: 警告:传递参数 2 (属于 ‘__memcpy’)时将整数赋给指针,未 作类型转换
/zjf/pedagogictime.c:55: 警告:赋值时将整数赋给指针,未作类型转换
/zjf/pedagogictime.c: 在函数 ‘sys_pedagogictime’ 中:
/zjf/pedagogictime.c:70: 警告:忽略声明有 warn_unused_result 属性的 ‘copy_to_use r’ 的返回值
Building modules, stage 2.
MODPOST
CC /zjf/pedagogictime.mod.o
LD [M] /zjf/pedagogictime.ko
make[1]: Leaving directory `/usr/src/redhat/BUILD/kernel-2.6.15/linux-2.6.15.i68 6'
[root@localhost zjf]# insmod pedagogictime.ko
段错误
[root@localhost zjf]#
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: Oops: 0003 [#1]
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: CPU: 0
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: EIP is at init_module+0x1e/0x2e [pedagogictime]
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: eax: c012a524 ebx: c02e04a0 ecx: c9350e6c edx: d0275197
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: esi: d0275700 edi: ca60ae48 ebp: d0275748 esp: c9350e68
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: ds: 007b es: 007b ss: 0068
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: Process insmod (pid: 2900, threadinfo=c9350000 task=c6398000)
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: Stack: <0>d0275197 c02e04a0 ca60ae48 c0130506 0000b0b6 0000043 8 00000300 d0275700
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: 00000000 00000000 00000000 00000000 00000000 00000000 0 0000000 d03359b4
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: 00000000 c7132340 d03325cc d03322d4 d03325f4 d0327000 0 0000004 00000004
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: Call Trace:
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: [<c0130506>] sys_init_module+0x1382/0x1514 [<c015240f>] d o_sync_read+0xb8/0xf3
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: [<c0172fd1>] inotify_inode_queue_event+0x44/0x131 [<c01c0 66e>] _atomic_dec_and_lock+0x22/0x2c
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: [<c0169c2e>] mntput_no_expire+0x11/0x6d [<c0102bc1>] sysc all_call+0x7/0xb
Message from syslogd@localhost at Wed Jun 6 12:26:07 2007 ...
localhost kernel: Code: 8b 15 10 59 27 d0 89 90 7c 03 00 00 c3 53 e8 4a ff ff ff 89 c3 50 68 97 51 27 d0 e8 5e 5c ea ef 8b 83 7c 03 00 00 a3 10 59 27 d0 <c7> 83 7c 03 00 00 de 50 27 d0 5b 58 31 c0 5b c3 53 83 ec 08 89
[root@localhost zjf]# ./test5
tv_sec:134513990 dtv_sec:1181103993
tv_usec:3214912 dtv_usec:951909
em...,let me sleep for 2 second.
tv_sec:134513990
tv_usec:3214912
[root@localhost zjf]#
大家注意上面的输出:tv_sec:134513990 这是自定义系统调用输出的结果, dtv_sec:1181103993这是调用系统函数gettimeofday()输出的
结果,两者显然不对,谁知道错那儿了? |
|