Однако, чтобы добиться этого, я считаю, что (вызывающий) драйвер ядра должен (каким-то образом) создавать буферы в пользовательском пространстве, чтобы использовать их для вызова другого драйвера. (исходный код использовал 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
Мобильная версия