💻 Modül 6 · Yazılım Yığını · Bölüm 6.2 · 10 dk okuma

Linux Kernel ve aether-driver

SIDRA özel kernel modülü — aether-driver iç yapısı.

Bu bölümde öğreneceklerin

  • aether-driver kaynak yapısını ve build sürecini açıkla
  • Module init/exit, IOCTL handler, interrupt handler kod parçalarını oku
  • Kernel debugging stratejilerini (printk, dmesg, kgdb) söyle
  • Driver güvenlik en iyi uygulamalarını uygula
  • aether-driver upstream'e Linux kernel sokma sürecini özetle

Açılış: aether-driver Anatomi

aether-driver SIDRA’nın resmi Linux kernel modülüdür. C dilinde, ~5000 satır. Open source (GPL v2). GitHub’da yayında.

Bu bölüm kaynak kodun yapısını, ana fonksiyonlarını, ve nasıl kullanılacağını anlatır.

Sezgi: 5 Ana Dosya

aether-driver/ repo:

src/
├── pci.c           # PCIe enumeration + probe/remove
├── device.c        # /dev/sidra0 char device
├── ioctl.c         # IOCTL handlers (33 komut)
├── dma.c           # DMA buffer yönetimi
├── interrupt.c     # IRQ handlers
├── sysfs.c         # /sys/class/sidra debug arayüzü
├── firmware.c      # Firmware yükleme
└── sidra_dev.h     # Header
Makefile
README.md

Build: make -C /lib/modules/$(uname -r)/build M=$PWD modules.

Install: sudo insmod sidra.ko veya modprobe sidra.

Formalizm: Driver Internals

L1 · Başlangıç

Module init/exit:

static int __init aether_init(void) {
    int ret = pci_register_driver(&aether_pci_driver);
    if (ret) return ret;
    
    pr_info("aether-driver loaded, version %s\n", AETHER_VERSION);
    return 0;
}

static void __exit aether_exit(void) {
    pci_unregister_driver(&aether_pci_driver);
    pr_info("aether-driver unloaded\n");
}

module_init(aether_init);
module_exit(aether_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SIDRA Team");

Probe (PCIe cihaz bulundu):

static int aether_probe(struct pci_dev *pdev, const struct pci_device_id *id) {
    struct sidra_dev *sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
    pci_set_drvdata(pdev, sdev);
    
    pci_enable_device(pdev);
    pci_set_master(pdev);  // bus master için
    pci_request_regions(pdev, "sidra");
    
    // BAR0 = control registers
    sdev->bar0 = pci_iomap(pdev, 0, 0);
    
    // BAR1 = DMA area
    sdev->bar1 = pci_iomap(pdev, 1, 0);
    
    // IRQ
    pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
    request_irq(pci_irq_vector(pdev, 0), aether_irq_handler,
                0, "sidra", sdev);
    
    // /dev/sidra0
    create_char_device(sdev);
    
    // Firmware yükle
    aether_load_firmware(sdev);
    
    return 0;
}
L2 · Tam

IOCTL handler:

static long aether_ioctl(struct file *f, unsigned int cmd, unsigned long arg) {
    struct sidra_dev *sdev = f->private_data;
    
    switch (cmd) {
    case SIDRA_IOCTL_VERSION: {
        u32 ver = readl(sdev->bar0 + REG_VERSION);
        return copy_to_user((void __user *)arg, &ver, sizeof(ver));
    }
    case SIDRA_IOCTL_LOAD_MODEL: {
        struct model_data m;
        copy_from_user(&m, (void __user *)arg, sizeof(m));
        return aether_load_model(sdev, &m);
    }
    case SIDRA_IOCTL_INFER: {
        struct inference_req req;
        copy_from_user(&req, (void __user *)arg, sizeof(req));
        return aether_run_inference(sdev, &req);
    }
    // ... 33 IOCTL komut
    default:
        return -ENOTTY;
    }
}

Interrupt handler:

static irqreturn_t aether_irq_handler(int irq, void *data) {
    struct sidra_dev *sdev = data;
    u32 status = readl(sdev->bar0 + REG_INT_STATUS);
    
    if (status & INT_INFERENCE_DONE) {
        wake_up(&sdev->infer_wait);
        writel(INT_INFERENCE_DONE, sdev->bar0 + REG_INT_CLEAR);
    }
    
    if (status & INT_ERROR) {
        u32 err = readl(sdev->bar0 + REG_ERROR_CODE);
        pr_warn("SIDRA error: 0x%x\n", err);
    }
    
    return IRQ_HANDLED;
}
L3 · Derin

Debug stratejileri:

  1. printk: pr_info, pr_warn, pr_err. dmesg ile görünür.
  2. sysfs: /sys/class/sidra/sidra0/temperature, /error_count.
  3. debugfs: /sys/kernel/debug/sidra/. Detaylı stats.
  4. kgdb: kernel debugger. Karmaşık.
  5. ftrace: function trace. Performance profiling.

Race condition’lar:

Kernel preemptive. Driver kritik bölge için spinlock veya mutex:

mutex_lock(&sdev->cmd_lock);
// kritik bölge
mutex_unlock(&sdev->cmd_lock);

Power management:

Suspend/resume callback’ler:

static int aether_suspend(struct pci_dev *pdev, pm_message_t state) {
    // Çipi sleep moda al, state sakla
    return 0;
}

static int aether_resume(struct pci_dev *pdev) {
    // Çipi uyandır, state geri yükle
    return 0;
}

Multi-instance:

Birden fazla SIDRA çipi varsa /dev/sidra0, /dev/sidra1, … her biri ayrı major/minor. Driver minor numarayla cihazı seçer.

Upstream’e gönderim:

Linux kernel’a kabul edilmek için:

  1. Coding style (kernel checkpatch.pl).
  2. Documentation/.
  3. SubmittingPatches kuralları.
  4. LKML (Linux Kernel Mailing List) review.
  5. Maintainer ile review.

SIDRA upstream hedefi: 2027 Y1 production sonrası. ASELSAN/üniversite Linux community katkısı.

Kernel ABI:

aether-driver’in IOCTL interface stabil. Versiyonlama:

  • AETHER_API_V1 (Y1): 33 IOCTL.
  • AETHER_API_V2 (Y3): + 10 IOCTL (yeni features).

User-space app her ikisini destekler (compile-time check).

Deney: aether-driver Build + Test

Build:

cd aether-driver/
make
# Çıktı: sidra.ko

Yükle:

sudo insmod sidra.ko
dmesg | tail
# Çıktı: aether-driver loaded, version 1.0.0
#         sidra 0000:01:00.0: PCIe device probed
#         sidra: /dev/sidra0 created

Test:

ls /dev/sidra0
# crw-rw---- 1 root sidra  243, 0 Apr 19 16:00 /dev/sidra0

cat /sys/class/sidra/sidra0/temperature
# 65

cat /sys/class/sidra/sidra0/version
# 0x00010000

Hata kontrolü:

cat /sys/class/sidra/sidra0/error_count
# 0

Kaldır:

sudo rmmod sidra
dmesg | tail
# Çıktı: aether-driver unloaded

Süre: Tüm cycle ~1 dakika. Geliştirici workflow standart.

Kısa Sınav

1/6aether-driver hangi dilde yazıldı?

Laboratuvar Görevi

aether-driver geliştirici cycle.

Senaryo: Yeni bir IOCTL ekle (SIDRA_IOCTL_GET_TEMP).

Adımlar:

  1. sidra_dev.h IOCTL kodu ekle: #define SIDRA_IOCTL_GET_TEMP _IOR('s', 5, int).
  2. ioctl.c switch case ekle, bar0 + REG_TEMP oku, copy_to_user.
  3. Build: make.
  4. Reload: sudo rmmod sidra && sudo insmod sidra.ko.
  5. Test C kodu yaz, ioctl çağır.
  6. dmesg ile log kontrol.

Süre: Yeni feature ~30 dakika (deneyimli driver dev için).

Pratik tip: ioctl numaraları ('s', 5) çakışmasın. Linux ioctl-number.txt referans.

Özet Kart

  • aether-driver: SIDRA resmi Linux kernel modülü, C, ~5K satır, GPL.
  • Yapı: pci.c, device.c, ioctl.c, dma.c, interrupt.c, sysfs.c, firmware.c.
  • Build: standart kernel module Makefile.
  • Debug: printk + dmesg, sysfs, debugfs, kgdb.
  • Multi-instance: /dev/sidra0, sidra1, …
  • Upstream: 2027 hedefi, mainline kernel.

Vizyon: aether-driver Türkiye Kernel Topluluğu

aether-driver upstream Linux’a girdiğinde:

  • Türkiye’den ilk büyük donanım driver’ı (ASELSAN, BİLGEM küçük katkıları olmuş).
  • Türk yazılımcılar mainline maintainer olabilir.
  • Kernel topluluğunda görünürlük → SIDRA marka.
  • Akademik bonus: PhD tezleri kernel cinsinden.

Daha İleri