Tüm eğitimler
TEKNİK REHBERGÖMÜLÜ LİNUXKERNEL GELİŞTİRME2026

Rust ile Kernel Modülü
Geliştirme

Linux 6.1+ Rust for Linux altyapısı ile güvenli kernel modülü yazımı, C köprüleme, gömülü sürücü geliştirme ve Rust kernel API kullanımı.

00 Rust Kernel'da Neden?

Linux çekirdeğindeki güvenlik açıklarının büyük çoğunluğu bellek hatalarından kaynaklanır. Rust, bu hataları derleme zamanında tespit ederek gömülü Linux sürücülerini daha güvenli hale getirir.

Google Project Zero ve Microsoft güvenlik araştırmaları, kernel güvenlik açıklarının yüzde yetmişten fazlasının bellek hatalarından kaynaklandığını ortaya koymuştur. Use-after-free, buffer overflow, double-free ve data race gibi hatalar C dilinde derleme zamanında tespit edilemez; bu hatalar üretim ortamında sessiz veri bozulmasına veya ayrıcalık yükseltme açıklarına yol açar.

Kernel Güvenlik Açığı İstatistikleri

Use-after-free (UAF)Serbest bırakılan belleğe erişim; Linux CVE'lerinin %35+ kaynağı — Rust ownership ile derleme hatası
Null pointer dereferenceNULL göstericiye erişim; kernel panic/oops — Rust'ta Option<T> ile zorunlu kontrol
Data raceSenkronizasyonsuz paylaşılan bellek; Rust Send/Sync trait'leri ile derleme hatası
Double-freeAynı belleği iki kez serbest bırakma; Rust ownership semantiği ile imkansız
Buffer overflowDizi sınırı dışı yazma; Rust'ta güvenli dilimler (slice) ile derleme veya çalışma hatası

Rust vs C Kernel Geliştirmesi

Hata TürüC DavranışıRust Davranışı
Use-after-freeÇalışma zamanı — tanımsız davranışDerleme hatası — borrow checker engeller
Double-freeÇalışma zamanı — tanımsız davranışDerleme hatası — ownership kuralları
Data raceÇalışma zamanı — sessiz bozulmaDerleme hatası — Send/Sync trait'leri
Null pointer derefÇalışma zamanı — kernel panicOption<T> ile zorunlu None kontrolü
Integer overflowİşaretli: UB; işaretsiz: wrapDebug: panic; Release: wrap (açık)

Rust for Linux Zaman Çizelgesi

Linux 6.1 (Aralık 2022)Rust altyapısı ana çekirdeğe girdi: rustc, bindgen, temel abstraksiyonlar
Linux 6.2 (Şubat 2023)platform::Driver, regulator, GPIO abstraksiyonları eklendi
Linux 6.8 (Mart 2024)Nova GPU sürücüsü — Rust ile yazılmış ilk gerçek GPU sürücüsü
Linux 6.12+ (2024-2025)null_block, HID sürücüleri; abstraksyon API'leri olgunlaşıyor

Kernel Ortamında Rust Kısıtları

no_std ortamıStandart kütüphane yok; yalnızca core ve alloc (özel kernel allocator ile) kullanılabilir
Kernel allocatorBox/Vec bellek ayırma kmalloc kullanır; başarısız olabilir ve Result döner
Floating point yasağıKernel bağlamında FPU kullanımı yasak; kaydet/yükle işlemi gerektirir
Preemption kurallarıSpin lock tutarken uyuma yasak; Rust API'si bu kısıtı tip sistemi ile zorunlu kılar

01 Geliştirme Ortamı Kurulumu

Rust for Linux belirli bir Rust araç zinciri sürümü, bindgen ve Rust desteğiyle derlenmiş bir kernel kaynak ağacı gerektirir.

Araç Zinciri Gereksinimleri

# Kernel'in gerektirdiği Rust surum:
cat linux/rust/rust-version
# Ornek cikti: 1.78.0

# rustup ile o surumu kur
rustup toolchain install 1.78.0
rustup component add rust-src --toolchain 1.78.0
rustup component add rustfmt  --toolchain 1.78.0
rustup component add clippy   --toolchain 1.78.0

# bindgen kurulumu (LLVM gerektirir)
cargo install --locked bindgen-cli

# Aracları dogrula
make LLVM=1 rustavailable
# Cikti: Rust is available!

Kernel'i Rust Desteğiyle Derleme

# LLVM/Clang bagimliliklari (Ubuntu 22.04+)
sudo apt install llvm clang lld libclang-dev

# Temel kernel yapilandirmasi
make LLVM=1 defconfig

# Rust desteğini etkinlestir
make LLVM=1 menuconfig
# General setup --->
#   [*] Rust support    (CONFIG_RUST=y)

# Derleme (LLVM=1 zorunlu — Rust LLVM backend kullanir)
make LLVM=1 -j$(nproc)

# Modulleri derle
make LLVM=1 modules -j$(nproc)

Rust Kaynak Dosyaları için Kbuild Kuralları

Dosya/DizinRolü
rust/kernel/lib.rsTemel Rust kütüphanesi giriş noktası; kernel::* modülleri burada
rust/bindings/bindgen tarafından üretilen C fonksiyon ve struct bağlamaları
rust/kernel/sync/Mutex, SpinLock, Arc, CondVar senkronizasyon primitifleri
rust/kernel/alloc/Box, Vec, KBox gibi kernel allocator sarmalayıcıları
samples/rust/Örnek Rust modülleri — başlangıç için ideal başlangıç noktası

Dış Modül Geliştirme Ortamı

# Dış modül icin dizin yapisi
my_driver/
  Makefile
  Kbuild
  src/
    my_driver.rs

# Kbuild icerigi
obj-m := my_driver.o
my_driver-objs := src/my_driver.o

# Makefile icerigi
KDIR ?= /lib/modules/$(shell uname -r)/build
LLVM  = 1

all:
	$(MAKE) -C $(KDIR) M=$(PWD) LLVM=1 modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) LLVM=1 clean

# Derleme komutu
make LLVM=1 KDIR=/path/to/linux-source

02 İlk Rust Kernel Modülü

module! makrosu modül meta verilerini tanımlar; C'deki module_init/module_exit yerine Module trait'inin init() ve drop() metotları kullanılır.

Minimal "Merhaba Kernel" Modülü

// SPDX-License-Identifier: GPL-2.0
//! Ilk Rust kernel modulu -- temel yapi iskeleti.

use kernel::prelude::*;

module! {
    type: HelloKernel,
    name: "hello_kernel",
    author: "Emirhan Pehlevan",
    description: "Ilk Rust kernel modulu ornegi",
    license: "GPL",
}

struct HelloKernel;

impl kernel::Module for HelloKernel {
    fn init(_name: &'static CStr,
            _module: &'static ThisModule) -> Result<Self>
    {
        pr_info!("Merhaba, Rust Kernel! Modul yuklendi.\n");
        Ok(HelloKernel)
    }
}

impl Drop for HelloKernel {
    fn drop(&mut self) {
        pr_info!("Gule gule, Rust Kernel! Modul kaldiriliyor.\n");
    }
}

module! Makrosu Parametreleri

typeModule trait'ini implemente eden struct — init ve drop burada çalışır
nameKernel'de görünen modül adı; lsmod çıktısında bu isim görünür
authorMODULE_AUTHOR — modinfo çıktısında gösterilir
descriptionMODULE_DESCRIPTION — modinfo description alanı
license"GPL" veya "GPL v2" — proprietary modüller GPL sembollerine erişemez
paramsİsteğe bağlı; module_param() karşılığı, tip güvenli parametre tanımı

Modül Parametresi Tanımlama

use kernel::prelude::*;

module! {
    type: ParamDemo,
    name: "param_demo",
    author: "Emirhan Pehlevan",
    description: "Parametre ornekli modul",
    license: "GPL",
    params: {
        debug_level: u32 {
            default: 1,
            permissions: 0o644,
            description: "Hata ayiklama seviyesi (0-3)",
        },
        device_name: str {
            default: b"default_dev",
            permissions: 0o444,
            description: "Hedef aygit adi",
        },
    },
}

struct ParamDemo;

impl kernel::Module for ParamDemo {
    fn init(_name: &'static CStr,
            _module: &'static ThisModule) -> Result<Self>
    {
        pr_info!("debug_level = {}\n", *debug_level.read());
        pr_info!("device_name = {}\n",
                 core::str::from_utf8(*device_name.read())
                     .unwrap_or("?"));
        Ok(ParamDemo)
    }
}

impl Drop for ParamDemo {
    fn drop(&mut self) {
        pr_info!("ParamDemo modulu kaldiriliyor\n");
    }
}

Derleme ve Yükleme

# Ornek moduller dizinini derle
make LLVM=1 M=samples/rust modules

# QEMU veya gercek donanimda yukle
sudo insmod samples/rust/hello_kernel.ko

# dmesg ciktisi:
# [  42.123456] hello_kernel: Merhaba, Rust Kernel! Modul yuklendi.

sudo rmmod hello_kernel

# dmesg ciktisi:
# [  45.789012] hello_kernel: Gule gule, Rust Kernel! Modul kaldiriliyor.

# Modul bilgisi
modinfo hello_kernel.ko
# description: Ilk Rust kernel modulu ornegi
# author:      Emirhan Pehlevan
# license:     GPL
# vermagic:    6.6.0 SMP mod_unload

03 Rust Kernel Tipleri

Rust kernel kütüphanesi standart Box/Vec/Arc yerine kernel allocator kullanan, başarısız ayırmayı Result ile işleyen güvenli sarmalayıcılar sunar. C'deki karşılıkları kavramak önemlidir.

Bellek Ayırma — KBox

use kernel::prelude::*;
use kernel::alloc::KBox;

struct SensorData {
    temperature: i32,
    humidity:    u32,
    timestamp:   u64,
}

fn allocate_sensor_data() -> Result<KBox<SensorData>> {
    // KBox::new basarisiz olabilir -- kmalloc(sizeof, GFP_KERNEL)
    // ? operatoru ile hata yukariya yayilir
    let data = KBox::new(SensorData {
        temperature: 0,
        humidity:    0,
        timestamp:   0,
    }, GFP_KERNEL)?;

    Ok(data)
    // Kapsam bitince KBox::drop cagrilir -- kfree otomatik
}

// Dizi tipi icin
fn allocate_buffer() -> Result<KBox<[u8; 256]>> {
    let buf = KBox::new([0u8; 256], GFP_KERNEL)?;
    Ok(buf)
}

Dinamik Dizi — KVec

use kernel::alloc::kvec::KVec;

fn build_device_list() -> Result<KVec<u32>> {
    let mut devs: KVec<u32> = KVec::new();

    devs.push(0xDEAD_BEEF, GFP_KERNEL)?;
    devs.push(0xCAFE_BABE, GFP_KERNEL)?;

    pr_info!("Aygit sayisi: {}\n", devs.len());
    Ok(devs)
    // Kapsam bitince KVec::drop -- kfree otomatik
}

Referans Sayımı — Arc

use kernel::sync::Arc;
use core::sync::atomic::{AtomicU32, Ordering};

struct SharedState {
    counter: AtomicU32,
}

fn arc_example() -> Result {
    // Arc::new -- kmalloc + refcount baslatir
    let state = Arc::new(SharedState {
        counter: AtomicU32::new(0),
    }, GFP_KERNEL)?;

    // clone sadece refcount artirir -- derin kopyalama yok
    let state_clone = state.clone();

    state_clone.counter.fetch_add(1, Ordering::Relaxed);
    pr_info!("Sayac: {}\n",
        state.counter.load(Ordering::Relaxed));

    // Her iki Arc kapsam disina cikinca kfree cagrilir
    Ok(())
}

Senkronizasyon Primitifleri — Karşılaştırma

Rust TipiC KarşılığıKullanım Yeri
kernel::sync::Mutex<T>mutex_lock/unlockUyku tutulabilir bağlam; veriyi sarmalar
kernel::sync::SpinLock<T>spin_lock/unlockIRQ bağlamı; kısa kritik bölümler
kernel::sync::RwSemaphore<T>down_read/up_readÇok okuyucu, tek yazıcı erişim deseni
kernel::sync::CondVarwait_event/wake_upKoşul değişkeni ile olay bekleme
kernel::sync::Arc<T>kref_get/kref_putPaylaşımlı sahiplik ve referans sayımı

Mutex Kullanım Örneği

use kernel::sync::{Arc, Mutex};

struct DriverState {
    open_count: u32,
    last_read:  u64,
}

fn mutex_example() -> Result {
    let state = Arc::new(
        Mutex::new(
            DriverState { open_count: 0, last_read: 0 },
            c_str!("driver_lock")
        ),
        GFP_KERNEL
    )?;

    {
        // lock() guard doner -- guard kapsam disina cikinca kilit acilir
        let mut guard = state.lock();
        guard.open_count += 1;
        pr_info!("Acilis sayisi: {}\n", guard.open_count);
        // guard burada Drop -- mutex_unlock otomatik
    }

    // Arc<Mutex<T>> Send + Sync -- is parcaciklari arasinda guvenle paylasilir
    Ok(())
}

04 Karakter Cihaz Sürücüsü

miscdev::Registration, basit karakter cihazlarını kaydetmek için en kolay yoldur. file_operations karşılığı Rust trait metotları ile tanımlanır.

miscdev ile Basit Karakter Cihazı

// SPDX-License-Identifier: GPL-2.0
use kernel::prelude::*;
use kernel::miscdev;
use kernel::sync::{Arc, Mutex};
use kernel::file::{self, File, Operations};

module! {
    type: RustMiscDev,
    name: "rust_miscdev",
    author: "Emirhan Pehlevan",
    description: "Rust ile misc karakter cihazi",
    license: "GPL",
}

/* Paylasilan cihaz durumu */
struct DevState {
    buf:    KVec<u8>,
    size:   usize,
}

/* file_operations karsiligi trait */
struct MiscDevOps;

#[vtable]
impl Operations for MiscDevOps {
    type Data = Arc<Mutex<DevState>>;

    fn open(_shared: &Arc<Mutex<DevState>>,
            _file: &File) -> Result<Self::Data>
    {
        pr_info!("Cihaz acildi\n");
        Ok(/* shared.clone() */)
    }

    fn read(shared: ArcBorrow<'_, Mutex<DevState>>,
            _file: &File,
            writer: &mut impl kernel::io_buffer::IoBufferWriter,
            offset: u64) -> Result<usize>
    {
        let state = shared.lock();
        let start = offset as usize;
        if start >= state.size {
            return Ok(0); /* EOF */
        }
        let to_copy = core::cmp::min(
            writer.len(),
            state.size - start
        );
        writer.write_slice(&state.buf[start..start + to_copy])?;
        Ok(to_copy)
    }

    fn write(shared: ArcBorrow<'_, Mutex<DevState>>,
             _file: &File,
             reader: &mut impl kernel::io_buffer::IoBufferReader,
             _offset: u64) -> Result<usize>
    {
        let mut state = shared.lock();
        let len = reader.len();
        state.buf.clear();
        state.size = len;

        let tmp = KVec::<u8>::new();
        /* okuma ve buf'a kopyalama */
        pr_info!("{} bayt yazildi\n", len);
        Ok(len)
    }
}

struct RustMiscDev {
    _dev: Pin<KBox<miscdev::Registration<MiscDevOps>>>,
}

impl kernel::Module for RustMiscDev {
    fn init(_name: &'static CStr,
            module: &'static ThisModule) -> Result<Self>
    {
        pr_info!("rust_miscdev yukleniyor\n");

        let state = Arc::new(
            Mutex::new(
                DevState {
                    buf:  KVec::new(),
                    size: 0,
                },
                c_str!("miscdev_lock")
            ),
            GFP_KERNEL
        )?;

        let dev = miscdev::Registration::new_pinned(
            fmt!("rust_misc"),
            state,
            module
        )?;

        Ok(RustMiscDev { _dev: dev })
    }
}

impl Drop for RustMiscDev {
    fn drop(&mut self) {
        pr_info!("rust_miscdev kaldiriliyor\n");
    }
}

Kullanım Testi

# Modul yukle
sudo insmod rust_miscdev.ko

# Cihaz dosyasi olusturuldu: /dev/rust_misc
ls -la /dev/rust_misc

# Veri yaz
echo "merhaba kernel" > /dev/rust_misc

# Veri oku
cat /dev/rust_misc

# Modul kaldir
sudo rmmod rust_miscdev

05 C Kodunu Rust'tan Çağırma

bindings:: modülü bindgen tarafından otomatik üretilir. C kernel fonksiyonlarına unsafe blok içinde erişilir; Rust soyutlamaları bu unsafe katmanı güvenli bir arayüzle sarmalar.

bindgen ile Otomatik Bağlama Üretimi

# Kernel derleme sirasinda otomatik uretilir:
#   rust/bindings/bindings_generated.rs
#
# Hangi basliklar dahil ediliyor:
#   rust/bindings/bindings_helper.h
#
# Ornek icerik:
#   #include <linux/slab.h>
#   #include <linux/device.h>
#   #include <linux/platform_device.h>
#   #include <linux/interrupt.h>

# Yeni bir baslik eklemek icin bindings_helper.h dosyasina ekle:
#   #include <linux/my_subsystem.h>

C Fonksiyonlarını Çağırma — unsafe Bloklar

use kernel::bindings;
use kernel::prelude::*;

fn c_interop_example() -> Result {
    // msleep C fonksiyonu -- uyku bağlamında cagrilmali
    // SAFETY: ms degeri pozitif; uyku baglaminda cagrilıyor
    unsafe { bindings::msleep(100) };

    // jiffies global degisken okuma
    let jiffies = unsafe { bindings::jiffies };
    pr_info!("Jiffies: {}\n", jiffies);

    // ktime_get_real_ts64 ile gercek zaman alma
    let mut tval = bindings::timespec64 {
        tv_sec:  0,
        tv_nsec: 0,
    };
    // SAFETY: tval gecerli; isaretcisi null degil
    unsafe {
        bindings::ktime_get_real_ts64(
            &mut tval as *mut bindings::timespec64
        );
    }
    pr_info!("Unix zaman: {} saniye\n", tval.tv_sec);

    Ok(())
}

// MMIO okuma -- sarmalayıcı ornegi
fn mmio_read_u32(base: *mut u8, offset: usize) -> u32 {
    // SAFETY: base ioremap ile alindi; offset gecerli araliginda
    unsafe {
        bindings::readl(
            base.add(offset) as *const core::ffi::c_void
        )
    }
}

SAFETY Yorumu Zorunluluğu

// DOGRU: SAFETY yorumuyla aciklama
// SAFETY: ptr, init_device() ile baslatildi ve henuz serbest
//         birakilmadi. Mutex tutuldugundan estozamanli erisim yok.
unsafe { (*ptr).field = value; }

// YANLIS: Yorum yok -- Clippy hatasi:
// warning: unsafe block missing SAFETY comment
unsafe { (*ptr).field = value; }

// Kernel Clippy kural dosyasi:
# kernel.clippy.toml
# - undocumented_unsafe_blocks: hata seviyesi
# - missing_docs: uyari seviyesi

C'den Rust Fonksiyonu Çağırma

// Rust tarafinda C ABI ile disa acik fonksiyon
#[no_mangle]
pub extern "C" fn rust_process_sensor_data(
    buf: *const u8,
    len: usize,
    result: *mut u32,
) -> i32 {
    if buf.is_null() || result.is_null() {
        return -(bindings::EINVAL as i32);
    }
    // SAFETY: buf/len C tarafindan gecerli olarak saglandi
    let slice = unsafe {
        core::slice::from_raw_parts(buf, len)
    };
    let sum: u32 = slice.iter()
        .map(|&b| b as u32)
        .sum();
    // SAFETY: result null degil (yukarda kontrol edildi)
    unsafe { *result = sum };
    0
}
/* C tarafindan cagirma */
extern int rust_process_sensor_data(
    const u8 *buf, size_t len, u32 *result);

void my_c_handler(void) {
    u8 data[] = {10, 20, 30, 40, 50};
    u32 result = 0;
    int ret = rust_process_sensor_data(
                  data, ARRAY_SIZE(data), &result);
    if (ret == 0)
        pr_info("Toplam: %u\n", result);
}

06 Platform Sürücüsü

platform::Driver trait'i probe/remove metotlarını ve Device Tree uyumluluk tablosunu zorunlu kılar. DeviceData yapısı cihaza özel durumu saklar.

Platform Sürücüsü İskelet Yapısı

use kernel::prelude::*;
use kernel::platform;
use kernel::of;
use kernel::sync::Arc;

module! {
    type: MyPlatformMod,
    name: "my_platform_driver",
    author: "Emirhan Pehlevan",
    description: "Ornek Rust platform surucusu",
    license: "GPL",
}

/* Cihaz basina durum yapisi */
struct DeviceState {
    base_addr: *mut core::ffi::c_void,
    irq_num:   u32,
    open_cnt:  u32,
}

// SAFETY: DeviceState yalnizca probe/remove baglaminda erisiliyor
unsafe impl Send for DeviceState {}
unsafe impl Sync for DeviceState {}

/* Platform surucu */
struct MyPlatformDriver;

impl platform::Driver for MyPlatformDriver {
    type Data = Arc<DeviceState>;
    type IdInfo = ();

    // Device Tree uyumluluk tablosu
    const OF_DEVICE_ID_TABLE: Option<&'static of::IdTable<()>> =
        Some(&of::IdTable::new([
            of::DeviceId::new("myvendor,my-sensor\0"),
        ]));

    fn probe(pdev: &mut platform::Device,
             _id_info: Option<&()>) -> Result<Self::Data>
    {
        dev_info!(pdev.as_ref(), "probe cagrildi\n");

        /* MMIO kaynagini al ve map et */
        let res = pdev.resource(bindings::IORESOURCE_MEM, 0)
            .ok_or(ENODEV)?;

        // SAFETY: gecerli fiziksel adres ve boyut
        let base = unsafe {
            bindings::ioremap(res.start(), res.size())
        };
        if base.is_null() {
            dev_err!(pdev.as_ref(), "ioremap basarisiz\n");
            return Err(ENOMEM);
        }

        let irq = pdev.irq(0).ok_or(ENODEV)?;
        dev_info!(pdev.as_ref(),
                  "IRQ: {}, Base: {:p}\n", irq, base);

        Ok(Arc::new(DeviceState {
            base_addr: base,
            irq_num:   irq,
            open_cnt:  0,
        }, GFP_KERNEL)?)
    }

    fn remove(pdev: &mut platform::Device,
              data: &Self::Data)
    {
        dev_info!(pdev.as_ref(), "remove cagrildi\n");
        // SAFETY: base ioremap ile alindi; remove once cagrilir
        unsafe { bindings::iounmap(data.base_addr) };
    }
}

struct MyPlatformMod {
    _drv: platform::Registration<MyPlatformDriver>,
}

impl kernel::Module for MyPlatformMod {
    fn init(_name: &'static CStr,
            module: &'static ThisModule) -> Result<Self>
    {
        let drv = platform::Registration::new(module)?;
        Ok(MyPlatformMod { _drv: drv })
    }
}

impl Drop for MyPlatformMod {
    fn drop(&mut self) {
        pr_info!("my_platform_driver kaldiriliyor\n");
    }
}

Device Tree Düğümü

/* arch/arm64/boot/dts/vendor/board.dts */
/ {
    my_sensor: sensor@fe000000 {
        compatible = "myvendor,my-sensor";
        reg = <0x0 0xfe000000 0x0 0x1000>;
        interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&clkc CLKID_SENSOR>;
        clock-names = "pclk";
        status = "okay";
    };
};

dev_* Log Makroları

dev_info!(dev, fmt, ...)Bilgi mesajı — KERN_INFO seviyesi, cihaz adını öne ekler
dev_warn!(dev, fmt, ...)Uyarı mesajı — KERN_WARNING seviyesi
dev_err!(dev, fmt, ...)Hata mesajı — KERN_ERR seviyesi; sorunu kaydet ama devam et
dev_dbg!(dev, fmt, ...)Debug mesajı — CONFIG_DYNAMIC_DEBUG etkin değilse derlenmez
pr_info!(fmt, ...)Cihaz bağlamı yokken genel bilgi mesajı

07 Hata Yönetimi

Rust kernel kodu hataları Result<T, Error> ile yönetir. ? operatörü hata yayılımını otomatikleştirir; POSIX errno kodları kernel::error::Error tipi ile eşlenir.

Kernel Hata Kodları

Rust Sabitierrno DeğeriAnlamı
ENOMEM-12Yeterli bellek yok; kmalloc başarısız
EINVAL-22Geçersiz argüman; sürücüye yanlış parametre
ENODEV-19Cihaz bulunamadı; DT kaynağı eksik
EBUSY-16Kaynak meşgul; IRQ zaten kayıtlı
ENOENT-2Dosya veya dizin yok
EPERM-1İzin yok; yetkisiz işlem
EIO-5Giriş/çıkış hatası; donanım hatası

? Operatörü ile Hata Yayılımı

use kernel::prelude::*;

fn init_hardware(base: *mut u8) -> Result {
    if base.is_null() {
        return Err(EINVAL);
    }

    // Her adim basarisiz olabilir -- ? ile yukari yayilir
    let irq = request_irq(42)?;           // Hata: Err(EBUSY)
    let clk = clk_get_by_name("pclk")?;  // Hata: Err(ENODEV)
    let reg = ioremap(0xFE000000, 4096)?; // Hata: Err(ENOMEM)

    pr_info!("Donanim baslatildi\n");
    Ok(())
}

/* Kullanan taraf */
fn probe(pdev: &mut platform::Device) -> Result<()> {
    // init_hardware herhangi bir adimda basarisiz olursa
    // ? ile bu fonksiyondan da cikis yapilir
    init_hardware(base)?;

    pr_info!("Probe basarili\n");
    Ok(())
}

Option ile Null Güvenliği

use kernel::prelude::*;

fn find_resource(pdev: &platform::Device) -> Result<u64> {
    // resource() Option doner -- None ise ENODEV
    let res = pdev.resource(bindings::IORESOURCE_MEM, 0)
        .ok_or(ENODEV)?;

    // Option::map ile degeri donustur
    let size = pdev.resource(bindings::IORESOURCE_MEM, 0)
        .map(|r| r.size())
        .unwrap_or(0x1000); /* Varsayilan 4 KB */

    pr_info!("Kaynak boyutu: {} bayt\n", size);
    Ok(res.start())
}

fn safe_deref_example(ptr: Option<&u32>) {
    // match ile guvenli erisim
    match ptr {
        Some(val) => pr_info!("Deger: {}\n", val),
        None      => pr_warn!("Isaretci None!\n"),
    }

    // if let ile daha kisa
    if let Some(val) = ptr {
        pr_info!("Deger: {}\n", val);
    }
}

Hata Dönüşümü — from_errno

use kernel::error::Error;

fn convert_c_error(ret: i32) -> Result {
    if ret < 0 {
        // C tarafindan donen errno degerini Rust Error'a cevir
        return Err(Error::from_errno(ret));
    }
    Ok(())
}

fn call_c_function() -> Result {
    // SAFETY: gerekli kosullar saglandi
    let ret = unsafe { bindings::some_c_function(42) };
    convert_c_error(ret)?;
    pr_info!("C fonksiyonu basarili\n");
    Ok(())
}

08 Sınırlar ve Gelecek

Rust for Linux hızla büyümektedir ancak bazı alt sistemler henüz Rust abstraksyonuna sahip değildir. Mevcut durumu ve gömülü sürücüler için hangi API'lerin hazır olduğunu anlamak önemlidir.

Mevcut Rust Abstraksyon Durumu (2026)

Alt SistemDurumKonumNotlar
Platform deviceKararlırust/kernel/platform.rsGömülü için hazır
PCIKararlırust/kernel/pci.rsNova GPU kullanıyor
miscdevKararlırust/kernel/miscdev.rsBasit karakter cihazı
Block deviceGelişiyorrust/kernel/block/null_block örneği var
DRM/GPUGelişiyorrust/kernel/drm/Nova sürücüsü referans
I2CErken aşamarust/kernel/i2c.rsKısmi; PR'lar beklemede
SPIPlanlanıyorC sürücü veya unsafe gerekli
USBPlanlanıyorKarmaşık; henüz başlanmadı
Net (netdev)Erken aşamarust/kernel/net/Temel abstraksiyonlar var

Graduation Süreci

Rust abstraksyonları "unstable" (kararsız) ile başlar ve API'nin olgunlaşmasıyla "stable" (kararlı) hale gelir:

RFC veya RFC-benzeri tartisma (lkml / rust-for-linux)
         |
         v
Karstorsiz API ile ilk PR (RFC olmayan, deneysel)
         |
         v
Gercek surucu kullanimi (en az 1 in-tree surucu)
         |
         v
API incelemesi (Maintainer + Rust altyapi ekibi)
         |
         v
Stable -- backcompat garantisi
  

Gömülü için Hangi Sürücüler Hazır?

Platform + miscdev kombinasyonuTam destek; I2C/SPI'ye ihtiyaç duymayan donanım için ideal başlangıç noktası
PCI sürücüleriKararlı; x86 ve ARM64 PCIe tabanlı gömülü için hazır
Blok sürücülerinull_block örneği referans; kendi depolama sürücünüz için geliştirilebilir
I2C/SPI sensörlerHenüz hazır değil; mevcut seçenek: C sürücü veya unsafe bindings kullanımı
GPIOTemel GPIO abstraksiyonları var; karmaşık GPIO debounce/interrupt için kısmi

Pratik Öneri: C ile Hibrit Yaklaşım

# Mevcut en iyi pratik (2026 itibariyle):
# 1. Yeni donanim-bagimsiz mantigi Rust ile yaz
# 2. Donanim erisimi (I2C, SPI, vs.) icin C sürücüsüne sar
# 3. C surucuyu Rust'tan bindings:: ile cagir

# Ornek: I2C sensor surucu (hibrit yaklasim)
# - C tarafinda: i2c_driver kaydi, probe/remove
# - Rust tarafinda: veri islemesi, hata yonetimi, sysfs

# Clippy ile kalite kontrolu
make LLVM=1 CLIPPY=1 drivers/my_driver/

# samples/rust/ dizini -- referans uygulamalar
ls samples/rust/
# rust_minimal.rs         rust_print.rs
# rust_module_parameters.rs  rust_sync.rs
# rust_chrdev.rs          rust_miscdev.rs
# rust_platform.rs        rust_net_filter.rs