2016-06-07 113 views
0

我是linux内核模块开发的新手,我正在寻找从内核模块到用户空间进程的共享内存段以避免复制数据的延迟。从内核模块到用户空间进程的sys v共享内存

我正在使用sys v共享内存api,当我在两个进程之间共享内存时它工作正常,但我无法在进程和内核模块之间共享内存。

波纹管是我的内核模块和用户空间应用

服务器端的代码:模块

#include <linux/module.h> // init_module, cleanup_module // 
#include <linux/kernel.h> // KERN_INFO // 
#include <linux/types.h> // uint64_t // 
#include <linux/kthread.h> // kthread_run, kthread_stop // 
#include <linux/delay.h> // msleep_interruptible // 
#include <linux/syscalls.h> // sys_shmget // 

#define BUFSIZE 100 
#define SHMSZ BUFSIZE*sizeof(char) 
key_t KEY = 5678; 

static struct task_struct *shm_task = NULL; 


static char *shm = NULL; 
static int shmid; 

static int run_thread(void *data) 
{ 
    char strAux[BUFSIZE]; 
    shmid = sys_shmget(KEY, SHMSZ, IPC_CREAT | 0666); 
    if(shmid < 0) 
    { 
     printk(KERN_INFO "SERVER : Unable to obtain shmid\n"); 
     return -1; 
    } 
    shm = sys_shmat(shmid, NULL, 0); 
    if(!shm) 
    { 
     printk(KERN_INFO "SERVER : Unable to attach to memory\n"); 
     return -1; 
    } 
    strncpy(strAux, "hello world from kernel module", BUFSIZE); 
    memcpy(shm, strAux, BUFSIZE); 
    return 0; 
} 

int init_module() 
{ 
    printk(KERN_INFO "SERVER : Initializing shm_server\n"); 
    shm_task = kthread_run(run_thread, NULL, "shm_server"); 
    return 0; 
} 

void cleanup_module() 
{ 
    int result; 
    printk(KERN_INFO "SERVER : Cleaning up shm_server\n"); 
    result = kthread_stop(shm_task); 
    if(result < 0) 
    { 
     printk(KERN_INFO "SERVER : Unable to stop shm_task\n"); 
    } 
    result = sys_shmctl(shmid, IPC_RMID, NULL); 
    if(result < 0) 
    { 
     printk(KERN_INFO 
     "SERVER : Unable to remove shared memory from system\n"); 
    } 

} 


MODULE_LICENSE("GPL"); 
MODULE_AUTHOR(" MBA"); 
MODULE_DESCRIPTION("Shared memory server"); 

客户端:过程

#include <sys/ipc.h> // IPC_CREAT, ftok // 
#include <sys/shm.h> // shmget, ... // 
#include <sys/sem.h> // semget, semop // 
#include <stdio.h> // printf // 
#include <string.h> // strcpy // 
#include <stdint.h> // uint64_t // 

#define BUFSIZE 4096 
key_t KEY = 5678; 

int main(int argc, char *argv[]) { 
    int shmid, result; 
    char *shm = NULL; 

    shmid = shmget(KEY, BUFSIZE, 0666); 
    if (shmid == -1) { 
     perror("shmget"); 
     exit(-1); 
    } 
    shm = shmat(shmid, NULL, 0); 
    if (!shm) { 
     perror("shmat"); 
     exit(-1); 
    } 

    printf("%s\n", shm); 
    result = shmdt(shm); 
    if (result < 0) { 
     perror("shmdt"); 
     exit(-1); 
    } 
} 

任何建议或文档可以提供帮助。

+0

内核模块和用户空间应用程序打印了什么内容? – Tsyvarev

+0

当我试图插入模块.ko我得到错误:(-1)未知的符号引用sys_shmhet,sys_shmat ..,但编译完成。 – Mondher123

回答

0

系统调用不适合内核使用:它们仅适用于用户程序。此外,sys v内存共享不太可能适用于内核线程。

内核和内核模块有自己的机制用于与用户 空间进行交互。为了共享内存,你的内核模块可以为它实现字符设备和mmap方法,它将内核分配的内存映射到用户。请参阅Linux设备驱动程序(第三版),第15章mmap实现的示例。

+0

This [article](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwj1mNXXw6TNAhWJOBoKHTxgBK4QFggeMAA&url=http%3A%2F%2Fciteseerx.ist.psu。 edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.145.6401%26rep%3Drep1%26type%3Dpdf&usg = AFQjCNGh8qSDajUD0bPt0nbtM2PvQM5ikA&sig2 = TttseQSxvpZB1i7oC1lA5Q)提供了3种内核线程和用户空间应用程序之间快速数据传输的方法,其中之一是sys v shared记忆! – Mondher123

+0

这篇文章明确地告诉你,你需要修改内核**来让make sys v共享内存工作:'导出内核函数* sys_shmget *,* sys_semget * ...需要内核模块来创建和销毁SYS V共享内存区域......(在第16页末尾)。 – Tsyvarev

+0

谢谢Tsyvarev。 – Mondher123

相关问题