错误系统调用:功能未实现。

3
我正在尝试向Linux内核添加新的(虚拟)系统调用。
1)我在linux-source/kernel/myfile.c文件中添加了系统调用代码,并相应地更新了Makefile。
2)我更新了syscall.h、unistd.h和entry.S文件,以反映新的系统调用(pedagogictime(int flag,struct timeval * time))。
然后编译内核并安装和重启镜像。当我运行命令:cat /proc/kallsyms | grep "pedag"时,这是我的输出:
0000000000000000 T sys_pedagogictime 0000000000000000 d event_exit__pedagogictime 0000000000000000 d event_enter__pedagogictime 0000000000000000 d __syscall_meta_pedagogictime 0000000000000000 d types_pedagogictime 0000000000000000 d args__pedagogictime 0000000000000000 t trace_init_flags_enter__pedagogictime 0000000000000000 t trace_init_flags_exit__pedagogictime 0000000000000000 t __event_exit__pedagogictime 0000000000000000 t __event_enter__pedagogictime 0000000000000000 t __p_syscall_meta__pedagogictime 0000000000000000 t __initcall_trace_init_flags_exit__pedagogictimeearly 0000000000000000 t __initcall_trace_init_flags_enter__pedagogictimeearly
这意味着系统调用已正确注册。
在我的用户空间程序中,我正在编写:
#define __NR_pedagogictime 1326 //1326 is my system call number
struct timeval *now = (struct timeval *)malloc(sizeof(struct timeval));

    long ret = syscall(__NR_pedagogictime,0,now);
    if(ret)
            perror("syscall ");

但是我遇到了错误:

"syscall:功能未实现"

如果有任何帮助,我将非常感激。谢谢。

编辑:

顺便说一下,syscall()的汇编代码如下:

    movl    $6, %esi
    movl    $1326, %edi
    movl    $0, %eax
    call    syscall
    cltq

1
你为什么选择1326作为系统调用号码? - Chris Stratton
因为文件natty-source/arch/ia64/include/asm/unistd.h中的最后一个系统调用号码是1325,所以我将我的号码加了一。 - Chandan
1
我怀疑你是否有ia64,你可能在x86_64上,这两者是非常不同的。 - Chris Stratton
1个回答

3

您选择了错误的系统调用号。看一下内核是如何检查系统调用号限制的这里。例如(x86,32位):

496 ENTRY(system_call)
497         RING0_INT_FRAME                 # can't unwind into user space anyway
498         pushl_cfi %eax                  # save orig_eax
499         SAVE_ALL
500         GET_THREAD_INFO(%ebp)
501                                         # system call tracing in operation / emulation
502         testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
503         jnz syscall_trace_entry
504         cmpl $(nr_syscalls), %eax
505         jae syscall_badsys
506 syscall_call:
507         call *sys_call_table(,%eax,4)
508         movl %eax,PT_EAX(%esp)          # store the return value

因此,您可以看到此代码比较%eax(系统调用号)和nr_syscalls(sys_call_table大小)。大于或等于会导致syscall_badsys
您还需要修改arch/x86/include/asm/unistd_32.h头文件。

是的,这也是我的想法。从地址长度和汇编模式来看,我怀疑这是x86_64。在unistd_64.h中曾经有一个关于系统调用表中不要有间隙的警告;在Linux 3.x中进行了大量的重组,但我认为间隙仍然有问题,而1326似乎太高了。 - Chris Stratton
好的,我明白你的意思了。由于系统调用在该文件中从1024开始:“natty-source/arch/ia64/include/asm/unistd.h”,我的程序得到的数字是1326。当我将其更改为303时,它开始工作了。非常感谢。但是,如果我在程序中简单地使用符号常量__NR_pedagogictime(如在unistd.h中定义为1326和unistd_64.h中定义为303),它无法解析该符号。有什么原因吗? - Chandan
@ChandanApsangi,你可能正在使用系统的/usr/include与从发行版内核中窃取的常量,而不是你修改过的版本。只需在你的代码中#define它,这样就不会弄乱你的系统了。 - vonbrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接