При написании драйвера устройства ядра Linux (особенно на ARM64) я узнал из таких ресурсов, как Драйверы устройств Linux и различных онлайн-материалов, что мне следует использовать методы доступа, такие как writel(), readl(), iowrite32(), ioread32() и т. д. при выполнении операций загрузки/сохранения в памяти ввода/вывода. Насколько я понимаю, эти средства доступа необходимы для обеспечения корректного поведения при наличии оптимизаций компилятора, кэширования ЦП и переупорядочения памяти.
Однако я также видел, что такие платформы, как Userspace I/O (UIO), позволяют сопоставлять память ввода-вывода устройства с адресным пространством пользовательского процесса с помощью mmap(). Это дает приложению указатель на область памяти устройства.
Мой вопрос:
Если я получу такой указатель в пользовательском пространстве через mmap(), безопасно ли напрямую разыменовывать его для выполнения операций загрузки/сохранения? Или мне все еще нужно беспокоиться о таких проблемах, как кеширование, переупорядочение памяти или оптимизация компилятора?
Насколько я понимаю, в ARM64 память устройства обычно отображается как строго упорядоченная или некэшируемая, поэтому переупорядочение и кеширование могут не вызывать проблем, но я не совсем уверен, гарантирует ли это безопасный прямой доступ из пользовательского пространства.
Более конкретно:
- Достаточно ли прямого разыменования указателя для MMIO в пользовательском пространстве?
- Существуют ли особенности архитектуры (например, ARM64 или x86)?
- Нужны ли какие-либо барьеры памяти или специальная обработка в пользовательском пространстве?
- Я неправильно понимаю, как UIO и mmap() обрабатывают атрибуты памяти?
Спасибо!
Мобильная версия