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
volatileolmalı;O_SYNCile önbelleksiz (uncached) eşleme istenir. - Root yetkisi gerekir;
CONFIG_STRICT_DEVMEMaçı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 kesmeleriread()ile bildirir. - PCIe/IOMMU olan sistemlerde VFIO.
- Kalıcı çözüm için küçük bir kernel driver yazmak.
İlgili Gömülü Linux soruları
- Linux'ta user space'den GPIO kontrol etmek için sysfs mi libgpiod mu kullanılmalı? Neden?
- 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?
- Cross-compilation nedir? Bir cross toolchain hangi bileşenlerden oluşur ve sysroot ne işe yarar?
- Yocto Project ile Buildroot arasındaki farklar nelerdir? Bir ürün için hangisini seçersiniz?
- 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?
- Device tree nedir, neden kullanılır? .dts, .dtsi, .dtb ve overlay kavramlarını açıklayın.
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.