转自: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. 裸机——DDR

    1.DDR介绍 DDR,是SDRAM的改进,是双通道的SDRAM, SDRAM是同步动态随机访问存储器. SDRAM与SRAM相对于,二者的特点是: SDRAM 需要初始化,使用时许访问,价格便宜. ...

  2. 猜数字问题 python

    猜数字问题,要求如下: ① 随机生成一个整数 ② 猜一个数字并输入 ③ 判断是大是小,直到猜正确 ④ 判断时间提示:需要用time模块.random模块该题目不需要创建函数 import random ...

  3. pdfmake实现中文支持,解决中文乱码问题

    引言:当初自己为了在项目中bootstrap-table中实现导出pdf,使用的pdfmake,但是pdfmake默认使用的不是中文字体,实现pdfmake使用中文字体主要就是编译新的vfs_font ...

  4. C#学习你需要知道的---(For和Foreach)

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52577283 作者:car ...

  5. SpringMVC---其它常用注解

    常用注解 PathVariable @RequestMapping注解中使用占位符的情况下,需要使用@PathVariable注解指定占位符参数.即指定占位符中的值与方法中哪一个参数进行匹配.如果方法 ...

  6. 7 Django分页器文章分页

    1.复习 2.这节课要解决的问题? 3.分页的原理 4.准备工作 (1)创建Django项目 C:\Users\Administrator\Desktop\root3>django-admin ...

  7. web在线调试

    xx <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta h ...

  8. python和matlab

    一.python简介 python是一种面向对象的解释型计算机程序设计语言.python是纯粹的自由软件,源代码和解释器CPython遵循GPL协议.Python语法简介清晰,特色之一是强制用空白符作 ...

  9. Java 注解(Annoation)学习笔记

    1 Junit中的@Test为例: 1.1 用注解(@Test)前 private boolean isTestMethod(Method m) { return m.getParameterType ...

  10. 《Cracking the Coding Interview》——第2章:链表——题目7

    2014-03-18 02:57 题目:检查链表是否是回文的,即是否中心对称. 解法:我的做法是将链表从中间对半拆成两条,然后把后半条反转,再与前半条对比.对比完了再将后半条反转了拼回去.这样不涉及额 ...