Bölüm 11: Giriş/Çıkış
Giriş
Öğrenme Çıktıları
Denetleyici, aygıt yazmaçları, PCIe/USB/NVMe veri yolları; kapı ve bellek eşlemeli G/Ç'yi açıklamak.
Yoklama, kesme güdümlü G/Ç ve DMA'yı karşılaştırmak; MSI-X ve IOMMU'nun rolünü söylemek.
Kesme işleyicisi, sürücü, aygıttan bağımsız katman ve kullanıcı kütüphanesini bir read() yolunda izlemek.
Engelleyen, engellemeyen ve eşzamansız G/Ç'yi; epoll ve io_uring'i ayırt etmek.
Erişim süresini hesaplamak; FCFS, SSTF, SCAN, C-SCAN, LOOK, C-LOOK toplam kafa hareketini bulmak.
FTL, aşınma dengeleme, TRIM ve blk-mq'yu; RAID 0/1/5/6/10 ve XOR eşliği ile kurtarmayı açıklamak.
Giriş
G/Ç Sistemine Genel Bakış
- İşletim sistemi aygıtlara komut verir, durumlarını okur, kesmeleri yakalar ve hataları ele alır.
- Uygulamalara aygıttan bağımsız, katmanlı ve tek tip bir arayüz sunar.
- Çekirdek kodunun büyük bölümü aygıt sürücüleridir (Linux kaynak kodunun yaklaşık %60–70'i
drivers/).
Giriş
Veri Yolları: PCIe, USB4, SATA
- Veri yolu: bileşenler arasında veri, adres ve denetim sinyallerini taşıyan bağlantı. Eski PC'lerde paylaşılan paralel yol (ISA, PCI); bugün noktadan noktaya seri hatlar (PCIe, USB, SATA).
- PCIe bir hat (lane) tam çift yönlüdür; bağlantı x1, x4, x8, x16 hat birleştirir. Bant genişliği her yönde ayrı ayrıdır.
| Bağlantı | Ham hız | Etkin veri hızı | Not |
|---|---|---|---|
| PCIe 4.0 | 16 GT/s / hat | ≈ 1,97 GB/s / hat; x4 ≈ 7,9 GB/s | 128b/130b kodlama; NVMe SSD'ler |
| PCIe 5.0 | 32 GT/s / hat | ≈ 3,94 GB/s / hat; x16 ≈ 63 GB/s | GPU, 14 GB/s sınıfı SSD |
| PCIe 6.0 | 64 GT/s (PAM4) | ≈ 7,6 GB/s / hat; x16 ≈ 121 GB/s | FLIT + FEC; sunucularda yaygınlaşıyor |
| USB 2.0 / 3.2 | 480 Mb/s / 5–20 Gb/s | ≤ 60 MB/s / ≤ 2,5 GB/s | Ana makine yoklamalı protokol |
| USB4 v1 / v2 | 40 / 80 Gb/s | PCIe, DisplayPort tünelleme | Thunderbolt 4/5 ile uyumlu |
| SATA III | 6 Gb/s | ≈ 600 MB/s (8b/10b) | AHCI: tek kuyruk, 32 komut |
| Ethernet | 1 / 10 / 100 / 400 Gb/s | 125 MB/s … 50 GB/s | Veri merkezi: 400–800 GbE |
Hesap: PCIe 4.0 hattı 16 GT/s × 128/130 ÷ 8 = 1,97 GB/s. Eski sunumdaki FireWire, 56K modem ve 10/100 Mb/s Ethernet artık tarihseldir.
Giriş
Aygıt Veri Hızları
Klavye ile PCIe 5.0 x16 arasında ≈ 6 × 109 kat fark var: aynı işletim sistemi hem saniyede birkaç tuşu hem saniyede milyonlarca NVMe isteğini yönetmelidir. Değerler tipik üst sınırlardır; gerçek hız sinyal kalitesi, protokol yükü ve aygıta bağlıdır. Eski tablodaki “SSD 1,5 GB/s” ve “HDD 200/150 MB/s” güncellendi.
Giriş
Aygıt Sınıfları: Blok, Karakter, Ağ
| Sınıf | Örnek | Özellik | Tipik arayüz |
|---|---|---|---|
| Blok | HDD, SSD, USB bellek, SD kart | Sabit boyutlu, adreslenebilir bloklar (512 B / 4 KiB); her blok bağımsız okunur/yazılır | read, write, lseek; dosya sistemi, mmap |
| Karakter | Klavye, fare, seri port, yazıcı, ses | Bayt akışı; adreslenemez, konum (seek) yok | read/write, ioctl; /dev/ttyS0 |
| Ağ | Ethernet, Wi-Fi | Paket tabanlı; ne blok ne karakter | Soket API'si (send, recv); /dev'de dosyası yok |
| Diğer | Saatler, zamanlayıcılar, GPU | Ne akış ne blok: kesme üretir ya da bellek eşlemelidir | timerfd, DRM/KMS, mmap |
$ ls -l /dev/nvme0n1 /dev/ttyS0 brw-rw---- 1 root disk 259, 0 nvme0n1 b = blok, ana/yan numara 259,0 crw-rw---- 1 root dialout 4, 64 ttyS0 c = karakter
Eski sunum ağ arabirimlerini karakter aygıtı sayıyordu; Unix/Linux'ta ağ ayrı bir sınıftır. Blok boyutu bugün çoğunlukla 512 B (öykünmeli) ya da 4 KiB'dir; sınıflandırma kesin değildir (teyp ve saatler sınıfa tam uymaz).
G/Ç Donanımı
Aygıt Denetleyicileri
- G/Ç birimi = mekanik/aygıt kısmı + elektronik denetleyici (yonga ya da kart; bağlayıcı ile aygıta bağlanır).
- Öncül (preamble) eşzamanlama deseni ile silindir/sektör numarasını taşır. Denetleyici bit akışını bloğa çevirir, ECC ile hatayı düzeltir, bloğu kendi tamponuna koyar; sonra belleğe aktarır.
- İşletim sistemi aygıtla değil denetleyiciyle konuşur; SATA/NVMe gibi standart arayüzler sayesinde tek sürücü birçok üreticinin aygıtını sürer.
- Modern diskler 4 KiB fiziksel sektör kullanır (Advanced Format); dışarıya 512 B gösterenlere 512e denir.
G/Ç Donanımı
Aygıt Yazmaçları: Durum, Komut, Veri
- Denetleyicinin genellikle dört yazmacı vardır: durum (meşgul, hazır, hata), komut (ne yapılacağı), veri girişi ve veri çıkışı.
- Yazmaçlara yazmak = komut vermek; okumak = durum öğrenmek. Ayrıca büyük veri tamponları (ör. çerçeve tamponu, NIC halkaları) olabilir.
- Yazmaç düzeni aygıta özgüdür; bu ayrıntıyı yalnız sürücü bilir. Bit adları burada örnek amaçlıdır.
G/Ç Donanımı
Kapı Eşlemeli ve Bellek Eşlemeli G/Ç
| Kapı (x86) | Aygıt |
|---|---|
| 0x20–0x21 | 8259 kesme denetleyicisi |
| 0x40–0x43 | 8254 zamanlayıcı (PIT) |
| 0x60, 0x64 | 8042 klavye denetleyicisi |
| 0x3F8–0x3FF | COM1 seri port |
| 0xCF8–0xCFF | PCI yapılandırma |
in al, 0x60 ; kapı: özel komut mov eax, [rbx+0x14] ; MMIO: sıradan yükleme Linux: inb()/outb() · ioremap() + readl()/writel() /proc/ioports · /proc/iomem
Kapı eşlemeli G/Ç'de CPU özel IN/OUT komutları ve ayrı bir adres uzayı kullanır; bellek eşlemelide aygıt yazmacı sıradan bir bellek adresidir ve adres çözücü erişimi ilgili aygıta yönlendirir. ARM ve RISC-V yalnız MMIO kullanır; PCIe aygıtları da yazmaçlarını BAR'lar ile MMIO olarak sunar.
G/Ç Donanımı
Bellek Eşlemeli G/Ç: Artılar ve Eksiler
Bellek eşlemeli G/Ç: artılar
- Özel komut gerekmez; sürücü tamamen C ile yazılabilir (
volatileişaretçi). - Koruma sayfa tablosuyla gelir: yazmaç sayfası kullanıcı uzayına eşlenmezse erişilemez; istenirse tek bir sürece verilebilir (VFIO, DPDK).
- Her bellek komutu yazmaçla çalışır:
TEST,ANDgibi komutlar doğrudan yazmaç üzerinde.
Eksiler
- Önbellek: durum yazmacı önbelleğe alınırsa güncel değer görülmez → sayfa önbelleklenemez işaretlenir (PAT/MTRR,
ioremap). - Birden çok yol: bellek ayrı hızlı yolda ise G/Ç aygıtı adresi göremez → yönlendirme köprü/kök kompleks tarafından adres aralıklarıyla yapılır.
- Derleyici erişimleri yeniden sıralayabilir:
volatileve bellek bariyerleri gerekir.
Programlanmış G/Ç · Kodu adım adım çalıştır
Yoklama: El Sıkışma Adım Adım
while (status & BUSY)
; /* meşgul bekleme */
command = WRITE;
data_out = 'A';
command |= CMDRDY;
/* --- denetleyici tarafı --- */
/* CMDRDY görüldü → BUSY = 1 */
/* komutu oku, baytı aygıta yaz */
/* CMDRDY = ERR = BUSY = 0 */Sürücü durum yazmacını tekrar tekrar okur: denetleyici önceki işi bitirmediği için BUSY = 1. CPU bu sırada başka iş yapamaz.
BUSY 0 oldu: döngüden çıkılır. Bu bekleme süresi aygıta bağlıdır; birkaç döngüden milisaniyelere kadar sürebilir.
Komut yazmacına WRITE biti yazılır: yapılacak iş yazma.
Gönderilecek bayt ('A' = 0x41) veri çıkış yazmacına konur.
CMDRDY = 1: “komut hazır”. Bu bit denetleyiciye işin başlayabileceğini söyler.
Denetleyici CMDRDY'yi görür ve BUSY = 1 yapar: artık meşgul olduğunu ana makineye bildirir.
Denetleyici komut yazmacını okur (WRITE), veri çıkış yazmacındaki baytı alır ve aygıta gönderir.
İş bitti: CMDRDY, ERR ve BUSY temizlenir (ERR = 0 → başarılı). Sonraki bayt için döngü baştan başlar.
Programlanmış G/Ç (PIO): her bayt için CPU bu el sıkışmayı kendisi yürütür. Basittir, ama bekleme boyunca CPU boşa döner; CPU başka sürece geçip bir baytı kaçırırsa (ör. tampon taşması) veri kaybolabilir.
Programlanmış G/Ç · Kodu adım adım çalıştır
Programlanmış G/Ç: Yazıcı Örneği
copy_from_user(buffer, p, count); for (i = 0; i < count; i++) { while (*printer_status_reg != READY) ; /* meşgul bekleme */ *printer_data_register = p[i]; } return_to_user();
Kullanıcının “ABCD” dizisi çekirdek tamponuna kopyalanır (copy_from_user); kullanıcı belleği doğrudan kullanılmaz.
i = 0: durum READY olana kadar döngü döner.
'A' veri yazmacına yazılır; yazıcı karakteri basar ve yeniden meşgul olur.
i = 1: yazıcı meşgul, CPU durum yazmacını yoklar.
'B' veri yazmacına yazılır; yazıcı karakteri basar ve yeniden meşgul olur.
i = 2: yazıcı meşgul, CPU durum yazmacını yoklar.
'C' veri yazmacına yazılır; yazıcı karakteri basar ve yeniden meşgul olur.
i = 3: yazıcı meşgul, CPU durum yazmacını yoklar.
'D' veri yazmacına yazılır; yazıcı karakteri basar ve yeniden meşgul olur.
Döngü bitti; sürece dönülür. CPU tüm süre boyunca bu sürece bağlı kaldı: 4 karakterlik iş, yazıcının hızıyla sınırlı.
Tanenbaum'un yazıcı örneği. Yazıcı saniyede 100 karakter basıyorsa her karakter için CPU ≈ 10 ms bekler; bu sürede milyonlarca komut çalıştırabilirdi. Gömülü sistemlerde CPU'nun başka işi yoksa PIO yine de mantıklıdır.
Kesmeler · Adım adım
Kesme Donanımı: Hattan MSI'ya
Aygıtların her biri kesme denetleyicisine bağlıdır; denetleyici CPU'nun tek kesme girişini paylaştırır ve öncelik belirler.
① Disk denetleyicisi işini bitirince kendi kesme hattına (IRQ) sinyal verir.
② Denetleyici başka kesme işlenmiyorsa ya da bu daha öncelikliyse CPU'ya kesme iletir; değilse istek bekletilir (CPU onaylayana kadar hat etkin kalır).
③ CPU kesmeyi kabul eder; denetleyici vektör numarasını yola koyar. CPU bu sayıyı kesme vektör tablosunda indis olarak kullanır.
Modern PCIe: MSI/MSI-X. Kablo yok; aygıt özel bir adrese (x86'da 0xFEE0_0000 bölgesi) vektörü içeren bir bellek yazması gönderir, yerel APIC bunu kesmeye çevirir.
Eski PC: iki 8259 PIC, 15 IRQ hattı. Bugün x86'da I/O APIC + çekirdek başına yerel APIC (x2APIC), ARM'da GIC. Eski sunumdaki “adres satırına sayı koyar” anlatımı yalnızca bu tarihsel PIC düzeni için geçerlidir.
Kesmeler
Vektörler, Öncelik, NMI ve İstisnalar
| Vektör | Olay | Tür |
|---|---|---|
| 0 | Bölme hatası | hata (fault) |
| 1 / 3 | Hata ayıklama / kesme noktası | tuzak (trap) |
| 2 | NMI (maskelenemez kesme) | kesme |
| 6 | Geçersiz işlem kodu | hata |
| 13 | Genel koruma hatası | hata |
| 14 | Sayfa hatası | hata |
| 18 | Makine denetimi | iptal (abort) |
| 32–255 | Aygıt kesmeleri, IPI, APIC zamanlayıcı | maskelenebilir |
- Kesme vektör tablosu (x86: IDT, 256 giriş): vektör → işleyici adresi. 0–31 işlemci istisnalarına ayrılmıştır.
- Maskelenebilir kesmeler kritik bölgede ertelenebilir (
cli/sti); NMI ertelenemez: donanım hatası, bellek ECC, izleme köpeği. - Öncelik: APIC vektör sınıfına göre sıralar; yüksek öncelikli kesme düşük öncelikli işleyiciyi kesebilir.
- Kesme zinciri: aygıt sayısı vektörden fazlaysa her girdi bir işleyici listesine işaret eder (paylaşılan IRQ).
- Hata (sayfa hatası): komut tamamlanamaz, işleyiciden sonra aynı komut yeniden çalışır. Tuzak (sistem çağrısı,
int3): sonraki komuttan devam edilir. - MSI-X: işlev başına 2048 vektöre kadar; NVMe ve NIC her kuyruk için ayrı vektör alır ve kesmeyi kuyruğun çekirdeğine yönlendirir (
/proc/interrupts,irqbalance).
Kesmeler · Adım adım
Kesme İşleme Adım Adım
Süreç A çalışıyor; B bir disk okumasının bitmesini bekliyor. Disk kesme isteği gelir. CPU o anki komutu bitirir, sonra kesmeyi kabul eder.
Donanım PC (RIP), PSW (RFLAGS) ve yığın işaretçisini çekirdek yığınına iter, çekirdek kipine geçer, kesmeleri maskeler.
Vektör numarası IDT'de indis olur → işleyici adresi. Giriş kodu (assembly) donanımın kaydetmediği yazmaçları kaydeder; ISR için bağlam ve yığın hazırdır.
ISR aygıtın durumunu okur, veriyi alır ve denetleyiciye onay (EOI) gönderir; yeni kesmeler artık gelebilir. Uzun iş alt yarıya ertelenir.
Bekleyen süreç B bloke durumundan hazır kuyruğuna alınır.
Çizelgeleyici sıradakini seçer (burada B). B'nin sayfa tablosu MMU'ya yüklenir (x86: CR3), yazmaçları süreç tablosu/yığından geri alınır.
iret: kaydedilen PC ve PSW geri yüklenir, kullanıcı kipine dönülür, kesmeler açılır. B kaldığı komuttan devam eder.
Bu sıra Tanenbaum'un kesme işleyicisi adımlarını izler. Çizelgeleyici A'yı da seçebilir; seçim politikaya bağlıdır. Ayrıntılı benzetim: Kesme, DMA ve G/Ç Akışı Görselleştiricisi.
Kesmeler · Adım adım
Kesin ve Kesin Olmayan Kesmeler
Kesin kesme: PC bilinen yere kaydedilir; PC'den önceki her komut tamamen bitmiş, sonrakilerin hiçbiri başlamamıştır; PC'deki komutun durumu bilinir.
Kesin olmayan kesme: boru hattı / sıra dışı yürütmede komutlar yarım kalmıştır. Yeniden başlatmak için ya donanım geri alır ya da işletim sistemi çok miktarda iç durumu kaydedip çözümlemelidir.
- Boru hattında aynı anda birçok komut farklı aşamalardadır; üstün ölçekli işlemcide komutlar sıra dışı tamamlanır. “PC” tek başına durumu anlatmaz.
- Modern x86, ARM ve RISC-V işlemciler kesin kesme sağlar: yeniden sıralama arabelleği (ROB) komutları program sırasıyla emekliye ayırır; kesmede sonraki komutların etkileri atılır. Bedeli yonga alanı ve karmaşıklıktır.
Kesmeler · Kodu adım adım çalıştır
Kesme Güdümlü G/Ç: Yazıcı Örneği
/* sistem çağrısı */ copy_from_user(buffer, p, count); enable_interrupts(); while (*printer_status_reg != READY) ; *printer_data_register = p[0]; i = 1; count = count - 1; scheduler(); /* süreç bloke */ /* kesme hizmet yordamı */ if (count == 0) { unblock_user(); } else { *printer_data_register = p[i]; count = count - 1; i = i + 1; } acknowledge_interrupt(); return_from_interrupt();
“ABC” çekirdek tamponuna kopyalanır, yazıcı kesmeleri açılır.
Yazıcı hazır olunca yalnız ilk karakter yazılır.
Sayaçlar güncellenir ve çizelgeleyici çağrılır: süreç bloke, CPU başka bir süreci çalıştırır.
1. kesme: 'A' basıldı. count ≠ 0 → p[1] = 'B' yazılır.
Kesme onaylanır ve kesilen sürece dönülür. CPU yazıcı beklerken boşa dönmedi.
2. kesme: 'B' basıldı → p[2] = 'C' yazılır.
3. kesme: count == 0 → tüm karakterler basıldı, kullanıcı süreci hazır kuyruğuna alınır.
Her karakter için bir kesme: 3 karakter → 3 kesme. Eski sunumdaki kodda i ve count ilk karakterden sonra güncellenmiyordu; 6. satır eklendi. Bedel: kesme başına bağlam kaydı ve işleyici süresi (≈ 1–2 µs).
Kesmeler
Üst Yarı, Alt Yarı ve Hibrit Yoklama
Gerçek ISR: kısa tutulur, kesmeler kısmen kapalıdır. Aygıtı onaylar, veriyi tampona alır, alt yarıyı planlar.
Ertelenmiş iş: Linux'ta softirq, tasklet, workqueue ya da iş parçacıklı IRQ (request_threaded_irq); Windows'ta ISR + DPC.
NIC ve NVMe birkaç tamamlanmayı tek kesmede bildirir (coalescing): daha az kesme, biraz daha fazla gecikme.
Yoğun ağ trafiğinde sürücü kesmeyi kapatıp kuyruğu yoklar, trafik azalınca kesmeye döner. Hibrit en iyisidir.
Olay hızı çok yüksek ve gecikme kritikse: DPDK/SPDK, NVMe yoklamalı kuyruklar, io_uring IOPOLL. Bir çekirdek tamamen yoklamaya ayrılır.
Hatalı aygıt sürekli kesme üretirse sistem kilitlenir; çekirdek “nobody cared” ile hattı kapatır, kesme hızını sınırlar.
DMA
Doğrudan Bellek Erişimi (DMA)
- Bayt bayt aktarımda CPU zamanı boşa gider; DMA denetleyicisi blok aktarımını CPU olmadan yapar. CPU yalnız kurulum ve bitiş kesmesiyle uğraşır.
- Yazmaçlar: bellek adresi, bayt sayısı, denetim (G/Ç kapısı, yön: okuma/yazma, birim: bayt/sözcük, patlama boyutu). Çok kanallı denetleyici aynı anda birçok aktarımı yönetir.
- Eski sunum DMA denetleyicisinin anakartta olduğunu söylüyordu: bu yalnız tarihsel 8237 için doğrudur. Bugün aygıtların çoğu kendi DMA motoruna sahiptir ve belleğe doğrudan PCIe yazması yapar.
DMA · Adım adım
DMA Aktarımı Adım Adım
① CPU DMA denetleyicisini (adres = 0x7A000, sayaç = 4096, yön) ve disk denetleyicisini (sektörü oku) programlar, sonra başka işe döner.
Disk denetleyicisi sektörü kendi tamponuna okur ve ECC ile doğrular. Tampon sayesinde yol meşgulken veri kaybolmaz.
② DMA denetleyicisi yolu ister, bellek adresini yola koyar ve disk denetleyicisine okuma isteği gönderir.
③ Disk denetleyicisi sözcüğü doğrudan belleğe yazar; CPU veri yolunda yer almaz.
④ Disk denetleyicisi onay gönderir; DMA adresi artırır, sayacı azaltır. Sayaç 0 olana kadar ②–④ tekrarlanır.
⑤ Sayaç 0: DMA denetleyicisi CPU'yu kesmeyle uyarır. İşletim sistemi açtığında veri zaten bellektedir.
Döngü çalma (cycle stealing): DMA her sözcük için yolu kısa süre alır, CPU belleğe erişirken biraz yavaşlar. Patlama (burst) kipinde yol bir blok boyunca tutulur. Geçişsiz (fly-by) kipte veri aygıttan belleğe doğrudan gider; aksi halde DMA önce okuyup sonra yazar.
DMA
Dağıt-Topla ve IOMMU
Aygıta (adres, uzunluk) çiftleri listesi verilir; aygıt bitişik olmayan sayfalara tek işlemde yazar (readv, ağ paketleri, NVMe PRP/SGL).
Aygıtın gördüğü adresi (IOVA) sayfa tablosuyla fiziksele çevirir: koruma (Thunderbolt DMA saldırıları), sanal makineye aygıt atama (VFIO), 32 bit aygıtlara yüksek bellek.
DMA · Kodu adım adım çalıştır
DMA ile G/Ç: Yazıcı Örneği
/* sistem çağrısı */ copy_from_user(buffer, p, count); set_up_DMA_controller(); scheduler(); /* süreç bloke */ /* kesme hizmet yordamı */ acknowledge_interrupt(); unblock_user(); return_from_interrupt();
Veri çekirdek tamponuna kopyalanır.
DMA denetleyicisi programlanır: tampon adresi, sayaç = 3, hedef yazıcı kapısı.
Süreç bloke edilir; CPU başka iş yapar. DMA karakterleri CPU'suz yazıcıya iletir.
Tüm karakterler aktarıldı; bu arada CPU'ya hiç kesme gelmedi.
DMA tek bir kesme üretir: işleyici onaylar.
Kullanıcı süreci uyandırılır ve kesmeden dönülür. Karakter başına değil, tampon başına bir kesme.
DMA, CPU'yu G/Ç'den kurtarır, ama DMA denetleyicisi genellikle CPU'dan yavaştır. Aygıt çok yavaşsa ya da CPU'nun yapacak başka işi yoksa kesme güdümlü G/Ç ya da PIO daha basit ve yeterli olabilir (Tanenbaum).
DMA · Adım adım hesap
Üç Yöntemin Maliyeti
Yoklama: CPU her karakteri bekler: 4096 × 1 ms = 4,096 s boyunca meşgul.
Programlanmış G/Ç'de CPU, aygıt hızına bağlıdır.
Kesme güdümlü: 4096 kesme × 2 µs = 8,19 ms (işin süresinin %0,2'si).
Bekleme ortadan kalkar; bedel kesme sayısıdır.
DMA: 5 µs kurulum + 1 kesme × 2 µs = ≈ 7 µs; yaklaşık 1170 kat daha az.
Ama DMA yol döngüsü çalar ve kurulumu küçük aktarımlarda kendini geri ödemez.
Hız farkı 4 basamaktan fazla. Kısa aktarım, yavaş DMA ya da boşta bekleyen CPU varsa DMA'nın kazancı kaybolur.
G/Ç Yazılımı
G/Ç Yazılımının Hedefleri
Program aygıtı bilmeden çalışmalı: sort < girdi dosya, SSD ya da USB bellekte aynı çalışır.
Ad aygıt tipine bağlı olmamalı: /dev/nvme0n1, /mnt/usb/rapor.txt; bağlama (mount) ile tek ağaç.
Hata donanıma olabildiğince yakın çözülmeli: denetleyici ECC ile düzeltir, sürücü yeniden dener; üst katman ancak gerekirse bilir.
Donanımda aktarım çoğunlukla eşzamansızdır (kesme güdümlü); kullanıcıya ise engelleyen arayüz sunmak programlamayı kolaylaştırır.
Gelen paket nereye gideceği belli olmadan bir yere konmalı; ses gibi gerçek zamanlı aygıtlar da tampona dayanır.
Disk birçok kullanıcıya aynı anda hizmet verir; yazıcı ya da tarayıcı tek kullanıcıya adanır (kilitlenme riskine dikkat).
G/Ç Yazılımı
G/Ç Yazılım Katmanları
Her katmanın iyi tanımlı bir görevi ve üst katmana arayüzü vardır. Tanenbaum dört katman sayar: kullanıcı düzeyi G/Ç yazılımı, aygıttan bağımsız yazılım, aygıt sürücüleri, kesme işleyicileri. Linux'ta “aygıttan bağımsız” kısım VFS, sayfa önbelleği, dosya sistemi ve blok katmanına ayrılır.
G/Ç Yazılımı · Adım adım
Bir read() Çağrısının Yolu
Süreç read(fd, buf, 4096) çağırır; libc sarmalayıcısı syscall komutuyla çekirdeğe geçer.
VFS tanımlayıcıyı açık dosyaya, dosyayı inode'a çevirir; erişim izni açılışta zaten denetlenmiştir.
Sayfa önbelleğine bakılır: istenen sayfa yok. Önbellek sayfası ayrılır, okuma başlatılır.
Dosya sistemi dosya ofsetini disk bloğuna (LBA) çevirir; blok katmanı bir bio/istek oluşturup donanım kuyruğuna verir.
NVMe sürücüsü okuma komutunu gönderim kuyruğuna yazar, kapı zili (doorbell) yazmacına yazar. Süreç bloke olur (D durumu).
SSD veriyi DMA ile önbellek sayfasına yazar, tamamlanma kuyruğuna kayıt ekler ve MSI-X kesmesi üretir.
Kesme işleyicisi tamamlanmayı işler: sayfa “güncel” işaretlenir, bekleyen süreç hazır olur.
Süreç çalışınca VFS veriyi önbellekten kullanıcı tamponuna kopyalar ve 4096 döndürür.
Aynı veri yeniden okunursa sayfa önbelleğinde isabet: aygıta hiç gidilmez, işlem mikrosaniyeler sürer.
G/Ç Yazılımı
Aygıt Sürücüleri
- Sürücü aygıta özgü kodu kapsüller: yazmaçları, komutları ve tuhaflıklarını yalnız o bilir. Linux'ta çoğu sürücü çekirdek ağacındadır (in-tree); bazıları üreticiden gelir.
- Görevleri: parametreleri doğrula, isteği aygıt komutuna çevir (LBA, kuyruk girdisi), gerekirse aygıtı başlat, yazmaçlara yaz, kesmeyi bekle (bloke), hatayı denetle, sonucu döndür.
- Yeniden girilebilir (reentrant) olmalı: işlerken yeni istek ya da kesme gelebilir. Sıcak tak (hot-plug) ile aygıt çalışırken kaybolabilir.
- Çekirdekteki hatalı sürücü tüm sistemi çökertir → kullanıcı alanı sürücüleri: MINIX 3, FUSE, VFIO/UIO, DPDK/SPDK; Windows UMDF. Yüklenebilir modüller:
modprobe,lsmod.
G/Ç Yazılımı
Aygıttan Bağımsız G/Ç Yazılımı
- Tüm sürücüler için tek tip arayüz: her sınıf aynı işlevleri sunar; çekirdek bir işlev işaretçisi tablosu üzerinden çağırır.
- Adlandırma:
/dev/nvme0n1→ ana numara (sürücü) + yan numara (birim). Koruma: aygıt dosyasının izinleri. - Aygıttan bağımsız blok boyutu, tamponlama, hata raporlama, adanmış aygıtların ayrılması ve bırakılması bu katmandadır.
struct file_operations nvme_fops = {
.open = nvme_open,
.release = nvme_release,
.read_iter = nvme_read,
.unlocked_ioctl = nvme_ioctl,
.poll = nvme_poll,
};G/Ç Yazılımı · Adım adım
Ara Belleğe Alma (Tamponlama)
Tamponsuz: her karakter için kesme gelir ve süreç uyandırılır. Çok sayıda bağlam değişimi, verimsiz.
Kullanıcı tamponu: kesme işleyicisi karakterleri doğrudan süreç tamponuna yazar. Tampon sayfası diske atılırsa? Sayfa kilitlenmeli; çok süreç kilitlerse bellek azalır.
Çekirdek tamponu: karakterler önce çekirdekte birikir, dolunca tek seferde kullanıcıya kopyalanır. Ama kopyalanırken gelen veri nereye konacak?
Çift tampon: biri dolarken diğeri kopyalanır; roller sırayla değişir. Daha genel biçimi dairesel tampondur.
Ağda bir paket gönderilirken 5 kez kopyalanabilir; her kopya bellek bant genişliği ve gecikme demektir. Bu yüzden sıfır kopya teknikleri geliştirilmiştir.
Tamponlamanın üç nedeni (Silberschatz): üretici ile tüketici arasındaki hız farkı, aktarım boyutu farkı (paketlerin birleştirilmesi) ve kopya anlamı (write döndükten sonra kullanıcı tamponunu değiştirebilmek).
G/Ç Yazılımı · Adım adım
Dairesel Tampon
Baş ve kuyruk aynı yuvayı gösteriyor: tampon boş.
Kesme işleyicisi gelen 3 baytı kuyruğa yazar; kuyruk ilerler. Tüketici henüz okumadı.
Süreç 2 bayt okur; baş ilerler. Okunan yuvalar yeniden kullanılabilir.
Üretici 5 bayt daha yazar; kuyruk sona gelince başa sarar (mod 8): kuyruk = 0.
'i' yazılınca kuyruk = 1 ve (kuyruk + 1) mod 8 == baş: tampon dolu. Bir yuva boş bırakılarak boş/dolu ayırt edilir. Dolu tamponda üretici bekler ya da veriyi düşürür (ağ paketi kaybı).
Dairesel tamponlar her yerdedir: klavye ve seri port sürücüleri, NIC alma/gönderme halkaları, NVMe gönderim/tamamlanma kuyrukları, io_uring. Tek üretici–tek tüketicide kilit gerekmez; yalnız bellek bariyerleri gerekir.
G/Ç Yazılımı
Önbellek, Biriktirme ve Hata Ele Alma
Tampon verinin tek kopyasını geçici tutar; önbellek başka yerde duran verinin hızlı kopyasıdır. Linux sayfa önbelleği ikisini birleştirir; boş RAM önbelleğe gider (free -h: buff/cache).
Adanmış aygıt için kuyruk: kullanıcı dosyayı biriktirme dizinine koyar, tek bir arka plan süreci (CUPS, /var/spool/cups) sırayla yazdırır. Hiçbir süreç yazıcıyı kilitlemez.
Programlama hatası (geçersiz fd) → hata kodu (EBADF, EINVAL). Gerçek G/Ç hatası → sürücü yeniden dener; kalıcıysa EIO ve günlük kaydı (dmesg).
Adanmış aygıt open ile ayrılır, meşgulse istek kuyruğa alınır ya da EBUSY döner. G/Ç komutları ayrıcalıklıdır; kullanıcı yalnız sistem çağrısıyla G/Ç yapar.
Kullanıcı alanındaki G/Ç yazılımı: printf/scanf gibi kütüphane yordamları biçimlendirme ve kullanıcı tamponlaması yapar (stdio satır/blok tamponu), sonra write/read sistem çağrılarını kullanır.
G/Ç Arayüzleri
Engelleyen, Engellemeyen ve Eşzamansız G/Ç
| Arayüz | Model | Not |
|---|---|---|
select / poll | hazır olma bildirimi | her çağrıda tüm fd listesi taranır: O(n) |
epoll (Linux), kqueue (BSD) | hazır olma bildirimi | ilgi listesi çekirdekte; yalnız hazır olanlar döner |
io_uring, Windows IOCP | tamamlanma bildirimi | gerçek eşzamansız G/Ç; disk dahil |
G/Ç Arayüzleri · Kodu adım adım çalıştır
Olay Döngüsü: epoll
int ep = epoll_create1(0); for (k = 0; k < nsock; k++) /* O_NONBLOCK */ epoll_ctl(ep, EPOLL_CTL_ADD, s[k], &ev); for (;;) { int n = epoll_wait(ep, evs, 64, -1); for (int i = 0; i < n; i++) { int fd = evs[i].data.fd; ssize_t r = read(fd, buf, sizeof buf); if (r < 0 && errno == EAGAIN) continue; handle(fd, buf, r); } }
Bir epoll örneği oluşturulur: çekirdekte ilgi ve hazır listeleri tutan bir nesne.
Üç soket (5, 6, 7) engellemeyen kipte ilgi listesine eklenir. Bu bir kez yapılır; select'teki gibi her turda tekrar verilmez.
epoll_wait hiçbir soket hazır değilken süreci bloke eder; CPU boşa dönmez.
Soket 7'ye paket geldi: NIC kesmesi → ağ yığını → fd 7 hazır listesine eklenir, süreç uyanır. n = 1.
Yalnız hazır olan fd işlenir: 512 bayt okunur. Maliyet hazır fd sayısıyla orantılıdır, toplamla değil.
Veri işlendi; bir sonraki read EAGAIN dönerse beklenecek veri kalmamıştır. Döngü yeniden epoll_wait'e gider.
Tek iş parçacığı on binlerce bağlantıyı yönetir (nginx, Node.js, Redis). epoll “okuyabilirsin” der, işi yine read yapar; disk dosyaları her zaman “hazır” görünür, bu yüzden disk için gerçek eşzamansızlık io_uring ile gelir.
G/Ç Arayüzleri · Adım adım
io_uring: Paylaşılan Halkalar
io_uring (Linux 5.1, 2019): uygulama ile çekirdek iki halkayı paylaşılan bellekte görür; istek ve sonuç kopyalanmaz.
Uygulama üç gönderim kaydı (SQE) yazar: iki okuma, bir yazma. Her biri işlem kodu, fd, tampon, ofset taşır.
Tek bir io_uring_enter çağrısı üç isteği birden gönderir. SQPOLL kipinde çekirdek iş parçacığı halkayı yoklar: hiç sistem çağrısı gerekmez.
Aygıtlar tamamlandıkça çekirdek tamamlanma kayıtlarını (CQE) halkaya ekler; sonuç alanı aktarılan bayt ya da −errno'dur.
Uygulama CQE'leri doğrudan bellekten okur ve başı ilerletir. Toplu gönderim + toplu toplama → çok az bağlam geçişi.
Bu bir tamamlanma modelidir (Windows IOCP gibi): “işin bitti” bildirilir. Ağ, dosya, accept, zamanlayıcı dahil yüzlerce işlem türü vardır. Güvenlik açıkları yüzünden bazı ortamlarda (ör. Android, bazı kapsayıcılar) kapalıdır.
Saatler ve Diğer Aygıtlar
Saat Donanımı
- Örnek (8254 PIT): 1 kHz kesme için sayaç = 1.193.182 / 1000 ≈ 1193 → gerçek frekans 1000,15 Hz.
- Modern x86: TSC (zaman damgası sayacı), HPET, yerel APIC zamanlayıcısı (TSC-deadline kipi); ARM: genel zamanlayıcı. Pil destekli RTC kapalıyken tarihi tutar.
- Saat yazılımı: günün saati, zaman dilimi (quantum) tükenmesi, CPU kullanım muhasebesi,
alarm/zamanlayıcılar, izleme köpeği (watchdog), profil çıkarma. - Günün saati 64 bit sayaçla tutulmalı: 32 bit
time_t19 Ocak 2038'de taşar.
Saatler ve Diğer Aygıtlar · Adım adım
Saat Yazılımı: Tik ve Tiksiz Çekirdek
Periyodik tik: zamanlayıcı her 1/HZ saniyede kesme üretir (Linux'ta HZ = 100, 250 ya da 1000 → 10, 4, 1 ms). İşleyici süreyi artırır, quantum'u azaltır, süresi dolan zamanlayıcıları çalıştırır.
Tiksiz çekirdek (NO_HZ_IDLE, 2007): CPU boşken tik durdurulur, saat bir sonraki olaya tek atım kurulur. nohz_full tek süreçli çekirdekte çalışırken bile tiki kaldırır (HPC, gerçek zamanlı).
Tanenbaum'un örneği: bekleyen sinyaller 4203, 4207, 4213, 4215, 4216'da. Liste yalnız farkları tutar; baştaki 0'a inince olay tetiklenir.
Tiksiz çalışma dizüstü ve sanal makinelerde enerji ile işlemci zamanı kazandırır. Kısa süreli (µs) bekleme için ise yumuşak zamanlayıcılar ve yoklama birlikte kullanılır.
Saatler ve Diğer Aygıtlar
Terminaller, Giriş Aygıtları ve Güç Yönetimi
- tty + satır disiplini: kanonik kipte satır düzenlenir (geri silme, Enter'da teslim); ham kipte her tuş hemen gelir (
stty -icanon, editörler). - Sözde terminal (pty): terminal öykünücüsü,
ssh; ekran denetimi ANSI kaçış dizileriyle. - Klavye tarama kodu gönderir (basma/bırakma); sürücü tuş eşlemesiyle karaktere çevirir. USB HID aygıtları ana makine tarafından 125–1000 Hz yoklanır.
- Linux: input alt sistemi →
/dev/input/event*(evdev) → libinput → Wayland birleştiricisi → pencere.
- ACPI sistem durumları: S0 çalışır (S0ix modern bekleme), S3 RAM'e askı, S4 hazırda bekleme (diske), S5 kapalı.
- CPU: C durumları (boşta uyku derinliği), P durumları (frekans/gerilim; Linux
schedutil). - Aygıtlar: D0–D3 durumları, çalışma zamanı güç yönetimi; NVMe APST, PCIe ASPM, Wi-Fi güç tasarrufu, ekranın kararması.
- İşletim sistemi aygıtları doğru sırayla uyutur/uyandırır ve uyandırma kaynaklarını (klavye, ağ, saat) belirler. Pil ömrünün büyük kısmı boşta geçen süreye bağlıdır.
Diskler
Manyetik Disk Geometrisi
- Plakalar 5400–7200 rpm (sunucu: 10–15 bin) döner; her yüzeye bir kafa. Aynı yarıçaptaki izler silindiri oluşturur. Dış bölgelerde iz başına daha çok sektör vardır.
- İşletim sistemi CHS (silindir, kafa, sektör) yerine LBA görür; disk içindeki denetleyici bunu gerçek geometriye, yedek sektörlere ve önbelleğe kendisi çevirir. Eski CHS sınırı: 1024 × 255 × 63 × 512 B ≈ 8,4 GB.
Diskler · Adım adım hesap
Erişim Süresi: Çalışılmış Örnek
Eski sunumda formül aktarım süresini dışarıda bırakıyordu; üç bileşen de sayılmalı.
Bir tur = 60 000 / 7200 = 8,33 ms; ortalama dönme gecikmesi = yarım tur = 4,17 ms.
İstenen sektör ortalamada yarım tur uzaktadır.
Aktarım = 4096 B ÷ 200 MB/s = 0,020 ms. Toplam = 8 + 4,17 + 0,02 = 12,19 ms.
Mekanik gecikme baskın: süre neredeyse tamamen arama ve dönmede geçer.
Rastgele 4 KiB: 1000 / 12,19 ≈ 82 IOPS → 82 × 4 KiB ≈ 0,34 MB/s. Ardışık 1 MiB: 8 + 4,17 + 5,24 = 17,41 ms → 60 MB/s.
Aynı disk, erişim düzenine göre 180 kat farklı hız verir: yerellik ve çizelgeleme bu yüzden önemli.
Karşılaştırma: NVMe SSD'de 4 KiB rastgele okuma ≈ 50–100 µs ve paralel kuyruklarla 1 milyonun üzerinde IOPS.
Diskler
Disk Biçimlendirme ve Silindir Eğriliği
- Düşük düzey format fabrikada yapılır: izler, sektörler, öncül, ECC ve yedek sektörler. Biçimlendirilmiş kapasite ham kapasiteden azdır.
- Eğrilik hesabı (Tanenbaum): 10 000 rpm → tur 6 ms; 300 sektör/iz → sektör başına 20 µs. İz değiştirme 800 µs ise eğrilik = 800 / 20 = 40 sektör.
- Serpiştirme (interleaving) yavaş denetleyiciler için ardışık sektörleri aralıklı dizerdi; bugün denetleyici tüm izi tampona okuduğundan gereksizdir.
- Bugünkü diskler: 4 KiB fiziksel sektör (Advanced Format); 512e diskler 512 B öykünür, hizasız yazma okuma-değiştir-yaz gerektirir.
Diskler
Bölümleme ve Önyükleme: MBR ve GPT
| BIOS + MBR | UEFI + GPT | |
|---|---|---|
| Bölüm sayısı | 4 birincil (+ mantıksal) | 128 (varsayılan) |
| Azami disk | 2³² × 512 B = 2 TiB | 2⁶⁴ sektör |
| Önyükleme | MBR kodu → etkin bölümün önyükleme sektörü → önyükleyici | Ürün yazılımı ESP'den EFI uygulamasını yükler (GRUB, systemd-boot, Windows Boot Manager); Güvenli Önyükleme imzayı denetler |
| Sağlamlık | tek kopya | yedek başlık + CRC32 |
Üst düzey format: bölüme boş bir dosya sistemi yazmak (önyükleme bloğu, boş alan yönetimi, kök dizin). Eski sunum yalnızca BIOS/MBR akışını anlatıyordu; 2012'den beri PC'ler UEFI + GPT ile gelir.
Diskler
Optik Diskler (Kısaca)
| CD (1982) | DVD (1996) | Blu-ray (2006) | |
|---|---|---|---|
| Kapasite | 650–700 MB | 4,7 / 8,5 / 9,4 / 17 GB | 25 / 50 GB; BDXL 100–128 GB |
| Lazer | 780 nm (kızılötesi) | 650 nm (kırmızı) | 405 nm (mavi-mor) |
| En küçük çukur | 0,83 µm | 0,40 µm | 0,15 µm |
| İz aralığı | 1,6 µm | 0,74 µm | 0,32 µm |
- Tek bir sarmal iz; çukur ile düzlük arasındaki geçiş 1 bitidir. Basılı disklerde çukurlar kalıpla polikarbonata basılır; lazerle yakılmaz. CD-R/DVD-R'de lazer organik boya katmanını ısıtıp yansıtıcılığı değiştirir.
- CD-ROM'da her bayt EFM ile 14 bitlik kanal sembolüne çevrilir (bu bir modülasyon kodudur, ECC değildir); hata düzeltme CIRC ile yapılır. 98 çerçeve × 24 veri baytı = 2352 B; mod 1'de bunun 2048 B'ı kullanıcı verisi, kalanı senkron, başlık ve ek ECC/EDC'dir.
- DVD'nin iki katmanı yarı saydamdır; lazer odağını değiştirerek alttakini okur. Optik ortam bugün çoğunlukla arşiv ve dağıtım içindir; yoğunlukta manyetik ve flash ortamın gerisindedir.
Disk Çizelgeleme
Disk Kolu Çizelgeleme
- Amaç kol hareketini (arama süresi) azaltıp verimi artırmak; sürücü (silindir, istek zamanı) listesini tutar. Ölçüt: toplam kafa hareketi (silindir).
- Bugün LBA → fiziksel eşleme diskin içindedir; diskin kendisi NCQ ile 32 isteği dönme konumuna göre yeniden sıralar. İşletim sistemi yaklaşık olarak “LBA yakınlığı” ile çizelgeler.
| Algoritma | Fikir | Sorun |
|---|---|---|
| FCFS | Geliş sırası | Adil ama kol çok gezer |
| SSTF | Kafaya en yakın istek (açgözlü) | Uçtaki istekler açlık çekebilir |
| SCAN (asansör) | Bir yönde uca kadar git, dön | Uçlar ve orta eşit beklemez |
| C-SCAN | Tek yönde tara, uçtan başa sıçra | Dönüş hareketi boşa |
| LOOK / C-LOOK | SCAN/C-SCAN, ama son isteğe kadar | Pratikte kullanılan biçimler |
Örnekler Silberschatz'ın kuyruğunu kullanır: kafa 53, istekler 98, 183, 37, 122, 14, 124, 65, 67. Silindirler 0–199.
Disk Çizelgeleme · Adım adım
FCFS
İlk gelen ilk hizmet alır: istekler geliş sırasıyla.
Kafa 53'te. Kuyruk: 98, 183, 37, 122, 14, 124, 65, 67 (silindir 0–199). Kırmızı: bekleyen, yeşil: hizmet verilmiş.
53 → 98: 45 silindir · toplam 45
98 → 183: 85 silindir · toplam 130
183 → 37: 146 silindir · toplam 276
37 → 122: 85 silindir · toplam 361
122 → 14: 108 silindir · toplam 469
14 → 124: 110 silindir · toplam 579
124 → 65: 59 silindir · toplam 638
65 → 67: 2 silindir · toplam 640
Toplam 640 silindir. Adil ve açlıksız, ama 122 → 14 → 124 gibi gidip gelmeler çok pahalı.
Disk Çizelgeleme · Adım adım
SSTF
En kısa arama süresi önce: her adımda kafaya en yakın istek.
Kafa 53'te. Kuyruk: 98, 183, 37, 122, 14, 124, 65, 67 (silindir 0–199). Kırmızı: bekleyen, yeşil: hizmet verilmiş.
53 → 65: 12 silindir · toplam 12
65 → 67: 2 silindir · toplam 14
67 → 37: 30 silindir · toplam 44
37 → 14: 23 silindir · toplam 67
14 → 98: 84 silindir · toplam 151
98 → 122: 24 silindir · toplam 175
122 → 124: 2 silindir · toplam 177
124 → 183: 59 silindir · toplam 236
Toplam 236 (FCFS'nin %37'si). Açgözlüdür ve en iyi sonucu garanti etmez: 53 → 37 → 14 → 65 … daha kısa (208). Yoğun yükte merkezdeki istekler uçtakileri aç bırakabilir.
Disk Çizelgeleme · Adım adım
SCAN (Asansör)
SCAN: kafa bir yönde (burada 0'a doğru) uca kadar gider, sonra döner; asansör gibi.
Kafa 53'te. Kuyruk: 98, 183, 37, 122, 14, 124, 65, 67 (silindir 0–199). Kırmızı: bekleyen, yeşil: hizmet verilmiş.
53 → 37: 16 silindir · toplam 16
37 → 14: 23 silindir · toplam 39
14 → 0: 14 silindir · toplam 53 (istek yok, diskin ucuna kadar gidilir)
0 → 65: 65 silindir · toplam 118
65 → 67: 2 silindir · toplam 120
67 → 98: 31 silindir · toplam 151
98 → 122: 24 silindir · toplam 175
122 → 124: 2 silindir · toplam 177
124 → 183: 59 silindir · toplam 236
Toplam 236. Eski sunumda “açgözlü, kafa bir bölgede sıkışabilir” denmişti: bu SSTF'nin özelliğidir, SCAN açlığı önler. Uca kadar gitmek (53 → 0) boşa harcanan 14 silindir demektir.
Disk Çizelgeleme · Adım adım
C-SCAN
Dairesel SCAN: yalnız yukarı yönde hizmet; uca varınca hizmet vermeden başa döner.
Kafa 53'te. Kuyruk: 98, 183, 37, 122, 14, 124, 65, 67 (silindir 0–199). Kırmızı: bekleyen, yeşil: hizmet verilmiş.
53 → 65: 12 silindir · toplam 12
65 → 67: 2 silindir · toplam 14
67 → 98: 31 silindir · toplam 45
98 → 122: 24 silindir · toplam 69
122 → 124: 2 silindir · toplam 71
124 → 183: 59 silindir · toplam 130
183 → 199: 16 silindir · toplam 146 (istek yok, diskin ucuna kadar gidilir)
199 → 0: geri dönüş (sıçrama, 199 silindir), istek hizmeti yok. Burada sayılıyor · toplam 345
0 → 14: 14 silindir · toplam 359
14 → 37: 23 silindir · toplam 382
Toplam 382 (dönüş sayılmazsa 183). Disk bir halka gibi görülür; bekleme süreleri SCAN'e göre daha eşittir.
Disk Çizelgeleme · Adım adım
LOOK ve C-LOOK
LOOK (aşağı yönde): SCAN gibi, ama uca kadar gitmez; o yöndeki son istekte döner.
53 → 37 → 14: aşağıdaki istekler bitti, 0'a gidilmez. Toplam 39.
14 → 65 … 183: yön değişir. Toplam 208 (SCAN'e göre 28 az). Eski sunumdaki “asansör: 208” aslında bu LOOK değeridir.
C-LOOK (yukarı yönde): 53 → 65 … 183 yukarıdaki son istek. Toplam 130.
183 → 14: en küçük bekleyen isteğe sıçrar (169 silindir), 199 ve 0'a gidilmez.
14 → 37: toplam 322 (sıçrama sayılmazsa 153). Tek yönlü tarama bekleme sürelerini eşitler.
Linux'un eski deadline ve CFQ zamanlayıcıları ile günümüzdeki mq-deadline LBA'ya göre sıralı gönderir; bu C-LOOK'a benzer bir davranıştır.
Disk Çizelgeleme
Algoritmaların Karşılaştırması
| Tanenbaum örneği: kafa 11; 1, 36, 16, 34, 9, 12 | Hareket |
|---|---|
| FCFS: 10 + 35 + 20 + 18 + 25 + 3 | 111 |
| SSTF: 12, 9, 16, 1, 34, 36 → 1 + 3 + 7 + 15 + 33 + 2 | 61 |
| Asansör (yukarı): 12, 16, 34, 36, 9, 1 → 1 + 4 + 18 + 2 + 27 + 8 | 60 |
SCAN yukarı yönde başlasaydı 331 olurdu: yön seçimi sonucu değiştirir. Tanenbaum'un asansörü uca gitmediği için aslında LOOK'tur.
Disk Çizelgeleme · Adım adım
Denetleyici Önbelleği ve Bozuk Sektörler
Disk kendi DRAM'inde (≈ 256 MB) iz önbelleği tutar: kafanın altından geçen, istenmemiş blokları da okur. İşletim sistemi önbelleğinden ayrıdır.
Yazma önbellekte bekleyebilir: kalıcılık için FLUSH/FUA gerekir. NCQ 32 isteği dönme konumuna göre sıralar.
Üretimde ya da kullanımda bozulan sektör: yazılan veri geri okunamaz. Denetleyici fabrika listesini ve kullanımda bulduklarını izler (SMART: Reallocated Sectors).
Yöntem 1: bozuk sektör bir yedekle eşlenir. Basit ama sektör 7'ye giden ardışık okuma ize bir tur daha ödeyebilir.
Yöntem 2: sektörler kaydırılır; tüm iz yeniden yazılmalıdır ama sıra korunur. İşletim sistemi de bozuk blok listesi tutabilir (badblocks, dosya sistemi).
SSD ve NVMe
SSD: NAND Flash
| Hücre | Bit/hücre | Tipik P/E döngüsü | Kullanım |
|---|---|---|---|
| SLC | 1 | ≈ 50–100 bin | önbellek bölgesi, endüstriyel |
| MLC | 2 | ≈ 3–10 bin | eski kurumsal |
| TLC | 3 | ≈ 1–3 bin | çoğu tüketici ve sunucu SSD'si |
| QLC | 4 | ≈ 0,1–1 bin | yüksek kapasite, okuma ağırlıklı |
- Hareketli parça yok: arama ve dönme gecikmesi yok, rastgele erişim ≈ ardışık erişim.
- Yerinde güncelleme yok: sil, sonra yaz; her hücrenin silme ömrü sınırlıdır. 3D NAND 200–300+ katman.
- Fiyat/GB farkı azaldı; HDD yine de arşivde ve kapasitede ucuzdur.
SSD ve NVMe · Adım adım
FTL, Çöp Toplama, TRIM, Aşınma Dengeleme
Üç mantıksal blok yazılır; FTL onları B0'ın boş sayfalarına koyar ve tabloya kaydeder.
LBA 1 yeniden yazılır: eski sayfanın üzerine yazılamaz. Yeni veri boş sayfaya gider, eskisi geçersiz olur (yer dışı güncelleme).
Dosya silinince dosya sistemi TRIM (NVMe: Deallocate) gönderir; SSD sayfanın gereksiz olduğunu öğrenir. TRIM olmasa bu veri çöp toplamada boşuna kopyalanırdı.
B0'da boş sayfa kalmadı; yeni yazmalar B1'e gider. B0'da yarısı geçersiz.
Çöp toplama: B0'daki geçerli sayfalar (LBA 0, 1) B1'e kopyalanır, B0 silinir. Ek 2 sayfa yazması = yazma büyütmesi.
Aşınma dengeleme: FTL silme sayılarını dengeler; uzun süre değişmeyen (soğuk) veriyi de taşıyarak tüm blokları eşit yaşlandırır. Yedek alan (over-provisioning) çöp toplamayı kolaylaştırır.
SSD ve NVMe
NVMe ve Çoklu Kuyruk
- NVMe, PCIe üzerindeki flash için tasarlanmış protokoldür; M.2 ise bir form faktörüdür (M.2 kart SATA da olabilir). U.2/U.3 ve E1.S/E3.S kablolu/yuvalı sunucu biçimleridir.
- Eski sunumdaki “64 KB'a kadar komut dizisi” ifadesi düzeltildi: 64 K kuyruk × 64 K komut. Sürücü desteği 2013'ten beri tüm işletim sistemlerinde yerleşiktir; AHCI ile uyumsuzluk yalnız protokol düzeyindedir.
- Gecikme ≈ 10–100 µs; PCIe 5.0 x4 sürücüler ≈ 14 GB/s ve > 2 milyon IOPS. NVMe-oF ile ağ üzerinden, ZNS ile bölgeli ad alanları.
SSD ve NVMe
Linux blk-mq ve G/Ç Zamanlayıcıları
| Zamanlayıcı | Fikir | Uygun |
|---|---|---|
none | Sıralama yok, doğrudan gönder | NVMe (varsayılan), hızlı SSD |
mq-deadline | LBA'ya göre sıralı + okuma/yazma son tarihi | SATA HDD/SSD (çoğu dağıtımda varsayılan) |
bfq | Süreç başına bütçe, adil paylaşım | Masaüstü, yavaş aygıtlarda etkileşim |
kyber | Okuma/yazma gecikme hedefleriyle sınırlama | Hızlı çok kuyruklu aygıtlar |
$ cat /sys/block/nvme0n1/queue/scheduler [none] mq-deadline kyber bfq $ echo bfq | sudo tee /sys/block/sda/queue/scheduler
Linux 5.0'da tek kuyruklu eski blok katmanı (noop, deadline, CFQ) kaldırıldı. SSD'de arama olmadığından zamanlayıcının işi sıralamak değil, adaleti ve gecikmeyi korumaktır.
RAID ve Kararlı Depolama
RAID: Diskleri Birleştirmek
- RAID (Patterson, Gibson, Katz, 1988): birçok diski işletim sistemine tek disk gibi gösterir; şeritleme paralellik, aynalama ve eşlik artıklık sağlar. Karşıtı SLED: tek, büyük, pahalı disk.
- Açılımı bugün Redundant Array of Independent Disks. Eski sunumdaki “SCSI ucuzdur, denetleyici başına 7 disk, seviye 0–7” bilgileri tarihseldir: SCSI pahalıydı, SAS genişleticiler yüzlerce disk bağlar, standart seviyeler 0–6'dır.
- Donanım RAID kartı ya da yazılım RAID (Linux
mdadm, ZFS RAID-Z, Btrfs, Windows Depolama Alanları). RAID yedek değildir: silinen dosya her diskte silinir.
| 4 × 4 TB disk | Kullanılabilir | Dayanır | Küçük rastgele yazma maliyeti |
|---|---|---|---|
| RAID 0 (şeritleme) | 16 TB | 0 disk | 1 G/Ç |
| RAID 1 (4 kopya ayna) | 4 TB | 3 disk | 4 G/Ç (her kopyaya) |
| RAID 10 (ayna + şerit) | 8 TB | 1 (çiftler farklıysa 2) | 2 G/Ç |
| RAID 5 (dağıtılmış eşlik) | 12 TB | 1 disk | 4 G/Ç (2 oku + 2 yaz) |
| RAID 6 (çift eşlik) | 8 TB | 2 disk | 6 G/Ç (3 oku + 3 yaz) |
RAID ve Kararlı Depolama · Adım adım
RAID Düzenleri
RAID 0: ardışık şeritler farklı disklere; büyük isteklerde n kat bant genişliği. Bir disk bozulursa her şey kaybolur.
RAID 1: her yazma iki kez yapılır; okuma iki diskten birinden (yük dağıtılır). Kapasitenin yarısı artıklık.
RAID 10: önce aynala, sonra şeritle. Veritabanlarında yaygın: hızlı yazma ve hızlı yeniden kurma.
RAID 2 sözcük + Hamming kodu, RAID 3 bayt + tek eşlik diski kullanır; kolların eşzamanlı dönmesi gerekir. Bugün kullanılmaz (disk zaten ECC yapar).
RAID 4: blok şeritleri + ayrı eşlik diski. Her küçük yazma eşlik diskini günceller: eşlik diski darboğaz.
RAID 5: eşlik blokları disklere sırayla dağıtılır; darboğaz kalkar. n − 1 disk kapasitesi, bir disk kaybına dayanır.
RAID 6: P (XOR) + Q (Reed–Solomon, GF(2⁸)) eşliği; iki disk kaybına dayanır. Büyük disklerde yeniden kurma saatler sürdüğü için tercih edilir.
RAID ve Kararlı Depolama · Adım adım
Eşlik ve XOR: Çalışılmış Örnek
Bir şeritte üç veri bloğu (burada 8 bitlik örnek). Eşlik bloğu henüz hesaplanmadı.
Eşlik bit bit XOR'dur: her bit konumunda 1'lerin sayısı çift olacak biçimde tamamlanır.
Disk 1 bozuldu. XOR'un özelliği: x ⊕ x = 0, dolayısıyla kayıp blok kalanların XOR'udur.
Kurtarılan değer 0101 1100: özgün D1 ile aynı. Yeni diske tüm şeritler böyle yeniden yazılır (yeniden kurma).
Küçük yazma: D1' = 0000 1111. Eski D1 ve P okunur, P' hesaplanır, D1' ve P' yazılır: 4 G/Ç (oku-değiştir-yaz).
Yeniden kurma riski: tüketici diskte düzeltilemeyen okuma hatası (URE) ≈ 1014 bitte 1. 12 TB'lık yeniden kurmada beklenen hata 12×1012×8 / 1014 ≈ 0,96: RAID 5'te ikinci bir sorun neredeyse kesin, bu yüzden büyük dizilerde RAID 6 seçilir.
RAID ve Kararlı Depolama · Adım adım
Kararlı Depolama
- Kararlı depolama: bir yazma ya doğru biçimde tamamlanır ya da eski veri yerinde kalır. Varsayımlar: iki diskte aynı bloğun birden bozulma olasılığı ihmal edilir; hatalı veri ECC ile fark edilir; CPU çökerse süren yazma durur.
- Kararlı yazma: disk 1'e yaz, geri oku, doğrula (n kez dene, gerekirse yedek sektör); sonra aynısını disk 2'ye yap. Kararlı okuma: disk 1'den geçerli ECC ile okunamazsa disk 2'den oku.
(a) Çökme disk 1'e yazmadan önce: iki kopya da eski. Yazma hiç olmamış sayılır.
(b) Çökme disk 1'e yazarken: disk 1 bozuk (ECC). Eski değer disk 2'den geri getirilir.
(c) Disk 1 yazıldı, disk 2 yazılmadan çöktü: yeni değer tamamlanır.
(d) Disk 2'ye yazarken çöktü: disk 2 bozuk, yeni değer disk 1'den kopyalanır.
(e) İki kopya da yeni: yazma tamamlanmış. Her durumda sonuç ya tamamen eski ya tamamen yenidir.
RAID bozulan sektörlere karşı korur, yazma sırasında çökmeye karşı korumaz. Bugün aynı fikir günlükleme (journaling), yazma bariyerleri/FUA ve kurumsal SSD'lerdeki güç kaybı koruma kapasitörleriyle uygulanır.
Özet
Özet
| Konu | Ana fikir | Bugün |
|---|---|---|
| Donanım erişimi | Denetleyici yazmaçları; kapı ya da bellek eşlemeli | PCIe BAR ile MMIO |
| Aktarım | Yoklama → kesme → DMA | MSI-X, bus-master DMA, IOMMU |
| Yazılım katmanları | Kullanıcı / bağımsız / sürücü / kesme | VFS + sayfa önbelleği + blk-mq |
| Arayüz | Engelleyen, engellemeyen, eşzamansız | epoll, io_uring |
| Tamponlama | Hız/boyut farkı, çift ve dairesel tampon | NIC/NVMe halkaları, sıfır kopya |
| HDD | Arama + dönme + aktarım; çizelgeleme | NCQ, mq-deadline, BFQ |
| SSD | Arama yok; FTL, çöp toplama, TRIM | NVMe, çok kuyruk, none |
| Güvenilirlik | RAID 0/1/5/6/10, kararlı depolama | mdadm, ZFS, günlükleme |
G/Ç tasarımının özü: yavaş ve çeşitli aygıtları hızlı CPU'dan ayırmak (tampon, kesme, DMA), farkları tek tip arayüzün arkasına gizlemek (sürücü, VFS) ve sırayı akıllıca seçmek (çizelgeleme, toplu gönderim).
Özet
Kontrol Soruları
- Kapı eşlemeli ve bellek eşlemeli G/Ç'de aygıt yazmacına hangi komutla erişilir? MMIO'da önbellek sorunu nasıl çözülür?
- 4096 karakter, saniyede 1000 karakter basan yazıcıya kesme güdümlü G/Ç ile gönderilecek; kesme başına 2 µs. CPU maliyeti nedir?
- Döngü çalma nedir? DMA hangi durumlarda kendini geri ödemez?
- 7200 rpm, ortalama arama 8 ms, ortam hızı 200 MB/s olan diskte 4 KiB rastgele okuma kaç ms sürer?
- Kafa 53, kuyruk 98, 183, 37, 122, 14, 124, 65, 67 (0–199). SSTF ve C-LOOK (yukarı) toplam hareketi nedir?
- Kafa 11, istekler 1, 36, 16, 34, 9, 12. FCFS, SSTF ve asansör (yukarı) kaç silindir hareket eder?
- RAID 5'te D0 = 1011 0010, D2 = 1110 0111, P = 0000 1001. Bozulan D1 nedir?
- SSD'de TRIM neden gerekir? Linux NVMe aygıtlarında varsayılan G/Ç zamanlayıcısı hangisidir, neden?
epollileio_uringarasındaki temel model farkı nedir?
Cevaplar
- Kapı:
IN/OUT; MMIO: sıradanMOV. Yazmaç sayfaları önbelleklenemez işaretlenir (PAT/MTRR,ioremap). - 4096 × 2 µs = 8,19 ms (yoklamada 4,096 s).
- DMA her sözcük için yolu kısa süre alır, CPU bellek erişiminde bekler. Küçük aktarım, yavaş DMA denetleyicisi ya da CPU'nun yapacak başka işi yoksa.
- 8 + 4,17 + 0,02 = 12,19 ms (≈ 82 IOPS).
- SSTF 236; C-LOOK 322 (sıçrama sayılmazsa 153).
- 111, 61, 60.
- D0 ⊕ D2 ⊕ P = 0101 1100.
- SSD hangi sayfaların artık geçersiz olduğunu öğrenir; çöp toplama onları kopyalamaz, yazma büyütmesi azalır.
none: arama yok, çok kuyruk zaten paralel; sıralama CPU harcar. - epoll hazır olmayı bildirir (sonra
readçağrılır); io_uring işin tamamlandığını bildirir ve istekleri paylaşılan halkalarla toplu gönderir.
Özet
Kaynaklar
- A. Silberschatz, P. B. Galvin, G. Gagne, Operating System Concepts, 10. baskı, Wiley, 2018 — Bölüm 11: Mass-Storage Structure; Bölüm 12: I/O Systems.
- A. S. Tanenbaum, H. Bos, Modern Operating Systems, 4. baskı (2014) / 5. baskı (2022), Pearson — Bölüm 5: Input/Output.
- R. H. Arpaci-Dusseau, A. C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces (OSTEP), ostep.org — “I/O Devices”, “Hard Disk Drives”, “RAID”, “Flash-based SSDs”.
- D. A. Patterson, G. Gibson, R. H. Katz, “A Case for Redundant Arrays of Inexpensive Disks (RAID)”, SIGMOD 1988.
- NVM Express Base Specification 2.x; PCI-SIG PCIe 5.0/6.0; USB4 Specification; UEFI Specification (GPT).
- Linux çekirdek belgeleri: “Multi-Queue Block IO Queueing Mechanism (blk-mq)”, “NO_HZ: Reducing Scheduling-Clock Ticks”,
io_uring(J. Axboe, “Efficient IO with io_uring”), “Linux Device Drivers” (Corbet, Rubini, Kroah-Hartman, 3. baskı).