2016-10-17 4 views
0

Я должен зарезервировать большое количество памяти ядра (1,5 МБ) и поделиться им с пользовательским пространством. Для короткой истории я загружаю модуль ядра, который выделяет большой буфер памяти в функции init с помощью kmalloc, затем пользовательский вызов программы ioctl извлекает адрес памяти ядра и перенастраивает его с помощью mmap, потому что мне нужно разделить эту память между двумя частями ,Включить блок памяти kmalloc в несколько структур

Я хотел бы знать, можно ли сделать этот блок памяти как структуру и использовать оставшуюся память в качестве буфера данных, и обе части будут видеть одну и ту же структуру. Трудно объяснить, что именно я хочу, вот пример.

Вот структура я хочу разделить между драйвером и программой пространства пользователя:

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; 

Как я уже сказал, ядро выделило 1,5 МБ памяти, используя kmalloc, пользовательская часть затем вызовет 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; 
} 

Как вы можете себе e Я использую оставшееся пространство памяти (после памяти, используемой структурой), чтобы объявить короткий массив.

После этого водитель может также получить доступ к той же памяти, используя km_array1.

Возможно ли это?

ответ

1

Я полагаю, что поле 'address' вашей структуры _Menstruct содержит значение, возвращаемое kmalloc. В этом случае это значение не имеет видимости вне пространства ядра. В пользовательской части вы создаете указатель на короткий тип (km_array1), который указывает на адрес ядра. Вероятно, у вас будет нарушение segfault или памяти. Вам нужно выполнить назначение в своем ядре (km_array1 = (short *) (memstruct-> address + sizeof (MemoryBlock)) попробуйте записать некоторые случайные значения в пространстве ядра с переменной km_array1 и прочитать их в пользовательской части с помощью vm_array1

+0

Да, это то, что я хочу сделать, km_array1 используется только в пространстве ядра: после переназначения пространство пользователя вписывается в структуру и адреса и может, наконец, совместно использовать структуру с драйвером. Таким образом, пользовательское пространство использует vm_array и драйвер использует km_array, но обе указывают одну и ту же физическую память. Это хороший способ сделать это? – AwaX

Смежные вопросы