Bölüm 2: İşletim Sistemi Yapıları

İşletim Sistemleri
ServislerSüreç, adres uzayı, dosyaÇift kipSistem çağrıları POSIX ve Win32MonolitikKatmanlıMikroçekirdek ModülerHibritExokernelSanal makinelerBağlama ve açılış
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Servisler ve kavramlar

İşletim sisteminin sunduğu servisleri; süreç, adres uzayı, dosya, bağlama ve boru hattı kavramlarını açıklamak.

Sistem çağrıları

Kullanıcı kipinden çekirdek kipine geçişi, parametre aktarımını ve temel POSIX çağrılarını adım adım izlemek.

Çekirdek yapıları

Monolitik, katmanlı, mikroçekirdek, modüler, hibrit ve exokernel yapılarını güçlü ve zayıf yönleriyle karşılaştırmak.

Sanallaştırma ve açılış

Hipervizör türlerini, konteynerleri, bağlayıcı/yükleyiciyi ve önyükleme sürecini tanımak.

Giriş

Neden Yapı Önemli?

  • İşletim sistemi; süreç, bellek, dosya, G/Ç ve ağ yönetimi gibi çok sayıda bileşenden oluşur.
  • Bu bileşenlerin nerede çalışacağına (çekirdek / kullanıcı kipi) ve nasıl haberleşeceğine (fonksiyon çağrısı / mesaj) dair stratejiye işletim sistemi yapısı denir.
  • Yapı; karmaşıklığı yönetmeyi, değişikliği, hata ayıklamayı ve taşınabilirliği doğrudan etkiler.
PerformansGüvenilirlikve izolasyonEsneklikve bakımödünleşim
Tek doğru yapı yoktur: her yapı belirli bir ödünleşim sunar ve belirli kullanım senaryolarına (masaüstü, sunucu, gömülü, güvenlik-kritik) daha uygundur.

Servisler

İşletim Sistemi Servisleri

Kullanıcılar ve diğer sistem programlarıArayüzler:GUIDokunmatikKomut satırıSistem çağrılarıİşletim sistemi servisleriProgram yürütmeG/Ç işlemleriDosya sistemleriİletişimKaynak ayırmaKaynak izlemeHata algılamaKoruma, güvenlikDonanım

Servislere kullanıcı arayüzleri ve programlar tarafından sistem çağrıları üzerinden erişilir (Silberschatz, Şekil 2.1’den uyarlanmıştır).

Servisler

Servisler Kime Hizmet Eder?

Kullanıcıya ve programlara yardımcı
  • Arayüz: komut satırı, GUI, dokunmatik, sesli.
  • Program yürütme: yükle, çalıştır, normal / hatalı sonlandır.
  • G/Ç işlemleri: program aygıta doğrudan değil OS üzerinden erişir.
  • Dosya sistemi: oluştur, sil, oku, yaz, ara, izinler.
  • İletişim: paylaşılan bellek veya mesaj aktarımı (yerel / ağ).
  • Hata algılama: donanım, aygıt ve program hataları.
Sistemin verimli ve güvenli çalışması
  • Kaynak ayırma: CPU, bellek, depolama birden çok sürece paylaştırılır.
  • Kaynak izleme (accounting): kim, ne kadar kaynak kullandı; günlük kayıtları.
  • Koruma: süreçler birbirine ve çekirdeğe zarar veremez.
  • Güvenlik: kimlik doğrulama, yetkilendirme, dış saldırılara karşı savunma.
Kullanıcıların çoğu işletim sistemini sistem çağrılarıyla değil, sistem programlarıyla görür: ls, cp, ps, paket yöneticisi, derleyici, dosya yöneticisi…

Temel Kavramlar

Süreç (Process)

  • Süreç, yürütülmekte olan bir programdır; program diskteki pasif dosya, süreç onun etkin örneğidir.
  • Her süreçle ilişkili: adres uzayı (kod, veri, yığın), yazmaçlar (PC, SP), açık dosyalar, alarmlar, ilişkili süreçler ve diğer kaynaklar.
  • OS bu bilgileri süreç tablosunda tutar; askıya alınan süreç, PCB sayesinde kaldığı yerden devam eder.
  • Süreçler birbirleriyle IPC (süreçler arası iletişim) ile haberleşebilir.
Süreç tablosuPIDDurumProgram1uyuyorsystemd812bekliyorbash1045çalışıyorls1046hazırgrepPCB (süreç denetim bloğu)PID, durum, öncelikPC, SP ve diğer yazmaçlarbellek haritası (adres uzayı)açık dosyalar (fd tablosu)sinyaller, alarmlar, UID, ata

Temel Kavramlar

Süreç Ağacı

Bir süreç fork() ile çocuk süreçler oluşturabilir; çocuklar da kendi çocuklarını oluşturur. Sonuç bir ağaçtır.

APID 1 (systemd) ağacın köküdür

Başlangıçta yalnızca A süreci vardır. Linux’ta tüm ağacın kökü PID 1 olan systemd (veya init) sürecidir.

ABCfork()

A süreci iki kez fork() çağırır: B ve C, A’nın çocuklarıdır (A onların atasıdır).

ABCDEFfork()fork()

B süreci D, E ve F olmak üzere üç çocuk oluşturur. pstree -p komutu bu ağacı gösterir.

Temel Kavramlar

Adres Uzayı ve Bellek Kesimleri

  • Adres uzayı: bir sürecin kullanabildiği adresler kümesi (0 … max). x86-64 Linux’ta kullanıcı alanı 128 TiB’dir.
  • Bellekte aynı anda çok sayıda süreç bulunur; OS onları birbirinden ve çekirdekten korur.
  • Metin: makine kodu; salt okunur, aynı programı çalıştıran süreçler ve tüm iş parçacıkları paylaşır.
  • Veri + BSS: global ve static değişkenler. Öbek: çalışma anında ayrılan dinamik bellek. İkisi de sürecin iş parçacıklarınca paylaşılır.
  • Yığın: parametreler, yerel değişkenler, dönüş adresleri; her iş parçacığının kendi yığını vardır.
  • Fiziksel bellekten büyük adres uzayları sanal bellek ile mümkündür (Bölüm 9).
max0yığın (stack)boşöbek (heap)BSSveri (data)metin (text)yerel değişkenler,parametreler,dönüş adreslerimalloc / newilklenmemiş globalilklenmiş globalmakine kodu,salt okunur

Temel Kavramlar

Dosyalar ve Dizin Hiyerarşisi

  • Dosya: verileri kalıcı olarak saklayan adlandırılmış birim (metin, resim, video, program…).
  • OS disk bloklarını ve aygıt ayrıntılarını gizler; temiz bir soyutlama sunar.
  • Dosyalar dizin ağacında tutulur. Yol adı mutlak (/home/ali/notlar.txt) veya çalışma dizinine göre göreli (ali/notlar.txt) olabilir.
  • Açılan dosyaya küçük bir tamsayı, dosya tanıtıcı (fd) verilir; 0, 1, 2 = stdin, stdout, stderr.
  • Özel dosyalar: aygıtlar dosya gibi görünür. Blok (/dev/sda, /dev/nvme0n1) ve karakter (/dev/tty, seri port) aygıtları.
/binhomeusrdevaliaysesdattynotlar.txtodev.cdizindosyaaygıt

Temel Kavramlar

Dosya Sistemini Bağlama (mount)

/binhomemntAna dosya sistemi (/dev/nvme0n1p2)kökabxyzUSB bellek (/dev/sdb1)?

Bağlamadan önce USB bellekteki dosya sistemi ayrı bir ağaçtır; ona hiçbir yol adıyla erişilemez.

/binhomemntAna dosya sistemi (/dev/nvme0n1p2)kökabxyzUSB bellek (/dev/sdb1)mount /dev/sdb1 /mnt

mount, yeni dosya sisteminin kökünü mevcut ağaçtaki bir bağlama noktasına (boş dizin /mnt) iliştirir.

/binhomemntAna dosya sistemi (/dev/nvme0n1p2)abxyzArtık tek ağaç:/mnt/a/x/mnt/b/z

Bağlandıktan sonra USB’deki dosyalar hiyerarşinin parçasıdır. Windows’ta bunun yerine genellikle sürücü harfleri (C:, D:) kullanılır.

Temel Kavramlar

mount Komutu ve Seçenekleri

$ lsblk                              # diskleri ve bölümleri listele
$ sudo mount /dev/sdb1 /mnt          # sdb1'i /mnt dizinine bağla
$ sudo mount -o ro /dev/sdb1 /mnt    # salt okunur (read-only) bağla
$ sudo mount -o remount,rw /mnt      # okuma-yazma olarak yeniden bağla
$ findmnt /mnt                       # bağlama bilgisini göster
$ sudo umount /mnt                   # bağlantıyı kaldır
ro / rw

Salt okunur ya da okuma-yazma bağlama. Kurtarma ve adli inceleme için ro güvenlidir.

/etc/fstab

Açılışta otomatik bağlanacak dosya sistemleri burada (veya systemd mount birimlerinde) tanımlanır.

Masaüstünde

Takılan USB bellek udisks2 tarafından kendiliğinden /run/media/… altına bağlanır.

Temel Kavramlar

Boru Hattı (pipe)

  • İki süreci bağlayan, çekirdekte tamponlanan tek yönlü bir bayt kanalıdır; süreçler onu dosya gibi read/write ile kullanır.
  • Anonim: pipe() ile oluşur, ata-çocuk süreçler arasında. Adlandırılmış (FIFO): mkfifo ile dosya sisteminde adı vardır, ilgisiz süreçler kullanabilir.
$ ls -l | grep "notlar"
çekirdekls -lstdout → fd[1]grep notlarstdin ← fd[0]boru tamponu (64 KiB)yazma ucuokuma ucu

Kabuk önce pipe(fd) çağırır: çekirdek bir tampon ve iki uç açar (fd[0] okuma, fd[1] yazma).

çekirdekls -lstdout → fd[1]grep notlarstdin ← fd[0]boru tamponu (64 KiB)yazma ucuokuma ucu

Kabuk iki kez fork eder; dup2 ile ls’in stdout’u yazma ucuna, grep’in stdin’i okuma ucuna yönlendirilir.

çekirdekls -lstdout → fd[1]grep notlarstdin ← fd[0]boru tamponu (64 KiB)yazma ucuokuma ucu-rw-r--r-- … notlar.txtterminale

ls listeyi boruya yazar, grep okur ve yalnızca “notlar” içeren satırları terminale yazar.

çekirdekls -lstdout → fd[1]grep notlarstdin ← fd[0]boru tamponu (64 KiB)yazma ucuokuma ucutampon dolu → yazan bekler; boş → okuyan beklerEOF

Akış denetimi çekirdekte: tampon dolunca yazan, boşken okuyan bloke olur. ls bitip yazma ucu kapanınca grep dosya sonu (EOF) görür.

Temel Kavramlar

Kilitlenme (Deadlock)

  • Kümedeki her süreç, başka bir sürecin tuttuğu kaynağı beklerse hiçbiri ilerleyemez: kilitlenme.
  • Trafikte dört yönden kavşağa girip birbirini bekleyen araçlar gibi. Ayrıntılar Bölüm 7’de.
P1P2R1R2P1P2R1R2(a) Potansiyel: istekler henüz yapılmadı(b) Gerçekleşmiş: döngü P1→R2→P2→R1→P1tutar

Kareden sürece ok: kaynak o süreçte. Süreçten kareye ok: süreç o kaynağı istiyor (kesikli = ileride isteyecek).

Koruma

Çift Kip: Kullanıcı ve Çekirdek

  • CPU’daki mod biti hangi kipte çalışıldığını gösterir. G/Ç, zamanlayıcıyı ayarlama, kesmeleri kapatma, sayfa tablolarını değiştirme gibi ayrıcalıklı komutlar yalnızca çekirdek kipinde çalışır.
  • Kullanıcı kipinde ayrıcalıklı komut denenirse donanım tuzak üretir, OS süreci sonlandırır. x86’da halkalar 0–3 (Linux ve Windows yalnızca 0 ve 3’ü kullanır), ARM’da EL0–EL3; sanallaştırma için ek bir kip vardır.
kullanıcı kipi (mod biti = 1)çekirdek kipi (mod biti = 0)kullanıcı süreci çalışıyortuzak: syscallsistem çağrısını yürütdönüş: sysretçağrıdan dönülür, devam

Kullanıcı süreci kullanıcı kipinde kendi kodunu çalıştırır.

kullanıcı kipi (mod biti = 1)çekirdek kipi (mod biti = 0)kullanıcı süreci çalışıyortuzak: syscallsistem çağrısını yürütdönüş: sysretçağrıdan dönülür, devam

Bir sistem çağrısı (veya kesme / istisna) tuzak üretir: mod biti 0 olur, CPU çekirdekteki sabit giriş noktasına atlar.

kullanıcı kipi (mod biti = 1)çekirdek kipi (mod biti = 0)kullanıcı süreci çalışıyortuzak: syscallsistem çağrısını yürütdönüş: sysretçağrıdan dönülür, devam

Çekirdek, istenen hizmeti tam ayrıcalıkla yürütür.

kullanıcı kipi (mod biti = 1)çekirdek kipi (mod biti = 0)kullanıcı süreci çalışıyortuzak: syscallsistem çağrısını yürütdönüş: sysretçağrıdan dönülür, devam

İş bitince özel dönüş komutu mod bitini 1 yapar ve kullanıcı koduna döner.

kullanıcı kipi (mod biti = 1)çekirdek kipi (mod biti = 0)kullanıcı süreci çalışıyortuzak: syscallsistem çağrısını yürütdönüş: sysretçağrıdan dönülür, devam

Süreç, sistem çağrısından sonraki komuttan devam eder; sonuç bir yazmaçtadır.

Koruma

Zamanlayıcı (Timer)

  • Amaç: bir sürecin sonsuz döngüye girip CPU’yu hiç bırakmamasını önlemek.
  • OS sayaca bir değer yükler; bu, ayrıcalıklı bir komuttur.
  • Fiziksel saatin her darbesinde sayaç azalır; sıfır olunca kesme üretilir ve OS kontrolü yeniden kazanır.
  • OS, zaman dilimini dolduran süreci keser ve CPU’yu başka sürece verir (kesintili zamanlama). Süreci sonlandırmak ancak CPU süresi sınırı (ör. RLIMIT_CPU) aşılırsa söz konusudur.
  • Linux’ta düzenli tik 100–1000 Hz’dir; boşta tik üretmeyen tickless (NO_HZ) kip enerji kazandırır.
sayaç3saat darbesi−1A çalışıyorCPU

OS, A’yı çalıştırmadan önce sayaca 3 yükler.

sayaç2saat darbesi−1A çalışıyorCPU

Her saat darbesinde sayaç bir azalır: 2.

sayaç1saat darbesi−1A çalışıyorCPU

Sayaç 1; A hâlâ CPU’da.

sayaç0saat darbesi−1kesme → OSCPUkontrol OS’ta

Sayaç 0: zamanlayıcı kesmesi. CPU çekirdek kipine geçer, kesme işleyicisi çalışır.

sayaç3saat darbesi−1B çalışıyorCPUsayaç yeniden yüklendi

Zamanlayıcı A’nın dilimi dolduğu için B’yi seçer ve sayacı yeniden yükler.

Sistem Çağrıları

Sistem Çağrısı Nedir?

  • Programların işletim sistemi servislerine (dosya, bellek, süreç, zaman, ağ…) erişmek için kullandığı tanımlı arayüz.
  • Uygulama tarafından istenir, çekirdek tarafından çekirdek kipinde yürütülür.
  • Programcı çoğunlukla çağrıları doğrudan değil bir API üzerinden kullanır: POSIX (glibc, musl), Windows API, Java API. API taşınabilirlik ve kolaylık sağlar.
  • Çağrı kümesi sistemden sisteme değişir: Linux x86-64’te yaklaşık 370 çağrı vardır. Temel kavramlar ise ortaktır.
  • strace (Linux), dtruss (macOS) ve Process Monitor (Windows) bir programın yaptığı çağrıları gösterir.
Uygulama programıAPI: libc, Win32, Javasistem çağrısı arayüzükullanıcıçekirdekÇekirdek servisleriDonanım

Sistem Çağrıları

API → Sistem Çağrısı Arayüzü → Çekirdek

kullanıcı kipiçekirdek kipiopen("notlar.txt", O_RDONLY)sistem çağrısı arayüzüsistem çağrısı tablosu0read1write2open3close……257openatopen() gerçeklemesidosyayı bul, izinleri denetle

Uygulama libc’deki open() sarmalayıcısını çağırır; sarmalayıcı çağrı numarasını yazmaca koyar ve tuzak komutunu çalıştırır.

kullanıcı kipiçekirdek kipiopen("notlar.txt", O_RDONLY)sistem çağrısı arayüzüsistem çağrısı tablosu0read1write2open3close……257openatopen() gerçeklemesidosyayı bul, izinleri denetle

Çekirdekteki sistem çağrısı arayüzü, numarayı sistem çağrısı tablosunda indis olarak kullanır (x86-64 Linux: open = 2).

kullanıcı kipiçekirdek kipiopen("notlar.txt", O_RDONLY)sistem çağrısı arayüzüsistem çağrısı tablosu0read1write2open3close……257openatopen() gerçeklemesidosyayı bul, izinleri denetle

Tablodaki gösterici çekirdekteki gerçeklemeye götürür: yol çözülür, izinler denetlenir, açık dosya kaydı oluşturulur.

kullanıcı kipiçekirdek kipiopen("notlar.txt", O_RDONLY)sistem çağrısı arayüzüsistem çağrısı tablosu0read1write2open3close……257openatopen() gerçeklemesidosyayı bul, izinleri denetledönüş: fd = 3

Sonuç (ilk boş tanıtıcı: 0, 1, 2 dolu olduğundan 3) kullanıcıya döner. Not: güncel glibc open()’u aslında openat (257) ile gerçekler.

Sistem Çağrıları

Örnek: Bir Dosyayı Başka Dosyaya Kopyalamak

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

Kullanıcıdan ad almak bile iki çağrı ister: ekrana istem yaz (write), klavyeden oku (read).

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

Aynı işlem çıktı dosyası için tekrarlanır.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

open başarısız olursa (dosya yok, izin yok) −1 döner; program hata mesajı yazıp çıkar.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

open(…, O_WRONLY | O_CREAT | O_EXCL): dosya zaten varsa hata verir.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

Asıl iş: read 0 (dosya sonu) dönene kadar okunan baytlar write ile yazılır.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

Her açık dosya close ile kapatılır.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

Kullanıcıya bilgi verilir.

Girdi dosyasının adını iste ve okuwrite, readÇıktı dosyasının adını iste ve okuwrite, readGirdi dosyasını aç (yoksa hata ver, çık)openÇıktı dosyasını oluştur (varsa hata, çık)open + O_CREATDöngü: girdiden oku, çıktıya yazread, writeDosyaları kapatcloseEkrana “tamamlandı” yazwriteNormal sonlanexit

exit ile süreç sonlanır. Böyle basit bir program bile onlarca çağrı yapar; strace -c cp a b ile sayılabilir.

Sistem Çağrıları

read(fd, buffer, nbytes) Çağrısının 11 Adımı

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfdDağıtıcıtablo[no]sys_read(işleyici)123

1–3: Parametreler yığına itilir (Tanenbaum’un örneğindeki tarihsel 32-bit x86 kuralı). x86-64’te ilk altı parametre yazmaçlarla aktarılır.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)4

4: Kütüphanedeki read() sıradan bir fonksiyon gibi çağrılır; dönüş adresi yığına girer.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)5

5: Kütüphane çağrı numarasını çekirdeğin beklediği yazmaca koyar (Linux x86-64: rax = 0).

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)6

6: Tuzak komutu (x86-64: syscall) çalışır; CPU çekirdek kipine geçip çekirdekteki sabit adrese atlar.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)7

7: Çekirdek çağrı numarasına bakar ve sistem çağrısı tablosu üzerinden doğru işleyiciye dallanır.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)8

8: İşleyici fd’den buffer’a en çok nbytes bayt kopyalar. Veri hazır değilse süreç bloke olur, CPU başka sürece verilir.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfddönüş adr.Dağıtıcıtablo[no]sys_read(işleyici)9

9: İş bitince kontrol kullanıcı kipine, tuzaktan sonraki komuta döner; sonuç (okunan bayt sayısı) yazmaçtadır.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınınbytes&bufferfdDağıtıcıtablo[no]sys_read(işleyici)10

10: Kütüphanedeki read() kullanıcı programına döner.

kullanıcı alanıçekirdek alanıKullanıcı programınbytes’ı yığına it&buffer’ı yığına itfd’yi yığına itread’i çağıryığını temizleKütüphane: read()çağrı no. → yazmaçTRAP (çekirdeğe geç)çağırana dönKullanıcı yığınıDağıtıcıtablo[no]sys_read(işleyici)11

11: Program parametreleri yığından temizler (SP artırılır) ve sonraki komutla devam eder.

Sistem Çağrıları

Sistem Çağrılarında Parametre Aktarımı

  1. Yazmaçlar: en hızlı yol; Linux en çok 6 parametreyi böyle aktarır.
  2. Bellekte blok / tablo: parametreler bellekte, adresi yazmaçta (şekil). Örn. clone3(struct clone_args *).
  3. Yığın: program parametreleri iter, OS çeker.
kullanıcı programıX adresini yazmacayükle;sistem çağrısı 13X: tabloparam 1param 2param 3yazmaç: X13 nolu çağrı: X’teki tabloyu kullan
x86-64 LinuxGörev
raxçağrı numarası; dönüşte sonuç
rdi, rsi, rdx1., 2., 3. parametre
r10, r8, r94., 5., 6. parametre (C kuralındaki rcx yerine r10)
syscallçekirdeğe geçiş; rcx ve r11 bozulur
ARM64x8 = numara, x0–x5 parametre, svc #0
Hata durumunda çekirdek −1…−4095 arası bir değer (−errno) döndürür; libc bunu errno’ya yazar ve çağırana −1 verir.

Sistem Çağrıları

Kod İzleme: write() ile Ekrana Yazmak

#include <unistd.h>      // write()
#include <string.h>      // strlen()

int main(void) {
    const char *msg = "Merhaba, Dünya!\n";
    size_t len = strlen(msg);        // 17 bayt
    ssize_t n = write(1, msg, len);  // 1: stdout
    if (n == -1)
        return 1;                    // hata
    return 0;
}

msg, salt okunur veri kesimindeki dizgeyi gösterir.

“Merhaba, ” 9 + “Dünya” 6 (ü, UTF-8’de 2 bayt) + “!” ve “\n” 2 = 17 bayt. Sabit 15 yazılsaydı çıktı “Merhaba, Dünya” olarak kesilirdi.

libc sarmalayıcısı: rax=1 (write), rdi=1, rsi=msg, rdx=17; ardından syscall.

Çekirdek kipinde sys_write, 17 baytı fd 1’in bağlı olduğu terminale aktarır.

Kullanıcı kipine dönüş: n = 17, yazılan bayt sayısı. Daha küçük olabilir (kısmi yazma).

n −1 değil, hata yok. Hata olsaydı −1 döner ve errno ayarlanırdı.

main 0 döndürür; libc exit_group(0) çağrısıyla süreci sonlandırır.

Sistem Çağrıları

Kod İzleme: read() ve Bloke Olma

#include <unistd.h>
#include <stdio.h>

int main(void) {
    char buf[100];
    ssize_t n = read(0, buf, sizeof(buf));
    if (n == -1) {
        perror("okuma hatası");
        return 1;
    }
    write(1, buf, n);    // tam n bayt
    return 0;
}

buf yığında ayrılır; içeriği ilklenmemiştir.

fd 0 = stdin (klavye). Henüz satır yok: süreç bloke olur, zamanlayıcı başka süreci çalıştırır.

Kullanıcı “selam” yazıp Enter’a basar; terminal sürücüsü karakterleri ekrana yansıtır ve satırı tamponlar.

Satır tamamlanınca 6 bayt buf’a kopyalanır, süreç uyanır, read 6 döndürür. Sona '\0' eklenmez.

n = 6, hata yok; perror atlanır.

write tam 6 baytı yazar. buf bir C dizgisi olmadığından printf("%s", buf) hatalı olurdu.

Program 0 ile sonlanır.

Sistem Çağrıları

Standart C Kütüphanesi ve Sistem Çağrıları

kullanıcı kipiçekirdek kipiint main(void) { printf("Merhaba\n"); return 0;}Standart C kütüphanesiprintf: biçimle, stdout tamponunakoy; gerekince write çağırwrite(1, tampon, 8) sistem çağrısıterminal: Merhaba

Program printf’i çağırır; bu bir sistem çağrısı değil, kullanıcı kipinde çalışan bir kütüphane fonksiyonudur.

kullanıcı kipiçekirdek kipiint main(void) { printf("Merhaba\n"); return 0;}Standart C kütüphanesiprintf: biçimle, stdout tamponunakoy; gerekince write çağırwrite(1, tampon, 8) sistem çağrısıterminal: Merhaba

libc metni biçimler ve stdout tamponuna koyar. Terminalde tampon satır tamponludur; dosyaya/boruya yönlendirilince tam tamponludur.

kullanıcı kipiçekirdek kipiint main(void) { printf("Merhaba\n"); return 0;}Standart C kütüphanesiprintf: biçimle, stdout tamponunakoy; gerekince write çağırwrite(1, tampon, 8) sistem çağrısıterminal: Merhaba

“\n” geldiği için libc write(1, tampon, 8) sistem çağrısını yapar; çekirdek baytları terminale aktarır.

kullanıcı kipiçekirdek kipiint main(void) { printf("Merhaba\n"); return 0;}Standart C kütüphanesiprintf: biçimle, stdout tamponunakoy; gerekince write çağırwrite(1, tampon, 8) sistem çağrısıterminal: Merhabadönüş: 8

write 8 döndürür, printf de çağırana döner. strace ./merhaba yalnızca write’ı gösterir, printf’i göstermez.

Sistem Çağrıları

Sistem Çağrısı Türleri

Süreç denetimi

oluştur, sonlandır, yükle, bekle, sinyal

fork, execve, exit, waitpid, kill
Dosya yönetimi

oluştur, sil, aç, kapat, oku, yaz, öznitelik

open, read, write, close, stat
Aygıt yönetimi

aygıt iste / bırak, oku, yaz, denetle

ioctl, read, write, mmap
Bilgi bakımı

saat, tarih, sistem ve süreç bilgisi

getpid, uname, clock_gettime
İletişim

bağlantı kur, mesaj gönder/al, paylaşılan bellek

pipe, socket, sendmsg, shm_open
Koruma

izinleri al / ayarla, kullanıcı kimliği

chmod, chown, umask, setuid

Windows karşılıkları: CreateProcess, ReadFile, DeviceIoControl, GetSystemTime, CreatePipe, SetFileSecurity… (Silberschatz, Şekil 2.8)

Sistem Çağrıları

POSIX Çağrıları: Süreç Yönetimi

ÇağrıAçıklama
pid = fork()Atanın kopyası olan bir çocuk süreç oluşturur.
pid = waitpid(pid, &statloc, options)Bir çocuğun sonlanmasını bekler; çıkış durumunu statloc’a yazar.
s = execve(name, argv, envp)Sürecin bellek görüntüsünü yeni programla değiştirir; başarılıysa geri dönmez.
exit(status)Süreci sonlandırır, durumu ataya iletir.
Hata durumunda çağrılar −1 döndürür ve errno ayarlanır. pid: süreç kimliği, s: dönüş kodu. Windows’ta tek bir CreateProcess çağrısı, fork + execve işini birlikte yapar.

Sistem Çağrıları

fork(): Süreç Oluşturma

Çocuk, atanın adres uzayının kopyasını alır: aynı kod, aynı değişken değerleri, aynı açık dosyalar; ama ayrı bir adres uzayında çalışır.

Ata (PID 1000)metin: program kodu (paylaşılır)veri: x = 5yığın, öbekaçık dosyalar: 0 1 2fork() çağırıyor…

Ata süreçte x = 5. Süreç pid = fork(); satırına gelir.

Ata (PID 1000)metin: program kodu (paylaşılır)veri: x = 5yığın, öbekaçık dosyalar: 0 1 2fork() → 1001Çocuk (PID 1001)metin: program kodu (paylaşılır)veri: x = 5yığın, öbekaçık dosyalar: 0 1 2fork() → 0

fork bir kez çağrılır, iki kez döner: atada çocuğun PID’si (1001), çocukta 0. Hata olursa yalnızca atada −1 döner.

Ata (PID 1000)metin: program kodu (paylaşılır)veri: x = 5yığın, öbekaçık dosyalar: 0 1 2fork() → 1001Çocuk (PID 1001)metin: program kodu (paylaşılır)veri: x = 6yığın, öbekaçık dosyalar: 0 1 2fork() → 0

Çocuk x = 6 yazınca yalnızca kendi kopyası değişir; atada x hâlâ 5. Modern OS’lar sayfaları yazılana dek paylaşır (copy-on-write), kopyalama ertelenir.

Sistem Çağrıları

Kod İzleme: Basit Bir Kabuk

#define TRUE 1

while (TRUE) {                  /* sonsuza dek */
    type_prompt();              /* istemi yaz */
    read_command(command, parameters);

    if (fork() != 0) {          /* ata süreç */
        waitpid(-1, &status, 0);
    } else {                    /* çocuk süreç */
        execve(command, parameters, 0);
    }
}

Kabuk istemi yazar ve kullanıcıyı bekler.

Kullanıcı ls yazar; komut ve parametreler ayrıştırılır.

fork kabuğun kopyasını oluşturur. Atada sonuç 1045 (≠ 0), çocukta 0’dır.

Ata waitpid(-1, …) ile herhangi bir çocuğun bitmesini bekler; bloke olur.

Çocuk execve ile kendini ls programıyla değiştirir (PID aynı kalır); ls çıktısını yazar. Gerçek kabuklar komutu PATH’te arar.

ls exit(0) ile biter; atanın waitpid’i döner, status çıkış durumunu içerir.

Döngü başa döner, yeni istem yazılır.

Sistem Çağrıları

POSIX Çağrıları: Dosya Yönetimi

ÇağrıAçıklama
fd = open(file, how, …)Dosyayı okuma, yazma veya ikisi için açar (gerekirse oluşturur).
s = close(fd)Açık dosyayı kapatır.
n = read(fd, buffer, nbytes)Dosyadan tampona en çok nbytes bayt okur.
n = write(fd, buffer, nbytes)Tampondan dosyaya veri yazar.
position = lseek(fd, offset, whence)Dosya konum göstericisini taşır (SEEK_SET, SEEK_CUR, SEEK_END).
s = stat(name, &buf)Dosyanın durum bilgisini (boyut, izinler, zamanlar) alır.

fd: dosya tanıtıcı, n: bayt sayısı, position: dosya başına göre konum. Güncel Linux ayrıca openat, pread/pwrite, statx sunar.

Sistem Çağrıları

POSIX Çağrıları: Dizin Yönetimi ve Diğerleri

ÇağrıAçıklama
s = mkdir(name, mode)Yeni bir dizin oluşturur.
s = rmdir(name)Boş bir dizini siler.
s = link(name1, name2)name1’in gösterdiği dosyaya name2 adlı yeni bir dizin girdisi oluşturur.
s = unlink(name)Bir dizin girdisini siler.
s = mount(special, name, flag)Bir dosya sistemini bağlar (Linux: mount(src, hedef, tür, bayrak, veri)).
s = umount(special)Bir dosya sisteminin bağlantısını kaldırır.
s = chdir(dirname)Çalışma dizinini değiştirir.
s = chmod(name, mode)Dosyanın koruma (izin) bitlerini değiştirir.
s = kill(pid, signal)Bir sürece sinyal gönderir (yalnızca öldürmek için değil).
seconds = time(&seconds)1 Ocak 1970 00:00 UTC’den (Unix epoch) bu yana geçen saniye.

32-bit time_t 19 Ocak 2038’de taşar (2038 sorunu); güncel sistemler 64-bit time_t kullanır.

Sistem Çağrıları

link ve unlink: Bir Dosya, İki Ad

UNIX’te dizin, (i-düğüm numarası, ad) çiftlerinden oluşan bir tablodur. Dosyanın asıl bilgisi i-düğümdedir (inode).

/usr/ast16mail81games40test/usr/jim31bin70memo59f.c.38prog1i-düğüm 70 (dosya)bağlantı sayısı: 1

Başlangıç: /usr/jim/memo 70 numaralı i-düğümü gösterir; bağlantı sayısı 1.

/usr/ast16mail81games40test70note/usr/jim31bin70memo59f.c.38prog1i-düğüm 70 (dosya)bağlantı sayısı: 2

link("/usr/jim/memo", "/usr/ast/note"): /usr/ast’a aynı i-düğümü (70) gösteren yeni girdi eklenir. Veri kopyalanmaz; sayı 2 olur.

/usr/ast16mail81games40test70note/usr/jim31bin59f.c.38prog1i-düğüm 70 (dosya)bağlantı sayısı: 1

unlink("/usr/jim/memo") yalnızca girdiyi siler; dosya note adıyla yaşar. Sayı 0 olunca (ve açık tutan kalmayınca) blokları serbest kalır.

Sistem Çağrıları

UNIX Çağrılarının Win32 API Karşılıkları

UNIXWin32
forkCreateProcess
waitpidWaitForSingleObject
execve(yok: CreateProcess)
exitExitProcess
openCreateFile
closeCloseHandle
readReadFile
writeWriteFile
lseekSetFilePointerEx
statGetFileAttributesEx
UNIXWin32
mkdirCreateDirectory
rmdirRemoveDirectory
linkCreateHardLink
unlinkDeleteFile
mountSetVolumeMountPoint
umountDeleteVolumeMountPoint
chdirSetCurrentDirectory
chmod(yok: ACL, SetFileSecurity)
kill(yok: TerminateProcess)
timeGetSystemTime
Win32 API binlerce fonksiyon içerir; asıl çekirdek geçişini ntdll.dll’deki Nt… fonksiyonları (ör. NtCreateFile) yapar. Bu çağrıların numaraları sürümden sürüme değiştiği ve belgelenmediği için programlar API’yi kullanır. Tanenbaum 3e’de “yok” görünen link ve mount karşılıkları bugün mevcuttur.

Yapılar

İşletim Sistemi Yapıları: Genel Bakış

BasitMS-DOSMonolitikUNIX, LinuxModülerLinux LKM, SolarisHibritWindows NT, macOSMikroçekirdekMINIX 3, QNX, seL4ExokernelAegis / ExOS← çekirdek kipinde çok şeyçekirdek kipinde çok az şey →
Katmanlı yapı

Bir yerleşim değil, düzenleme ilkesidir: bileşenler hiyerarşik katmanlara ayrılır (THE, MULTICS halkaları).

Sanal makineler

Ayrı bir eksen: donanımın kendisi sanallaştırılır, üzerinde birden çok işletim sistemi çalışır.

Yapılar

Basit Yapı: MS-DOS

Uygulama programıYerleşik sistem programıMS-DOS aygıt sürücüleriROM BIOS aygıt sürücülerikatmanatlama
  • Belirgin bir yapısı yoktur: küçük, basit ve sınırlı donanım için yazılmıştır.
  • Arayüzler ve işlev düzeyleri iyi ayrılmamıştır; uygulamalar BIOS rutinlerine ve donanıma doğrudan erişebilir.
  • Intel 8088’de çift kip olmadığından donanım koruması yoktu: tek bir hatalı program tüm sistemi çökertebilir.
  • Modüller arasında net sınır ve veri gizleme (data hiding) yoktur.
  • Silberschatz bunu “basit yapı” olarak, monolitik çekirdeklerden ayrı ele alır.

Yapılar

Monolitik Sistem

Tüm işletim sistemi, çekirdek kipinde çalışan tek bir program olarak bağlanır. Her prosedür diğerini doğrudan çağırabilir.

  1. Ana program: çağrı numarasına bakıp istenen hizmet prosedürünü başlatır.
  2. Hizmet prosedürleri: her sistem çağrısını gerçekleştirir.
  3. Yardımcı prosedürler: birden çok hizmetin ortak işleri (ör. kullanıcı belleğinden veri almak).

Çoğu monolitik çekirdek bugün sürücüleri ve dosya sistemlerini çalışma anında yüklenebilir modül olarak da alır.

Ana prosedürhizmethizmethizmethizmetyard.yard.yard.yard.yard.hepsi tek ikili dosya, tek adres uzayı, çekirdek kipi

Yapılar

Geleneksel UNIX ve Linux: Monolitik Çekirdek

Kullanıcılarkabuklar, komutlar, derleyiciler, sistem kütüphanelerisistem çağrısı arayüzüÇekirdeksinyaller,terminal yönetimi,karakter G/Ç,terminal sürücüleridosya sistemi,takas, blok G/Ç,disk sürücüleriCPU zamanlama,sayfa değiştirme,sanal bellekçekirdek–donanım arayüzüterminaldenetleyicileriaygıtdenetleyicileribellekdenetleyicileri

Güçlü yönler

  • Doğrudan fonksiyon çağrıları: IPC ve kip geçişi yok, hızlı.
  • Tasarımı ve gerçeklemesi görece basit, bütünleşik.

Zayıf yönler

  • Tek bir sürücü hatası tüm çekirdeği çökertebilir.
  • Dev kod tabanı (Linux 2025’te 40 milyon satırı aştı): hata bulmak ve bakım zor.

Yapılar

Katmanlı Yapı

0İşlemci tahsisi, çoklu programlama

Katman 0: kesmelerde ve zamanlayıcı dolunca süreçler arasında geçiş yapar; üstteki katmanlar tek CPU’yu düşünmek zorunda kalmaz.

0İşlemci tahsisi, çoklu programlama1Bellek ve tambur yönetimi

Katman 1: süreçlere bellek ayırır, sayfaları tambur (o günün diski) ile bellek arasında taşır.

0İşlemci tahsisi, çoklu programlama1Bellek ve tambur yönetimi2Operatör–süreç iletişimi

Katman 2: her süreç ile operatör konsolu arasındaki iletişimi yönetir.

0İşlemci tahsisi, çoklu programlama1Bellek ve tambur yönetimi2Operatör–süreç iletişimi3G/Ç yönetimi

Katman 3: G/Ç aygıtlarını yönetir; üst katmanlar soyut aygıtlarla çalışır.

0İşlemci tahsisi, çoklu programlama1Bellek ve tambur yönetimi2Operatör–süreç iletişimi3G/Ç yönetimi4Kullanıcı programları

Katman 4: kullanıcı programları; bellek, konsol ve G/Ç ayrıntılarıyla uğraşmaz.

0İşlemci tahsisi, çoklu programlama1Bellek ve tambur yönetimi2Operatör–süreç iletişimi3G/Ç yönetimi4Kullanıcı programları5Operatör

Katman 5: sistem operatörü. Dijkstra’nın THE sistemi (1968) bu altı katmandan oluşuyordu.

OS katmanlara bölünür: en alt katman donanıma, en üst katman kullanıcıya en yakındır. Her katman yalnızca altındakilerin hizmetlerini kullanır.

Artılar

  • Hata ayıklama ve doğrulama katman katman yapılır; hata ilgili katmanda aranır.
  • Soyutlama ve veri gizleme kolaydır.

Eksiler

  • Katmanları doğru tanımlamak zordur (bağımlılıklar çoğu kez iki yönlüdür).
  • Her katman geçişi ek yük getirir. Fikir bugün ağ yığınlarında yaşar.

Yapılar

Mikroçekirdek (Microkernel)

  • Gerekli olmayan her şey çekirdekten çıkarılır; çekirdekte yalnızca IPC (mesaj aktarımı), temel zamanlama, adres uzayı yönetimi ve kesme işleme kalır.
  • Sürücüler, dosya sistemleri ve ağ yığını kullanıcı kipinde sunucu süreçler olarak çalışır; yeni hizmetler kullanıcı alanına eklenir, çekirdek değişmez.
  • Örnekler: MINIX 3, QNX Neutrino (otomotiv), L4 ailesi, biçimsel olarak doğrulanmış seL4. macOS ise saf mikroçekirdek değil, hibrit XNU’dur.
  • Mekanizma çekirdekte, politika dışarıda: çekirdek öncelikli süreçleri çalıştırmayı sağlar; önceliklerin nasıl atanacağına kullanıcı kipindeki bileşen karar verir.

Artılar

  • Çöken sürücü sistemi düşürmez, yeniden başlatılabilir.
  • Küçük çekirdek: test, doğrulama ve taşıma kolay.
  • Daha güvenli: saldırı yüzeyi küçük.

Eksiler

  • Mesajlar ve kip geçişleri ek yük getirir; L4 tasarımları bunu büyük ölçüde azalttı.

Yapılar

Mikroçekirdekte Bir Dosya Okuma

kullanıcı kipiçekirdek kipiUygulama programıDosya sistemiAygıt sürücüsüIPC (mesaj aktarımı)Bellek yönetimiCPU zamanlamaDonanımmesaj: oku(dosya)

Uygulama, dosya sistemi sunucusuna bir mesaj gönderir; mesaj çekirdeğin IPC mekanizmasından geçer.

kullanıcı kipiçekirdek kipiUygulama programıDosya sistemiAygıt sürücüsüIPC (mesaj aktarımı)Bellek yönetimiCPU zamanlamaDonanım

Çekirdek mesajı, kullanıcı kipindeki dosya sistemi sunucusuna teslim eder.

kullanıcı kipiçekirdek kipiUygulama programıDosya sistemiAygıt sürücüsüIPC (mesaj aktarımı)Bellek yönetimiCPU zamanlamaDonanım

Dosya sistemi hangi bloğun okunacağını bulur ve yine çekirdek üzerinden disk sürücüsüne mesaj yollar.

kullanıcı kipiçekirdek kipiUygulama programıDosya sistemiAygıt sürücüsüIPC (mesaj aktarımı)Bellek yönetimiCPU zamanlamaDonanımyanıt

Sürücü, çekirdeğin izin verdiği G/Ç ile donanıma erişir; yanıtlar aynı yoldan döner. Monolitik çekirdekte bu iş tek bir fonksiyon çağrı zinciridir.

Yapılar

MINIX 3: Bir Mikroçekirdek Örneği

Kullanıcı süreçleriKabukMakeDerleyici…DiğerSunucu süreçleriFSPM (süreç)RSAğDiğerSürücü süreçleriDiskTTYAğ kartıYazıcıDiğerÇekirdek kipiMikroçekirdek: kesmeler, süreçler, zamanlama, IPCçekirdek görevleri: saat (clock), sistem (sys)
Reenkarnasyon sunucusu (RS)

Sürücülerin sağlığını denetler; çöken bir sürücüyü (ör. TTY) kullanıcı fark etmeden yeniden başlatır: kendini onaran sistem.

Bölünmüş ayrıcalık

Sürücü kullanıcı kipindedir; G/Ç portlarına yalnızca çekirdek çağrılarıyla, izin verilen ölçüde erişir. Hatalı bir sürücü belleği bozamaz.

Yapılar

İstemci–Sunucu Modeli

kullanıcı kipiçekirdek kipiİstemciSüreç sunucusuTerminal sunucusuDosya sunucusuBellek sunucusuMikroçekirdekmesaj

Mikroçekirdek üzerinde süreçler iki sınıfa ayrılır: hizmet isteyen istemciler ve hizmet veren sunucular. Haberleşme yalnızca mesajlarladır.

Makine 1İstemciÇekirdekMakine 2Dosya sunucusuÇekirdekMakine 3Süreç sunucusuÇekirdekMakine 4Terminal sunucusuÇekirdekAğmesaj

İstemci, mesajın yerelde mi yoksa ağdaki başka bir makinede mi işlendiğini bilmek zorunda değildir: model doğal olarak dağıtık sistemlere genişler (bugünün web ve mikroservis mimarileri).

Yapılar

Tanenbaum – Torvalds Tartışması (1992)

Andrew Tanenbaum: mikroçekirdek
  • “LINUX is obsolete” başlıklı iletisinde monolitik tasarımı 1970’lerin geride kalmış bir yaklaşımı olarak gördü.
  • Mikroçekirdek daha modüler, esnek, taşınabilir; bir bileşendeki hatanın verdiği zarar sınırlı.
  • Donanım hızlandıkça mesajlaşmanın ek yükü önemsizleşir.
Linus Torvalds: monolitik
  • Monolitik çekirdeğin tasarımı ve gerçeklemesi daha basit; doğrudan fonksiyon çağrıları daha hızlı.
  • Süreçler arası mesajlaşmaya gerek yok; pratikte çalışan kod önemli.
  • Açık kaynak geliştirme modeli Linux’un hızla gelişmesini sağladı.
Bugün iki taraf da kısmen haklı çıktı: Linux monolitik kaldı ama yüklenebilir modüller, kullanıcı alanı sürücüleri (FUSE, VFIO) ve eBPF ile esneklik kazandı; mikroçekirdekler ise güvenlik-kritik ve gömülü alanda (QNX, seL4) yaygınlaştı.

Yapılar

Modüler Yapı: Yüklenebilir Çekirdek Modülleri

  • Çekirdekte yalnızca temel bileşenler bulunur; diğer hizmetler açılışta veya çalışma anında modül olarak yüklenir (Linux LKM, FreeBSD, Solaris).
  • Katmanlıya benzer (tanımlı arayüzler) ama daha esnektir: her modül diğerini çağırabilir. Mikroçekirdeğe benzer ama mesaj gerekmez, modüller çekirdek kipinde çalışır.
dosya sistemleriaygıt sürücüleriağ protokolleriyürütülebilir biçimlerÇekirdek çekirdeğizamanlama, bellek, IPC

Açılışta çekirdek ve initramfs’teki gerekli modüller yüklüdür. lsmod yüklü modülleri listeler.

dosya sistemleriaygıt sürücüleriağ protokolleriyürütülebilir biçimlerÇekirdek çekirdeğizamanlama, bellek, IPCusb_storage + vfat

USB bellek takılır: udev olayı modprobe usb-storage ve vfat modüllerini (bağımlılıklarıyla) yükletir.

dosya sistemleriaygıt sürücüleriağ protokolleriyürütülebilir biçimlerÇekirdek çekirdeğizamanlama, bellek, IPCusb_storage + vfat

Modül kendini çekirdeğe kaydeder ve doğrudan fonksiyon çağrılarıyla çalışır: hızlı, ama izolasyon yoktur; hatalı modül çekirdeği çökertebilir.

dosya sistemleriaygıt sürücüleriağ protokolleriyürütülebilir biçimlerÇekirdek çekirdeğizamanlama, bellek, IPCusb_storage + vfat

Kullanım sayısı 0 olunca modprobe -r (veya rmmod) modülü bellekten çıkarır. Modüllerin çekirdek sürümüyle uyumlu olması gerekir.

Yapılar

Hibrit Çekirdek: Windows ve macOS

kullanıcı kipiçekirdek kipiUygulamalarOrtam alt sistemleri (Win32…)Sistem servislerintdll.dll: sistem çağrısı saplamaları (Nt… fonksiyonları)Yürütücü (Executive)G/Ç, bellek, süreç ve nesne yöneticileri,güvenlik başvuru izleyicisi, önbellekwin32k.sys (grafik)Aygıt sürücüleriÇekirdek (kernel): zamanlama, kesmeler, senkronizasyonHAL (donanım soyutlama katmanı)Donanım

Windows NT: mikroçekirdek fikirleri (alt sistemler, nesne/mesaj temelli tasarım) korunmuş, ama performans için yürütücü, grafik ve sürücüler çekirdek kipine alınmıştır.

kullanıcı kipiçekirdek kipiUygulamalarÇatılar: Cocoa / SwiftUI, Metal, Core …libSystem (libc, sistem çağrısı saplamaları)XNU çekirdeği (Darwin)MachIPC, zamanlama,sanal bellekBSDPOSIX, ağ, dosyasistemleri, güvenlikI/O Kitnesne yönelimlisürücü çatısıYeni sürücüler çekirdek dışına, kullanıcı alanındaki DriverKit’e taşınıyorDonanım (Apple silicon / x86-64)

macOS / iOS XNU: Mach mikroçekirdeği ile BSD katmanı aynı çekirdek adres uzayında birleşir: mikroçekirdeğin modülerliği + monolitik hız.

Yapılar

Exo-Çekirdek (Exokernel)

Web sunucusuLibOS:özel ağ / önbellekVeritabanıLibOS:özel bellek / diskPOSIX uygulamasıLibOS:ExOS (UNIX benzeri)Exokernel: yalnızca güvenli paylaştırma ve korumahangi disk bloğu / bellek sayfası / CPU dilimi kimin?disk bloklarıbellek sayfalarıCPU zaman dilimiağ kartı
  • MIT’de Engler ve Kaashoek’un araştırma mimarisi (1995): çekirdek Aegis, kütüphane OS ExOS. Ticari bir işletim sistemi değildir.
  • Yönetimi korumadan ayırır: çekirdek yalnızca kaynakların kime ait olduğunu izler; soyutlamaları (dosya, sanal bellek) uygulama düzeyindeki LibOS’lar sağlar.
  • Uygulamaya özgü bellek yönetimi ve önbellekleme ile yüksek başarım; ama uygulama geliştirmek karmaşıktır. Fikir bugün unikernel’lerde ve DPDK / SPDK gibi çekirdeği atlayan G/Ç’de yaşar.

Yapılar

Yapıların Karşılaştırılması

YapıÇekirdekte ne var?Güçlü yönZayıf yönÖrnek
Basither şey, sınırsızküçük, basitkoruma yokMS-DOS
Monolitiktüm servislerhızhata yalıtımı yokUNIX, Linux
Katmanlıhiyerarşik katmanlardoğrulama kolayek yük, tanım zorTHE, MULTICS
MikroçekirdekIPC, zamanlama, bellekgüvenilirlikmesaj ek yüküMINIX 3, QNX, seL4
Modülerçekirdek + modülleresneklik, hızmodül = tam yetkiLinux, FreeBSD
Hibritmikro + seçili servislerdengekarmaşıklıkWindows, macOS
Exokernelyalnızca korumauygulamaya özgü hızgeliştirme zorAegis/ExOS

Gerçek sistemler saf değildir: Linux monolitik + modüler, Windows ve macOS hibrittir; hemen hepsi bir ölçüde katmanlıdır.

Sanal Makineler

Sanal Makine Kavramı

  • Hipervizör (VMM), tek bir fiziksel donanım üzerinde her biri bağımsız bir bilgisayar gibi görünen sanal makineler oluşturur.
  • Her konuk OS kendi CPU’su, RAM’i, diski ve G/Ç aygıtları olduğuna inanır; farklı işletim sistemleri aynı donanımda eş zamanlı çalışabilir.
  • Fikir IBM VM/370’e (1972) dayanır; bugün bulut bilişimin temelidir: sunucu birleştirme, yalıtım, anlık görüntü, canlı taşıma.
süreçsüreçsüreçÇekirdekdonanıma doğrudan erişirDonanımsüreçlerçekirdekVM1süreçlerçekirdekVM2süreçlerçekirdekVM3Sanal makine yöneticisi (hipervizör)Donanım(a) Sanal olmayan makine(b) Sanal makineler

Sanal Makineler

Hipervizör Türleri

süreçlersüreçlerWindowsLinuxTip 1 hipervizör(çekirdek kipinde,doğrudan donanımda)Donanım(a) Tip 1konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSDonanım(b) Saf tip 2konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSkvm.ko /vboxdrvDonanım(c) Pratik tip 2

Tip 1 (bare-metal): hipervizör doğrudan donanımda, en ayrıcalıklı kipte çalışır; konuk OS’lar onun üzerindedir. Veri merkezlerinin standart çözümüdür.

süreçlersüreçlerWindowsLinuxTip 1 hipervizör(çekirdek kipinde,doğrudan donanımda)Donanım(a) Tip 1konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSDonanım(b) Saf tip 2konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSkvm.ko /vboxdrvDonanım(c) Pratik tip 2

Saf tip 2: hipervizör, ana makine OS’u üzerinde sıradan bir süreçtir; konuk komutlarını yorumlar veya ikili çeviriyle çalıştırır (ör. KVM’siz QEMU). Esnek ama yavaştır.

süreçlersüreçlerWindowsLinuxTip 1 hipervizör(çekirdek kipinde,doğrudan donanımda)Donanım(a) Tip 1konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSDonanım(b) Saf tip 2konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSkvm.ko /vboxdrvDonanım(c) Pratik tip 2

Pratik tip 2: hipervizör yine bir uygulamadır, ancak ana OS’a yüklenen bir çekirdek modülü sayesinde donanım destekli sanallaştırmayı (Intel VT-x, AMD-V, ARM EL2) kullanır.

süreçlersüreçlerWindowsLinuxTip 1 hipervizör(çekirdek kipinde,doğrudan donanımda)Donanım(a) Tip 1konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSDonanım(b) Saf tip 2konuk süreçKonuk OSTip 2 hip.(süreç)anamakinesüreçleriAna makine OSkvm.ko /vboxdrvDonanım(c) Pratik tip 2

Sınırlar bulanıklaştı: KVM, Linux çekirdeğinin kendisini tip 1 hipervizöre dönüştürür; Hyper-V etkinleşince Windows bile bir kök bölümde (VM) çalışır.

Sanal Makineler

Tip 1 ve Tip 2 Hipervizörler

Tip 1: “bare-metal”
  • İşletim sisteminden bağımsız, doğrudan donanım üzerinde çalışır.
  • Fiziksel sunucuları sanal makinelere bölmek, kaynakları verimli kullanmak ve izlemek için.
  • VMware ESXi: kurumsal veri merkezleri.
  • Microsoft Hyper-V: Windows Server rolü (ayrı ücretsiz “Hyper-V Server” 2019’dan sonra sürdürülmedi).
  • Xen (XCP-ng) ve KVM: açık kaynak; büyük bulutların (AWS Nitro, Google Cloud) temeli KVM’dir.
Tip 2: “hosted”
  • Bir ana makine işletim sistemi üzerinde uygulama olarak çalışır.
  • Kişisel bilgisayarlarda deneme, eğitim ve geliştirme ortamları için.
  • Oracle VirtualBox: ücretsiz, açık kaynak, çok platformlu.
  • VMware Workstation Pro / Fusion: 2024’ten beri ücretsiz.
  • Parallels Desktop ve UTM (QEMU): macOS üzerinde.
  • G/Ç yolu ana OS’tan geçtiği için ek yük daha fazladır; donanım desteğiyle CPU farkı küçüktür.

Sanal Makineler

Sanal Makine mi, Konteyner mi?

UygulamakütüphanelerKonuk OSUygulamakütüphanelerKonuk OSUygulamakütüphanelerKonuk OSHipervizörDonanımUygulamakütüphanelerUygulamakütüphanelerUygulamakütüphanelerKonteyner çalışma zamanıAna OS çekirdeği (namespaces, cgroups)DonanımSanal makineler: her biri kendi çekirdeğiyleKonteynerler: tek çekirdek paylaşılır
Konteyner

OS düzeyinde sanallaştırma: süreçler namespaces ile yalıtılır, cgroups ile sınırlanır. Saniyenin altında başlar (Docker, Podman, Kubernetes).

Sanal makine

Tam yalıtım, farklı OS çalıştırabilir; ama her VM kendi çekirdeğini ve belleğini taşır.

Ara çözümler

Firecracker microVM, Kata Containers, gVisor; WSL 2 da hafif bir Hyper-V VM’inde gerçek Linux çekirdeği çalıştırır.

Donanım ve Yapı

Simetrik Çok İşlemcili ve Çok Çekirdekli Mimari

CPU0yazmaçlarönbellekCPU1yazmaçlarönbellekCPU2yazmaçlarönbellekveri yoluAna bellek (paylaşılan)

SMP: her CPU kendi yazmaçlarına ve önbelleğine sahiptir, belleği paylaşır; hepsi OS dâhil her işi yapabilir. Çekirdek veri yapıları kilitlerle korunmalıdır (Linux’un “büyük çekirdek kilidi” 2011’de tamamen kaldırıldı).

tek yongaÇekirdek 0yazmaçlarL1 önbellekÇekirdek 1yazmaçlarL1 önbellekL2 / L3 önbellek (paylaşılan)Ana bellek

Çok çekirdekli yonga: çekirdekler aynı yongada, yakın önbellek paylaşımıyla daha hızlı ve az enerjiyle haberleşir. 2026’da yaygın olan P/E (performans/verimlilik) çekirdekleri zamanlayıcıya yeni görevler yükler.

Bağlama ve Açılış

Derleme, Bağlama ve Yükleme

main.cDerleyicigcc -cmain.onesne dosyasıdiğer .o,libm.aBağlayıcıldprogramçalıştırılabilirYükleyiciexecve + ld.solibc.so.6paylaşılanbellekteki süreç(çalışıyor)

Derleyici kaynak kodu yeniden konumlandırılabilir nesne dosyasına çevirir: adresler henüz kesin değildir, dış semboller (ör. printf) çözülmemiştir.

main.cDerleyicigcc -cmain.onesne dosyasıdiğer .o,libm.aBağlayıcıldprogramçalıştırılabilirYükleyiciexecve + ld.solibc.so.6paylaşılanbellekteki süreç(çalışıyor)

Bağlayıcı nesne dosyalarını ve statik kütüphaneleri birleştirir, sembolleri çözer, adresleri düzeltir ve çalıştırılabilir dosya üretir.

main.cDerleyicigcc -cmain.onesne dosyasıdiğer .o,libm.aBağlayıcıldprogramçalıştırılabilirYükleyiciexecve + ld.solibc.so.6paylaşılanbellekteki süreç(çalışıyor)

Kabuk execve çağırır; çekirdekteki yükleyici dosyanın başlığını okur, kesimleri adres uzayına eşler ve dinamik bağlayıcıyı (ld-linux.so) başlatır.

main.cDerleyicigcc -cmain.onesne dosyasıdiğer .o,libm.aBağlayıcıldprogramçalıştırılabilirYükleyiciexecve + ld.solibc.so.6paylaşılanbellekteki süreç(çalışıyor)

Paylaşılan kütüphaneler (libc.so.6) çalışma anında bağlanır ve süreçler arasında paylaşılır. Biçimler OS’a özgüdür: ELF (Linux), PE (Windows), Mach-O (macOS); bu yüzden programlar OS’lar arasında doğrudan taşınamaz.

Bağlama ve Açılış

İşletim Sisteminin Açılışı (Boot)

Açılış, çekirdeği belleğe yükleyip ilk kullanıcı sürecini başlatana kadar geçen süreçtir. Linux’ta systemd-analyze her aşamanın süresini gösterir.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdCPU sabit bir adresten ürün yazılımını çalıştırmaya başlar.

Güç verilince CPU sıfırlanır ve kalıcı bellekteki ürün yazılımına atlar.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdPOST ile donanım sınanır ve ilklenir; EFI sistem bölümündeki önyükleyici bulunur.Secure Boot her aşamanın imzasını doğrular.

UEFI donanımı ilkler; GPT diskteki EFI sistem bölümünden (FAT32) önyükleyiciyi yükler.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdÖnyükleyici çekirdek seçimini sunar, çekirdeği ve initramfs’i belleğe yükler.Eski sistemler: BIOS + MBR.

Önyükleyici menü sunar; seçilen çekirdeği ve başlangıç RAM diskini (initramfs) belleğe koyar ve çekirdeğe atlar.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdÇekirdek kendini açar, donanımı tanır, sürücüleri yükler;initramfs geçici bir kök dosya sistemi sağlar.

Çekirdek bellek yönetimini, zamanlayıcıyı ve sürücüleri başlatır; initramfs içindeki betikler gerekli modülleri yükler.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdGerçek kök dosya sistemi (ör. şifreli disk açılarak) bağlanır.

Gerçek kök dosya sistemi bağlanır ve initramfs bırakılır.

Güç /sıfırlamaUEFIürün yazılımıÖnyükleyiciGRUB 2 /systemd-bootÇekirdek+ initramfsKök FSbağlanırPID 1systemdİlk kullanıcı süreci başlar; servisleri paralel başlatır ve giriş ekranını açar.

Çekirdek PID 1’i (systemd) başlatır; o da servisleri, ağı ve giriş ekranını açar. Bundan sonra her süreç PID 1’in soyundandır.

Özet

Kontrol Soruları

  1. Kullanıcı kipinde çalışan bir program neden G/Ç komutlarını doğrudan çalıştıramaz? Denerse ne olur?
  2. printf ile write arasındaki fark nedir? Hangisi sistem çağrısıdır?
  3. fork() neden “bir kez çağrılır, iki kez döner”? Atada ve çocukta dönüş değerleri nedir?
  4. Mikroçekirdekte bir sürücü çökerse ne olur? Monolitik çekirdekte?
  5. Linux’un yüklenebilir modülleri onu mikroçekirdek yapar mı? Neden?
  6. Tip 1 ve tip 2 hipervizörü ayırt eden nedir? KVM nereye konur?
Cevapları göster
  1. G/Ç ayrıcalıklı komuttur; mod biti 1 iken donanım tuzak üretir, OS süreci sonlandırır (koruma).
  2. printf kullanıcı kipinde biçimleyen kütüphane fonksiyonudur; gerektiğinde write sistem çağrısını yapar.
  3. Çağrıdan sonra iki süreç vardır ve ikisi de aynı noktadan devam eder: atada çocuğun PID’si, çocukta 0 (hata: −1).
  4. Mikroçekirdekte yalnızca o sunucu süreci çöker, yeniden başlatılabilir; monolitikte tüm çekirdek çökebilir.
  5. Hayır: modüller çekirdek kipinde ve aynı adres uzayında çalışır, mesajla değil fonksiyon çağrısıyla haberleşir.
  6. Tip 1 doğrudan donanımda, tip 2 bir ana OS üzerinde çalışır. KVM çekirdeği hipervizöre dönüştürdüğü için genelde tip 1 sayılır.

Özet

Kaynaklar

  • Silberschatz, Galvin ve Gagne, Operating System Concepts, 10. baskı, Wiley, 2018 (Bölüm 2 ve 18).
  • Tanenbaum ve Bos, Modern Operating Systems, 4. baskı, Pearson, 2014 (Bölüm 1.5–1.7 ve 7).
  • Arpaci-Dusseau ve Arpaci-Dusseau, Operating Systems: Three Easy Pieces (OSTEP), sürüm 1.10, pages.cs.wisc.edu/~remzi/OSTEP.
  • Linux man sayfaları: syscalls(2), syscall(2), fork(2), pipe(7), mount(8).
  • Engler, Kaashoek ve O’Toole, “Exokernel: An Operating System Architecture for Application-Level Resource Management”, SOSP 1995.

Son

Bölüm 2: İşletim Sistemi Yapıları
Sonraki bölüm: Süreçler
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.