относительно того, "как насчет copy_to_user, поскольку ядро передает адрес пространства ядра, как может процесс пользовательского пространства получить к нему доступ"
Процесс пространства пользователя может пытаться получить доступ к любому адресу. Однако, если адрес не отображается в пользовательском пространстве этого процесса (то есть в таблицах страниц этого процесса) или если существует проблема с доступом, например попытка записи в местоположение только для чтения, то генерируется ошибка страницы. Обратите внимание, что, по крайней мере, на x86, каждый процесс имеет все пространство ядра, отображаемое в младшем 1 гигабайте виртуального адресного пространства этого процесса, в то время как 3 верхних гигабайта в общем адресном пространстве 4 ГБ (я использую здесь 32-битную классическую case) используются для текста процесса (т.е. кода) и данных.
Копирование в или из пользовательского пространства выполняется кодом ядра, который выполняется от имени процесса, и фактически это отображение памяти (то есть таблицы страниц) этого процесса, которые используются во время копирования. Это происходит во время выполнения в режиме ядра - то есть в привилегированном режиме / режиме супервизора на языке x86.
Предполагая, что код пользовательского пространства прошел законное целевое местоположение (то есть адрес, правильно сопоставленный в адресном пространстве этого процесса) для копирования данных, copy_to_user, запуск из контекста ядра сможет нормально записывать этот адрес / область без проблемы и после того, как элемент управления возвращается к пользователю, пользовательское пространство также может считывать данные из этой настройки местоположения самим процессом, с которого можно начать.
Более интересные подробности можно найти в главах 9 и 10 «Понимание ядра Linux», 3-е издание, Даниэль П. Бове, Марко Чезати. В частности, access_ok () является необходимой, но не достаточной проверкой достоверности. Пользователь по-прежнему может передавать адреса, не принадлежащие адресному пространству процесса. В этом случае возникнет исключение Page Fault, пока код ядра выполняет копию. Наиболее интересной частью является то, как обработчик ошибок страницы ядра определяет, что ошибка страницы в таком случае не из-за ошибки в коде ядра, а скорее из-за неправильного адреса пользователя (особенно, если рассматриваемый код ядра взят из модуля ядра). загружен).