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
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 bozulma | Derleme hatası — Send/Sync trait'leri |
| Null pointer deref | Çalışma zamanı — kernel panic | Option<T> ile zorunlu None kontrolü |
| Integer overflow | İşaretli: UB; işaretsiz: wrap | Debug: panic; Release: wrap (açık) |
Rust for Linux Zaman Çizelgesi
Kernel Ortamında Rust Kısıtları
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/Dizin | Rolü |
|---|---|
| rust/kernel/lib.rs | Temel 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
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 Tipi | C Karşılığı | Kullanım Yeri |
|---|---|---|
| kernel::sync::Mutex<T> | mutex_lock/unlock | Uyku tutulabilir bağlam; veriyi sarmalar |
| kernel::sync::SpinLock<T> | spin_lock/unlock | IRQ 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::CondVar | wait_event/wake_up | Koşul değişkeni ile olay bekleme |
| kernel::sync::Arc<T> | kref_get/kref_put | Paylaşı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ı
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 Sabiti | errno Değeri | Anlamı |
|---|---|---|
| ENOMEM | -12 | Yeterli bellek yok; kmalloc başarısız |
| EINVAL | -22 | Geçersiz argüman; sürücüye yanlış parametre |
| ENODEV | -19 | Cihaz bulunamadı; DT kaynağı eksik |
| EBUSY | -16 | Kaynak meşgul; IRQ zaten kayıtlı |
| ENOENT | -2 | Dosya veya dizin yok |
| EPERM | -1 | İzin yok; yetkisiz işlem |
| EIO | -5 | Giriş/çı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 Sistem | Durum | Konum | Notlar |
|---|---|---|---|
| Platform device | Kararlı | rust/kernel/platform.rs | Gömülü için hazır |
| PCI | Kararlı | rust/kernel/pci.rs | Nova GPU kullanıyor |
| miscdev | Kararlı | rust/kernel/miscdev.rs | Basit karakter cihazı |
| Block device | Gelişiyor | rust/kernel/block/ | null_block örneği var |
| DRM/GPU | Gelişiyor | rust/kernel/drm/ | Nova sürücüsü referans |
| I2C | Erken aşama | rust/kernel/i2c.rs | Kısmi; PR'lar beklemede |
| SPI | Planlanıyor | — | C sürücü veya unsafe gerekli |
| USB | Planlanıyor | — | Karmaşık; henüz başlanmadı |
| Net (netdev) | Erken aşama | rust/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?
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