将kmalloc内存块转换为多个结构

时间:2016-10-17 14:44:32

标签: c linux memory linux-kernel mmap

我必须保留大量内核内存(1.5 MB)并与用户空间共享。对于简短的故事,我加载我的内核模块,它使用kmalloc在init函数中分配一个大内存缓冲区,然后用户程序调用ioctl来检索内核内存地址并使用mmap重新映射它,因为我需要在两个部分之间共享这个内存

我想知道是否可以将此内存块转换为结构并将剩余内存用作数据缓冲区,并且两个部分都将看到相同的结构。 很难准确地解释我想要的东西,所以这里有一个例子。

以下是我想在驱动程序和用户空间程序之间共享的结构:

typedef struct _MemoryBlock {
    int param1;
    int param2;
    short* vm_array1;
    short* km_array1;
    long* vm_array2;
    long* km_array2;
} MemoryBlock;

调用ioctl时用于检索内存地址的结构:

typedef struct _MemStruct {
    void *address;    // Kernel memory address
    void *vmAddress;  // Virtual memory address
    size_t size;     // Size of the memory block
} MemStruct;

正如我所说,内核使用kmalloc分配了1.5 MB的内存,用户部分然后调用ioctl并使用MemStruct(由驱动程序更新并返回)检索此内存块的内核地址。 地址字段是kmalloc返回的内核地址, vmAddress 设置为NULL,并在调用mmap后更新:

MemStruct *memStruct = malloc(sizeof(MemStruct));
ioctl(_This.fd, IOCTL_GET_MEM, (unsigned long) memStruct);

然后我必须重新映射这个记忆:

unsigned long mask = getpagesize() - 1;
off_t offset = ((unsigned long) memStruct->address) & ~mask;
memStruct->vmAddress = mmap(0, memStruct->size, PROT_READ | PROT_WRITE, MAP_SHARED, _This.fd, offset);

在用户部分,我想这样做:

MemoryBlock *memBlock = (MemoryBlock*) memStruct->vmAddress;
memBlock->param1 = 42;
memBlock->param2 = 0;
vm_array1 = (short*) (memStruct->vmAddress + sizeof(MemoryBlock));
km_array1 = (short*) (memStruct->address + sizeof(MemoryBlock));

int i; 
for (i = 0; i < 1000; i++) {
    vm_array1[i] = 42;
}

如您所见,我使用内存的剩余空间(在结构使用的内存之后)声明一个短数组。

之后,驱动程序也可以使用km_array1访问相同的内存。

这可能吗?

1 个答案:

答案 0 :(得分:1)

我认为struct _Menstruct的字段'address'包含kmalloc返回的值。在这种情况下,此值在内核空间之外没有任何可见性。在用户部分中,您创建一个指向短类型(km_array1)的指针,该指针指向内核地址。您可能会遇到段错或内存违规。您需要在内核中进行分配(km_array1 =(short *)(memstruct-&gt; address + sizeof(MemoryBlock))尝试使用km_array1变量在内核空间中编写一些随机值,并使用用户部分读取它们vm_array1。