添加一个系统调用,遍历内核进程

    技术2022-05-19  17

     

    环境:Fedora 12

    内核:linux-2.6.32.2

     

    STEP  0: 编译一个linux-2.6.32.2内核,且能够正常启动。上一篇博客已经讲了。

    STEP  1: linux-2.6.32.2/arch/x86/kernel 目录中,找到syscall_table_32.S,在这个文件的最后一行,添加:.long sys_mycall

          

    .long sys_mycall

    STEP  2: 在linux-2.6.32.2/arch/x86/include/asm目录下,找到unistd_32.h,在这个文件的 #define NR_syscalls 337前面加:#define __NR_mycall  337,同时把NR_syscalls改成338.

     

    #define __NR_mycall 337#ifdef __KERNEL__

    #define __NR_syscalls 338 NR_syscalls,相当于系统调用表边界,所有系统号都得小于它。

    STEP  3: 在linux-2.6.32.2/include/linux 目录中,找到syscalls.h, 在这个文件中添加:asmlinkage long sys_mycall(void); 我认为这为系统调用函数声明。

    asmlinkage long sys_mycall(void); 

    STEP 4: 实现系统调用.在linux-2.6.32.2/kernel目录下,找到sys.c,在里面添加入系统调用的实现程序。在linux-2.6.32里面,跟以前的版本不一样,这里用到了宏SYSCALL_DEFINE0对系统调用进行了封装。难怪网上的都在说找不到系统调用的定义。

    next_task是内核定义的一个宏,用于寻找进程链表的下一个进程指针。程序如下:

    SYSCALL_DEFINE0(mycall){    struct task_struct *p;    printk("********************************************/n");    printk("------------the output of mycall------------/n");    printk("********************************************/n/n");    printk("%-20s %-6s %-6s %-20s/n","Name","pid","state","ParentName");    for(p = &init_task; (p = next_task(p)) != &init_task;)        printk("%-20s %-6d %-6d %-20s/n",p->comm , p->pid, p->state, p-< 

    /span>>parent->comm);    return 1;}

    STEP 5: 编译内核。make; make install;重启;

    STEP 6: 测试系统调用。编写程序test.c。前面我们定义了mycall的系统调用号是337.所以,在程序中,调用mycall的语句就是:syscall(337).程序如下:

    /span>include<stdio.h>int main(){    if(syscall(337))        printf("ok!/n");    else        printf("failed!/n");    return 0;}

    STEP 7: 编译test.cgcc test.c –o test, 执行 ./test.


    最新回复(0)