Выделение user space памяти из Linux Kernel
Всем привет. Можно ли выделить область памяти пользовательского пространства и вернуть указатель на него из модуля ядра Linux? Я знаю, что пользовательские процессы используют виртуальную память и виртуальное адресное пространство, для выделения смежной виртуальной памяти можно использовать vmalloc, но будет ли она доступна пользовательскому процессу? Так же можно использовать kmalloc с флагом GFP_USER, но будет ли эта память доступна пользовательскому процессу? Так же я не уверен, не приведет ли доступ по адресам, указывающим на выделенную в другом процессе память, к segmentation fault. Буду благодарен тому, кто прольет свет на эти вопросы. Спасибо.
Ответы (1 шт):
Можно ли выделить область памяти пользовательского пространства и вернуть указатель на него из модуля ядра Linux?
Это довольно странная идея... А если при работающем приложении модуль будет выгружен из памяти ядра - тогда что произойдёт?
На самом деле, доступ к памяти пользователя из ядра возникает только в трёх ситуациях:
- Выполняется операция ввода в буфер пользователя
- Выполняется операция вывода из буфера пользователя
- Выполняется обработка вызова ioctl() в котором третий аргумент - указатель на буфер пользователя.
При всех трёх вариантах надобности выделить память пользователю из ядра просто не возникает. Для передачи данных при этом используются вызовы API ядра:
copy_to_user()
copy_from_user()
Поченму это так, почитатйте вот здесь:
Иногда, очень редко, возникает реальная ситуация, когда ядру необходимо вернуть пользователю заранее неизвестный объём памяти с данными. Широко известный пример - опрос пользователем свойств сетевых интерфейсов системы.
Пользователь заранее не знает, сколько интерфейсов в системе и не может заранее выделить достаточную память. Поэтому приходится использовать такой довольно запутанный механизм:
- Прикладная программа организует цикл вызова ioctl() начиная от буфера размером в один элемент.
- Ядро отвечает, что памяти недостаточно
- Прикладная программа выделяет больший буфер
- Выполняется вызов ioctl() с новым размером буфера
И так далее, пока ioctl() не завершится с нулевым кодом ошибки.