sys v shared memory from kernel module to user spa

2019-09-08 18:40发布

问题:

i am new in linux kernel module developpement and i am searching for sharing a memory segment from kernel module to user space process to escape latency of copying data.

i am using the sys v shared memory api, when i share memory between two process it's work fine, but i am not able to share memory between process and kernel module.

bellow is my code of the kernel module and the user space app

server side : module

#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" );

client side : process

#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);
    }
}

any suggestion or document can help.

回答1:

System calls are not intended for being use by the kernel: they are for user programs only. Also, it is unlikely that is sys v memory sharing works for kernel threads.

Kernel and kernel modules have their own mechanism for interract with user space. For sharing memory, your kernel module may implement character device and mmap method for it, which maps kernel's allocated memory to user. See example of such mmap implementation in Linux Device Drivers(3d edition), Chapter 15.