Как создать буфер пользовательского пространства из драйвера ядра Linux?Linux

Ответить
Anonymous
 Как создать буфер пользовательского пространства из драйвера ядра Linux?

Сообщение Anonymous »

Я пытаюсь обновить старый драйвер ядра для работы под Debian Bookworm, но у меня возникла проблема. Поскольку этот драйвер использует другой последовательный драйвер (например, /dev/ttyS4), он использует filp_open() для этого другого драйвера, а затем вызывает файловые операции (ioctl, чтение, запись) для управления этим другим драйвером с любыми параметрами буфера/структуры. пересылается в/из пользовательского пространства.
Однако, чтобы добиться этого, я считаю, что (вызывающий) драйвер ядра должен (каким-то образом) создавать буферы в пользовательском пространстве, чтобы использовать их для вызова другого драйвера. (исходный код использовал mm_seg_t и т. д.). Я думал, что все, что мне нужно сделать, это vmalloc() блок памяти, kmalloc() блок указателей страниц, а затем вызвать get_user_pages() для этого блока. Но когда я пробую это, get_user_pages() возвращает -14 (EFAULT).
Вот моя текущая попытка:

Код: Выделить всё

// Calculate page-aligned size of user data block
size_t szUserdata_sizeof = PAGE_ALIGN(sizeof(struct userdata));

// Calculate the number of pages
int iUserdata_numpages = szUserdata_sizeof / PAGE_SIZE;

// Allocate block of memory in kernel space
struct userdata * pstUserdata_kernel = vmalloc(szUserdata_sizeof);
if (pstUserdata_kernel == NULL) { return -ENOMEM; }

// Array to store pointers to the pinned pages
static struct page **papstUserdata_pages;
papstUserdata_pages = kmalloc(iUserdata_numpages * sizeof(struct page *), GFP_KERNEL);
if (papstUserdata_pages == NULL) { return -ENOMEM; }

// Determine the (fake) user-space address we will be using
unsigned long ulUserdata_user = (unsigned long)pstUserdata_kernel;

// Use get_user_pages() to pin the buffer's pages, simulating user-space memory
long ret = get_user_pages(ulUserdata_user, iUserdata_numpages, FOLL_WRITE, papstUserdata_pages, NULL);
Похоже, что мне не хватает очень маленького кусочка мозаики. Что мне нужно сделать, чтобы все заработало? Спасибо!
Примечание: я знаю, что более современный (и лучший) способ заставить драйвер ядра управлять другим драйвером ядра tty — это использовать tty_kopen_exclusive() и т. д.: но это будет значит переписать большую часть этого драйвера с нуля (чего я не думаю, что хочу делать).

Подробнее здесь: https://stackoverflow.com/questions/790 ... nel-driver
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»