转自: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. [Bzoj3611]大工程(虚树+DP)

    Description 题目链接 Solution 在虚树上跑DP即可 关于虚树的建立,是维护一个最右链的过程 关键代码如下: sort(A+1,A+k+1,cmp);//按dfs序排序 s[top= ...

  2. luogu2221 [HAOI2012]高速公路

    和sdoi的相关分析很像qwq,推柿子然后线段树搞搞 #include <iostream> #include <cstdio> using namespace std; ty ...

  3. PHP字符串word末字符大小写互换

    要求 给出一个字符串如 “A journey of, a thousand 'miles' must can't \"begin\" with a single step.” ,通 ...

  4. global js库

    var GLOBAL = {}; GLOBAL.namespace = function(str) { var arr = str.split("."), o = GLOBAL,i ...

  5. web自动化测试,定位不到元素的原因及解决方案(持续更新中2018年9月29日)

    主要讲自己在实战中遇到的坑: 1.动态id定位不到元素 分析原因:每次打开页面,ID都会变化.用ID去找元素,每次刷新页面ID都会发生变化. 解决方案:推荐使用xpath的相对路径方法或者cssSel ...

  6. APPIUM-----自动发现兼容的Chromedrivers

    使用Appium Desired Capabilities:chromedriverExecutableDir chromeDriver所有版本下载路径:https://chromedriver.st ...

  7. cloud.cfg_for_centos

    users: - default disable_root: 0 ssh_pwauth: 1 locale_configfile: /etc/sysconfig/i18n mount_default_ ...

  8. git使用及一些配置、问题

    安装https://git-for-windows.github.io/ 一.绑定用户名.邮件地址 git config --global user.name "Your Name" ...

  9. Linux网络运维相关

    删除特殊的用户和用户组 userdel games group games   关闭不需要的服务 chkconfig chkconfig --level 345 bluetooth off   删减系 ...

  10. realloc在aarch64_be-gcc的奇怪表现

    最近遇到一个使用aarch64_be-gcc编译的ssh服务器出现不能通过ssh1协议使用密钥+passphrase不能正常登陆的问题. (⊙o⊙)…不要奇怪为啥还在用SSH1,我也在奇怪.. 一顿捣 ...