I have to reserve a large amount of kernel memory (1.5 MB) and share it with the user space. For the short story, I load my kernel module which allocates a large memory buffer in init function using kmalloc, then the user program call ioctl to retrieve the kernel memory address and remaps it using mmap because I need to share this memory between the two parts.
I would like to know if it's possible to cast this memory block as a structure and use the remaining memory as a data buffer and both parts would see the same structure. It's hard to explain exactly what I want so here is an example.
Here is the structure I want to share between the driver and the user space program :
typedef struct _MemoryBlock {
int param1;
int param2;
short* vm_array1;
short* km_array1;
long* vm_array2;
long* km_array2;
} MemoryBlock;
Structure used to retrieve memory addresses when calling ioctl :
typedef struct _MemStruct {
void *address; // Kernel memory address
void *vmAddress; // Virtual memory address
size_t size; // Size of the memory block
} MemStruct;
As I said, the kernel has allocated 1.5 MB of memory using kmalloc, user part then call ioctl and retrieve the kernel address of this memory block using MemStruct (which is updated by the driver and returned). The address field is the kernel address returned by kmalloc and vmAddress is set to NULL and will be updated after the call to mmap :
MemStruct *memStruct = malloc(sizeof(MemStruct));
ioctl(_This.fd, IOCTL_GET_MEM, (unsigned long) memStruct);
Then I have to remap this memory :
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);
And in the user part I would like to do this :
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;
}
As you can see I use the remaining space of the memory (after the memory used by the structure) to declare a short array.
After that the driver could also access the same memory using the km_array1.
Is this possible ?