Мне любопытно, потому что я получил панику ядра после попытки получить доступ к памяти напрямую (тогда я нашел эти функции).
Зачем вам нужно использовать copy_to_user()/copy_from_user() для доступа к пользовательскому пространству из ядра?
Ответ 1
Эти функции делают несколько вещей:
- Они проверяют, является ли предоставленный блок пользовательского пространства полностью внутри пользовательской части адресного пространства (
access_ok()
) - это запрещает приложениям пользовательского пространства запрашивать ядро для чтения/записи адресов ядра; - Они возвращают ошибку, если какой-либо из адресов недоступен, что позволяет возвращать ошибку в пользовательское пространство (
EFAULT
) вместо сбоя ядра (это реализуется специальным сотрудничеством с обработчиком ошибок страницы, который специально может обнаруживать, когда возникает ошибка в одной из функций доступа к памяти пользователя); - Они допускают макет, специфичный для архитектуры, например, для обеспечения согласованности архитектур с виртуальными кэшами, для отключения защиты, такой как SMAP, или для переключения адресных пространств на архитектурах с отдельными адресными пространствами пользователя/ядра, такими как S/390.
Ответ 2
Эти функции проверяют доступность памяти. Если ядро пытается напрямую получить доступ к не доступному адресу, он будет паниковать. Но, кроме того, ядро и пользовательские адресные пространства могут быть разными... действительный адрес в адресном пространстве пользователя может быть недоступен в ядре, и если это так, он может указывать на материал ядра, а не на пользовательский материал.
Подробнее см. http://www.ibm.com/developerworks/linux/library/l-kernel-memory-access/index.html
В исторической заметке: когда-то существовали операционные системы, в которых ядро было спроектировано как часть пользовательского адресного пространства, а в этих системах ядро всегда могло напрямую обращаться к пользовательскому пространству. Там могут быть такие системы, но современный Linux не один. Память пользовательского процесса, являющаяся частью адресного пространства ядра, всегда является вариантом для реализации, и это может сделать copy_to_user и copy_from_user намного быстрее.