C 向linux内核添加新的系统调用不会';好像不行

C 向linux内核添加新的系统调用不会';好像不行,c,linux,linux-kernel,operating-system,system-calls,C,Linux,Linux Kernel,Operating System,System Calls,我正在学习操作系统课程,第一个任务是向内核添加一些系统调用(Redhat,内核版本2.4) 我已经添加了我认为需要添加的所有内容,但仍然不起作用 我正在尝试运行测试,我注意到包装器(我在下面添加了一个示例,并为其添加了sys_调用代码)没有链接到系统调用。我之所以知道这一点,是因为我在系统调用中放入了printk,它们从未出现过(测试本身也没有给出我期望的结果) 现在据我所知,添加系统调用的开发过程是: 创建一个包装器,如说明中的示例包装器函数(让我们将其称为服务) 将sys_aservice写

我正在学习操作系统课程,第一个任务是向内核添加一些系统调用(Redhat,内核版本2.4)

我已经添加了我认为需要添加的所有内容,但仍然不起作用

我正在尝试运行测试,我注意到包装器(我在下面添加了一个示例,并为其添加了sys_调用代码)没有链接到系统调用。我之所以知道这一点,是因为我在系统调用中放入了printk,它们从未出现过(测试本身也没有给出我期望的结果)

现在据我所知,添加系统调用的开发过程是:

  • 创建一个包装器,如说明中的示例包装器函数(让我们将其称为服务)
  • 将sys_aservice写入一个.c文件,该文件将转到linux-2.4.18-14自定义文件夹中的多个文件之一。它所指向的文件取决于我想要添加的服务类型(例如,如果它是一个文件系统服务,我会将它放在fs中)
  • /usr/src/linuxlinux-2.4.18-14custom/arch/i386/kernel/entry.S
  • 这是我一开始做的,但似乎还不够(因为它似乎不起作用)

    我在网上查了一下(并读到:),我读到我需要添加/更改以下内容才能使链接正常工作

  • 在unistd.h中为系统调用添加一行。看起来像

    定义服务

  • 将aservice添加到makefile。例如,如果我将aservice.c放在fs文件夹中,我会将aservice.c添加到fs中的makefile中

  • 创建一个aservice.h文件,该文件将转到linux-2.4.18-14 custom/include/linux(所有h文件都在哪里?)。这个.h文件将包含一个称为“存根”的东西,它是由unistd.h中的宏自动生成的(该.h文件必须包含该宏),以便用户程序可以使用您的系统调用。 存根的声明如下所示:_syscallN(返回类型、函数名、arg1类型、arg1名称…),其中“N”是参数数

  • 在aservice.c中的每个sys_X函数前面加上关键字“asmlinkage”(需要包含linkage.h)。因此函数声明如下所示: ASMINT系统服务(…){…} 然后将.h文件包含在.c文件中

  • 所有这些都正确吗?因为即使在执行了以下操作之后,系统调用似乎仍然没有被调用

    下面是一个包装器和系统调用实现示例:

     int stop_monitor(int pid){
            long __res;
            __asm__ volatile (
                    "movl $244, %%eax;" << 244 is the entry in the sys_call table in entry.S 
                    "movl %1, %%ebx;"
                    "int $0x80;"
                    "movl %%eax, %0"
                    : "=m" (__res)
                    : "m" (pid)
                    : "%eax", "%ebx"
            );
            if((unsigned long)(__res) >= (unsigned long)(-125)) {
                errno = -(__res);
                __res = -1;
            }
            return (int)(__res);
        }
    
    
    asmlinkage int sys_stop_monitor(int pid){
        task_t* task = find_task_by_pid(pid);
        if(!task)
            return -ESRCH;
        if(task->flagMonitor == 0)
            return -EPERM;
        task->flagMonitor = 0;
        return 0;
    }
    
    int-stop\u监视器(int-pid){
    长时间;
    __反复无常(
    “movl$244,%%eax;”=(无符号多头)(-125)){
    errno=-(uu res);
    __res=-1;
    }
    返回值(整数);
    }
    ASM联动装置内部系统停止监视器(内部pid){
    task_t*task=通过_pid(pid)查找_task_;
    如果(!任务)
    返回-ESRCH;
    如果(任务->标志监视器==0)
    返回-EPERM;
    task->flagMonitor=0;
    返回0;
    }
    

    我缺少什么?

    我已经测试了我为micro libc编写的这些系统调用帮助程序:

    #define MKFNS(fn,...) MKFN_N(fn,##__VA_ARGS__,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__)
    #define MKFN_N(fn, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n, ...) fn##n
    #define syscall(...) MKFNS(syscall,##__VA_ARGS__)
    
    static inline long syscall0(long n){
        unsigned long r;
        asm volatile("int $128":"=a"(r):"a"(n):"memory");
        return r;
    }
    
    #define syscall1(n,a) _syscall1(n,(long)a)
    static inline long _syscall1(long n, long a){
        unsigned long r;
        asm volatile("int $128":"=a"(r):"a"(n),"b"(a):"memory");
        return r;
    }
    
    #define syscall2(n,a,b) _syscall2(n,(long)a,(long)b)
    static inline long _syscall2(long n, long a, long b){
        unsigned long r;
        asm volatile("int $128":"=a"(r):"a"(n),"b"(a),"c"(b):"memory");
        return r;
    }
    
    #define syscall3(n,a,b,c) _syscall3(n,(long)a,(long)b,(long)c)
    static inline long _syscall3(long n, long a, long b, long c){
        unsigned long r;
        asm volatile("int $128" : "=a"(r):"a"(n),"b"(a),"c"(b),"d"(c):"memory");
        return r;
    }
    
    #define syscall4(n,a,b,c,d) _syscall4(n,(long)a,(long)b,(long)c,(long)d)
    static inline long _syscall4(long n, long a, long b, long c, long d){
        unsigned long r;
        asm volatile("int $128":"=a"(r):"a"(n),"b"(a),"c"(b),"d"(c),"S"(d):"memory");
        return r;
    }
    
    #define syscall5(n,a,b,c,d,e) _syscall5(n,(long)a,(long)b,(long)c,(long)d,(long)e)
    static inline long _syscall5(long n, long a, long b, long c, long d, long e){
        unsigned long __ret;
        __asm__ __volatile__ ("int $128" : "=a"(__ret) : "a"(n), "b"(a), "c"(b), "d"(c), "S"(d), "D"(e) : "memory");
        return __ret;
    }
    
    void exit(long a){asm volatile("int $128":"=a"(a):"a"(1),"b"(a):"memory");}
    extern char **environ;
    
    asm(".text\n"
    ".global _start\n"
    "_start:\n"
    "popl %ecx\n"
    "movl %esp,%esi\n"
    "pushl %ecx\n"
    "leal 4(%esi,%ecx,4),%eax\n"
    "pushl %eax\n"
    "pushl %esi\n"
    "pushl %ecx\n"
    "movl %eax,environ\n"
    "call main\n"
    "pushl %eax\n"
    "call exit\n"
    "hlt\n"
    ".Lstart:\n"
    ".size _start,.Lstart-._start\n"
    );
    
    #define aservice(...) syscall(__NR_aservice,__VA_ARGS__)
    #define write(...) syscall(__NR_write,__VA_ARGS__) //#define __NR_write 4
    
    然后,您可以运行一个简单的测试程序,以确保能够处理系统调用

    int main(void){write(1,"hello world!\n",13);}
    
    使用内置的gcc-nostlib-fno编译


    这将允许您测试是否可以访问系统调用,以便知道问题是您的系统调用还是您访问系统调用的方式。

    您是否记得配置内核来编译它?我做了。我还向makefile添加了必要的更改。