转自:http://biancheng.dnbcw.net/linux/303362.html

linux下实现自己的系统调用。主要功能是:遍历系统的进程,并将相关的进程信息存放在自己定义的结构体中,同时编写系统调用,实现内核数据向用户空间的文件中写入。

首先实现相关的系统调用:

1.修改系统调用表:
在目录/usr/src/linux-2.6.33.1/arch/x86/kernel
修改文件:syscall_table_32.S 在文件的末尾处添加自己的系统调用表项。
如下:
        .long sys_rt_tgsigqueueinfo /* 335 */
.long sys_perf_event_open
.long sys_recvmmsg
.long sys_sayhello
        .long sys_getdata
        .long sys_datawrite
        .long sys_dataflush
其中绿色部分是上一个简单的系统调用测试。下面3个红色部分的是我现在要实现的从内核部分向用户空间写文件。
2.添加系统调用号。
在目录/usr/src/linux-2.6.33.1/arch/x86/include/asm/
修改文件unistd_32.h文件,在文件中添加自己的系统调用号。
如下:
#define __NR_perf_event_open 336
#define __NR_recvmmsg 337
#define __NR_syahello 338
#define  __NR_getdata                 339
#define  __NR_datawrite               340
#define  __NR_dataflush               341
同时修改接下来的定义:
#define NR_syscalls                   342          //这个表示的当前系统调用的总数
其中绿色部分是上一个简单的系统调用测试。下面3个红色的是我们当前需要关心的。
3.编写系统调用的处理函数:
原则上你可一在内核文件的任何位置添加你的处理函数。我这里选择在kernel目录下新建一个自己的C文件。
get_data.c
这就需要修改相关的Makefile文件。修改get_data.c所在的目录下的Makefile文件
找到大概16行,添加你的编译目标
如下(红色部分为自己添加的):
obj-y += groups.o
obj-y += get_data.o
get_data.c文件的内容:

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#define TASK_COMM_LEN 16
#define TMP_DATA_LEN 50
typedef struct my_task_struct {
    volatile long state;
    int prio, static_prio, normal_prio;
    pid_t pid;
    pid_t tgid;
    char comm[TASK_COMM_LEN];
    struct my_task_struct *next;
}my_struct_t, *my_struct_p;
my_struct_p get_data
(void)
{
    my_struct_p p, head, h;
    struct task_struct *task = NULL;
    head
= (my_struct_p)kmalloc(sizeof(my_struct_t), GFP_ATOMIC);
    head->next = NULL;
    h = head;
    for_each_process
(task) {
        p = (my_struct_p)kmalloc(sizeof(my_struct_t), GFP_ATOMIC);
        p
->state = task->state;
        p->prio = task->prio;
        p->static_prio = task->static_prio;
        p->normal_prio = task->normal_prio;
        p->pid = task->pid;
        p->tgid = task->tgid;
        
memset(p->comm, '\0', sizeof(p->comm));
        strncpy(p->comm, task->comm, TASK_COMM_LEN-1);
        p
->next = h->next;
        h->next = p;
        h = p;
    }
    return head;
}
int filewrite(const char * filename, my_struct_p head)
{
    struct file *filp;
    mm_segment_t fs;
    my_struct_p data;
    char *change_line = "\t";
    char *menu_line = "state\tprio\tstatic_prio\tnormal_prio\tpid\ttgid\tcomm\n";
    char tmpdata[TMP_DATA_LEN];
    data
= head->next;
    filp = filp_open(filename, O_RDWR|O_APPEND|O_CREAT, 0644);
    if(IS_ERR(filp)) {
        printk("open error!\n");
        return 1;
    }
    fs = get_fs();
    set_fs(KERNEL_DS);
    filp->f_op->write(filp, menu_line, strlen(menu_line), &filp->f_pos);
    
while(NULL != data) {
        memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->state), "%ld", data->state);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->prio), "%d", data->prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->static_prio), "%d", data->static_prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->normal_prio), "%d", data->normal_prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->pid), "%d", data->pid);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->tgid), "%d", data->tgid);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->comm), "%s", data->comm);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
        memset(tmpdata, '\0', TMP_DATA_LEN);
        strcpy(tmpdata, "\n");
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        data
= data->next;
    }
    set_fs(fs);
    filp_close(filp, NULL);
    return 0;
}
int data_flush(my_struct_p head)
{
    my_struct_p data;
    data = head;
    while(NULL != data) {
        head = head->next;
        kfree(data);
        data = head;
    }
    return 0;
}
asmlinkage my_struct_p sys_getdata
(void)
{
    my_struct_p res;
    res = get_data();
    return res;
}
asmlinkage
int sys_datawrite(const char *filename, my_struct_p head)
{
    return filewrite(filename, head);
}
asmlinkage
int sys_dataflush(my_struct_p head)
{
    return data_flush(head);
}

用户空间测试程序:test.c

#include <asm/unistd.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <string.h>
#define SYS_SAYHELLO 338
#define SYS_GETDATA 339
#define SYS_FILEWRITE 340
#define SYS_DATAFLUSH 341
struct my_struct {
    
volatile long state;
    int prio, static_prio, normal_prio;
    pid_t pid;
    pid_t tgid;
    char comm[16];
    struct my_struct *next;
};
int main(void)
{
    struct my_struct * data;
    
    data = syscall(SYS_GETDATA);
    syscall(SYS_FILEWRITE, "file", data);
    syscall(SYS_DATAFLUSH, data)
    return 0;
}
 

对test.c编译运行之后在当前目录下应该可以看到打印出的进程信息在文件file中。

实现自己的系统调用针对linux-2.6.34【转】的更多相关文章

  1. Virtio:针对 Linux 的 I/O 虚拟化框架

    Virtio:针对 Linux 的 I/O 虚拟化框架 --http://www.ibm.com/developerworks/cn/linux/l-virtio/#ibm-pcon 使用 KVM 和 ...

  2. Xshell6远程访问linux及Xftp6远程针对linux系统中文件操作(附图文详解)

    1.首先我们需要先做好前期准备工作,需要到XManager6官网上将Xshell及Xftp下载并安装,安装过程一直下一步就好了.这里是其官网:http://www.xshellcn.com/.安装完成 ...

  3. 针对Linux 文件完整性监控的实现

    针对Linux 文件完整性监控的实现 摘要 计算机和互联网是20世纪以来最伟大的发明之一,随着计算机技术的不断发展,人们的生活方式发生了巨大的变化.计算机和互联网的发展给人们的生产生活带来了极大的便利 ...

  4. ZTE AD3812 3G模块在linux 2.6.34 内核的开发板上的支持方法

    先说段废话,话说在linux 2.6.34 下,好多比较新的3G网卡及3G模块都没有很好的支持.如果想支持的这些3G网卡/3G模块呢,基本上有两种方式: 1.使用该3G模块的 linux 下的驱动,交 ...

  5. Ubuntu 14.04 + Linux 3.14.34 系统调用实现文件拷贝

    采用 64位系统, ubuntu 14.04 + 新内核linux-3.14.34 下载地址https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.1 ...

  6. 针对Linux ASP.NET MVC网站中 httpHandlers配置无效的解决方案

    近期有Linux ASP.NET用户反映,在MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404(找不到网页) ...

  7. 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案

    基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...

  8. 针对Linux系统主机,进入修复模式,解决开机报错问题

    1.让主机重启,进入开机时的内核选择界面,按e进入编辑界面 2.找到linux16那一行,将光标移动到最前面,按下End键,到这一行的末尾,然后空格 rd.break console=tty0 3.第 ...

  9. 该优化针对Linux X86_X64环境

    http://netkiller.github.io/www/tomcat/server.html 1. Tomcat优化其实就是对server.xml优化(开户线程池,调整http connecto ...

随机推荐

  1. ZOJ3640 概率DP

    Background If thou doest well, shalt thou not be accepted? and if thou doest not well, sin lieth at ...

  2. fromkeys语法/set集合/深浅拷贝/列表/字典的删除

    fromkeys语法: dic = {"apple":"苹果", "banana":"香蕉"} 返回新字典. 和原来的没 ...

  3. 3,版本控制git-多人协作

    如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到 `git clone` 命令. 如果你对其它的 VCS 系统(比如说Subversion)很 ...

  4. 1864: [Zjoi2006]三色二叉树

    1864: [Zjoi2006]三色二叉树 链接 分析: 做得最智障的一题了... 首先中间输出两个数之间没空格(换行居然也过了...), 写了dp[i][0/1/2],后来知道其实dp[i][0/1 ...

  5. Java中的垃圾回收机制&内存管理&内存泄漏

    1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...

  6. 即将到来的5G,我们该做些什么准备?

    本文来自网易云社区. 作者:任长存 5G和4G到底什么区别? 实际上5G只是4G通信技术上的演进,都是在 光速 = 波长*频率,这个数学公式上做文章,为什么这么讲? 首先大家都用过WIFI,WIFI的 ...

  7. 关于ADB push 出现failed to copy 'D:\file.xtxt' to '/system/temp/' : Read-only file system 的报错信息解决办法

    首先使用USB连接电脑与小机,然后安装adb相应的驱动,这是第一步,也是必须要做的. 进入doc系统后,敲入adb shell  可以进入linux命令行状态,说明adb可以使用了. 回到标题,我们现 ...

  8. Restful API实战

    简介:随着移动互联网的发展,客户端层出不穷,app,web,微信端等等,而后端业务逻辑基于是一致的,如何做到业务逻辑“一次编写,随时接入”?答案是通过远程调用API,而目前比较火的方案是“Restfu ...

  9. Entity Framework(一)

    相关知识点复习: 1.var 类型推断: var p=new Person(); 2.匿名类型: var a=new {Name="wang",Age=12  }; 3.给新创建的 ...

  10. php session访问限制

    登录 <?php // 启动会话 session_start(); // 注册登陆成功的 admin 变量,并赋值 true $_SESSION["admin"] = tru ...