Chinaunix首页 | 论坛 | 博客
  • 博客访问: 437289
  • 博文数量: 123
  • 博客积分: 2686
  • 博客等级: 少校
  • 技术积分: 1349
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 22:11
文章分类
文章存档

2012年(3)

2011年(10)

2010年(100)

2009年(10)

我的朋友

分类: LINUX

2009-12-25 11:47:50

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

 

环境: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->parent->comm);
    return 1;
}


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

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



#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.


STEP 8: 查看printk的输出。printk函数的输出被记录在 /var/log/messges里面。

输入,cat /var/log/messges. 可以得到:




Dec 25 11:37:05 localhost kernel: *******************************************
Dec 25 11:37:05 localhost kernel: --------the output of mycall------------
Dec 25 11:37:05 localhost kernel: *****************************************
Dec 25 11:37:05 localhost kernel:
Dec 25 11:37:05 localhost kernel: Name        pid     state   ParentName
Dec 25 11:37:05 localhost kernel: init        1       1       swapper
Dec 25 11:37:05 localhost kernel: kthreadd    2       1       swapper
Dec 25 11:37:05 localhost kernel: migration/0 3       1       kthreadd
Dec 25 11:37:05 localhost kernel: ksoftirqd/0 4       1       kthreadd
Dec 25 11:37:05 localhost kernel: watchdog/0  5       1       kthreadd
Dec 25 11:37:05 localhost kernel: events/0    6       1       kthreadd
Dec 25 11:37:05 localhost kernel: cpuset      7       1       kthreadd
Dec 25 11:37:05 localhost kernel: khelper     8       1       kthreadd
Dec 25 11:37:05 localhost kernel: netns       9       1       kthreadd

………………



后记:这篇博客主要讲了添加系统调用的步骤,和一些基本的解释。然而,系统调用是一个非常复杂的过程,涉及到很多东西。我将在下一篇博客重点分析系统调用,由表及里,层层剥离下去。
阅读(3203) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-12-03 20:48:24

非常有用,谢谢分享。封装了的系统调用确实让人找起来有些困难。

chinaunix网友2010-05-16 00:29:18

正纠结着呢,感谢楼主!

chinaunix网友2009-12-31 00:16:08

恁个好的东西,啷个都没人回复的哦?