User space'den /dev/mem ve mmap ile donanım register'larına erişmek nasıl yapılır? Riskleri ve daha iyi alternatifleri nelerdir?

Cevap

/dev/mem, fiziksel adres uzayının tamamını temsil eden bir karakter cihazıdır. mmap() ile bir peripheral'ın fiziksel adres bölgesini sürecin sanal adres uzayına eşleyip register'lara doğrudan pointer ile erişebilirsiniz. Prototip ve hızlı test için kullanışlıdır ama ürün kodu için genelde uygun değildir.

#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <unistd.h>

#define GPIO_BASE   0x0209C000UL   /* örnek: i.MX6 GPIO1 */
#define MAP_SIZE    0x1000UL

int fd = open("/dev/mem", O_RDWR | O_SYNC);
volatile uint32_t *gpio = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
                               MAP_SHARED, fd, GPIO_BASE & ~(MAP_SIZE - 1));
if (gpio == MAP_FAILED) { /* hata */ }

gpio[0x00 / 4] |= (1u << 5);       /* DR register'ı, bit 5 */

munmap((void *)gpio, MAP_SIZE);
close(fd);

Dikkat edilmesi gerekenler

  • Offset sayfa boyutuna hizalı olmalıdır (genelde 4 KB).
  • Pointer volatile olmalı; O_SYNC ile önbelleksiz (uncached) eşleme istenir.
  • Root yetkisi gerekir; CONFIG_STRICT_DEVMEM açık kernellerde bazı bölgelere erişim engellenir.

Riskler

  • Kernel sürücüsüyle yarış: Aynı register'ı kernel de kullanıyorsa read-modify-write çakışmaları olur, sistem kararsızlaşır.
  • Güvenlik: Tüm fiziksel belleğe erişim, kernel belleğinin okunup yazılabilmesi demektir.
  • Kesme yok: Kesmeyi user space'de alamazsınız, polling yapmak zorunda kalırsınız.
  • Clock/power yönetimi: Kernel, kullanılmadığını düşündüğü bloğun saatini kapatabilir; erişim bus hatasıyla çöker.

Daha iyi alternatifler

  • Var olan alt sistemi kullanmak: libgpiod, spidev, i2c-dev, IIO.
  • UIO (Userspace I/O): Device tree'de tanımlanan bölgeyi /dev/uio0 üzerinden güvenli şekilde mmap eder ve kesmeleri read() ile bildirir.
  • PCIe/IOMMU olan sistemlerde VFIO.
  • Kalıcı çözüm için küçük bir kernel driver yazmak.
  1. Linux'ta user space'den GPIO kontrol etmek için sysfs mi libgpiod mu kullanılmalı? Neden?KolayGömülü LinuxEmbedded
  2. Linux kernel'de kesme işleme neden top half ve bottom half olarak ikiye ayrılır? Softirq, tasklet, workqueue ve threaded IRQ arasındaki farklar nelerdir?ZorGömülü LinuxEmbedded
  3. Cross-compilation nedir? Bir cross toolchain hangi bileşenlerden oluşur ve sysroot ne işe yarar?KolayGömülü LinuxEmbedded
  4. Yocto Project ile Buildroot arasındaki farklar nelerdir? Bir ürün için hangisini seçersiniz?OrtaGömülü LinuxEmbedded
  5. Bir donanım için kernel modülü (kernel space driver) mi yoksa user space driver mı yazarsınız? Artıları ve eksileri nelerdir?OrtaGömülü LinuxEmbedded
  6. Device tree nedir, neden kullanılır? .dts, .dtsi, .dtb ve overlay kavramlarını açıklayın.OrtaGömülü LinuxEmbedded

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle