From 4a66c14a67b84a97535561e563df478dbf7b2627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20K=C4=B1l=C4=B1=C3=A7?= Date: Sun, 23 Aug 2026 00:32:17 +0300 Subject: [PATCH 1/2] docs: 00-giris/on-gereksinimler.md notu --- 00-giris/README.md | 2 +- 00-giris/on-gereksinimler.md | 185 +++++++++++++++++++++++++++++++++++ TERIMLER.md | 6 ++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 00-giris/on-gereksinimler.md diff --git a/00-giris/README.md b/00-giris/README.md index 4015100..72865f9 100644 --- a/00-giris/README.md +++ b/00-giris/README.md @@ -10,7 +10,7 @@ Bu bölüm, sonraki bölümlerde anlatılan konuları denemek için gereken çal | --- | --- | --- | | OSDev nedir, neyi kapsar | [osdev-nedir.md](osdev-nedir.md) | ✅ | | Nereden başlanır: yol haritası | [yol-haritasi.md](yol-haritasi.md) | ✅ | -| Ön gereksinimler (C, assembly, bilgisayar mimarisi) | `on-gereksinimler.md` | ⬜ | +| Ön gereksinimler (C, assembly, bilgisayar mimarisi) | [on-gereksinimler.md](on-gereksinimler.md) | ✅ | | Geliştirme ortamı kurulumu (Linux / WSL) | `gelistirme-ortami.md` | ⬜ | | Cross-compiler hazırlama (GCC, Clang) | `cross-compiler.md` | ⬜ | | Build sistemi: Make ve alternatifleri | `build-sistemi.md` | ⬜ | diff --git a/00-giris/on-gereksinimler.md b/00-giris/on-gereksinimler.md new file mode 100644 index 0000000..fbfd57d --- /dev/null +++ b/00-giris/on-gereksinimler.md @@ -0,0 +1,185 @@ +# Ön gereksinimler + +OSDev'e başlamak için gereken bilgi tek bir dile veya tek bir konuya sığmaz. Kernel yazan kişi aynı anda üç düzlemde çalışır: kodu yazdığı dil (çoğunlukla C ve assembly), kodun üzerinde çalıştığı donanım modeli ve kaynağı çalıştırılabilir bir imaja dönüştüren araç zinciri. Bu üç düzlemden birindeki boşluk, çoğu zaman diğer ikisinde anlaşılmayan bir hata olarak görünür. + +Bu not, o üç düzlemde nelerin gerçekten gerekli olduğunu ayırır. Amaç bir okuma listesi vermek değil, hangi konunun hangi somut probleme karşılık geldiğini göstermektir: `volatile` bilmemek sürücü yazarken, struct hizalaması bilmemek tanımlayıcı tablo kurarken, çağrı kuralını bilmemek ilk interrupt handler'da karşınıza çıkar. + +## Ön koşullar + +- [OSDev nedir](osdev-nedir.md) + +## Ne kadarı yeterli + +Ön gereksinimlerin tamamını başlamadan önce öğrenmek gerekmez; böyle bir sıra pratikte işlemez de. Gereken şey uzmanlık değil bir eşiktir: bir mimari manual'ının ilgili bölümünü okuyup anlayabilmek ve kendi derleyicinizin ürettiği çıktıyı okuyabilmek. Bu iki yetenek elinizdeyse eksik kalan bilgiyi ihtiyaç anında tamamlayabilirsiniz. Bunlar yoksa, karşılaşılan her sorun kaynağı belirsiz bir tıkanmaya dönüşür. + +Aşağıdaki bölümler konuları bu eşiğe göre sıralar. Her başlığın sonunda o bilginin ilk hangi aşamada gerekeceği belirtilmiştir; aşamaların tanımı [yol haritası](yol-haritasi.md) notundadır. + +## C bilgisi + +Kernel'lerin büyük kısmı C ile yazılır. Kernel'de yazılan C, uygulama geliştirmede yazılan C'den iki noktada ayrılır: altta standart kütüphane yoktur ve yazılan kodun belleğe nasıl yerleştiği doğrudan önemlidir. + +**İşaretçiler ve bellek düzeni.** Bir adresi işaretçiye çevirmek, o adresteki baytları belirli bir struct gibi okumak ve işaretçi aritmetiğinin tip boyutuna göre ölçeklendiğini bilmek temel gereksinimdir. Tamsayı ile işaretçi arasındaki dönüşümlerde `uintptr_t` kullanılır; `int` bir adresi tutmak için yeterli değildir. + +**Sabit genişlikli tipler.** `int` ve `long` boyutları platforma ve veri modeline göre değişir. Donanımla konuşan her yapıda `stdint.h` içindeki `uint8_t`, `uint32_t`, `uint64_t` gibi tipler kullanılır. Bir sayfa tablosu girdisinin 64 bit olduğu bilgisi tipin adında görünmelidir. + +**Bit işlemleri.** Bayrak okuma, maskeleme ve kaydırma kernel kodunun günlük işidir. Kaydırmalarda işaretsiz sabit kullanmak gerekir: 32 bitlik bir `int` üzerinde `1 << 31` tanımsız davranıştır, doğrusu `1u << 31` veya 64 bit için `UINT64_C(1) << 63` biçimidir. Hizalama hesapları da bu gruba girer; bir adresi `n` sınırına yukarı hizalamak `(a + n - 1) & ~(n - 1)` ifadesiyle yapılır ve `n` ikinin kuvveti olmak zorundadır. + +**struct düzeni, hizalama ve dolgu.** Derleyici, struct alanlarının arasına hizalama için dolgu (padding) ekler. Donanımın beklediği bir yapıyı (tanımlayıcı tablo girdisi, boot protokolü yapısı, aygıt register bloğu) tanımlarken bu dolgu yapıyı bozar. `__attribute__((packed))` dolguyu kaldırır, ancak bu kez alanlar hizasız kalır: x86-64'te hizasız erişim çalışır fakat yavaştır, bazı mimarilerde ve aygıt belleğinde hata üretir. Daha sağlam yaklaşım, yapıyı donanımın istediği hizaya kendiliğinden oturacak biçimde tasarlamak ve boyutunu derleme zamanında `_Static_assert` ile doğrulamaktır. + +**`volatile` ve donanım erişimi.** Derleyici, sonucu kullanılmayan bir okumayı kaldırabilir veya art arda gelen erişimleri birleştirebilir. Aygıt register'ında erişimin kendisi bir yan etkidir; kaldırılamaz. + +```c +// Aygıt register'ı sabit bir adrese eşlenmiştir. +// volatile olmadan derleyici bu okumayı döngünün dışına taşıyabilir. +static volatile uint32_t *const durum = (volatile uint32_t *)0xFEE00020; + +while ((*durum & (1u << 12)) != 0) { + // aygıt hâlâ meşgul +} +``` + +`volatile` yalnızca derleyicinin bu erişimi kaldırmasını, birleştirmesini veya diğer `volatile` erişimlere göre yerini değiştirmesini engeller. İşlemci ve veri yolu tarafındaki sıralama için ayrıca bellek bariyeri gerekir; `volatile` atomiklik de sağlamaz. + +**Tanımsız davranış.** Uygulama kodunda "pratikte çalışan" tanımsız davranış, kernel'de optimizasyon seviyesi değiştiğinde kaybolan bir hataya dönüşür. En sık karşılaşılanlar: tip kuralını çiğneyen işaretçi dönüşümleri (strict aliasing), işaretli tamsayı taşması ve null işaretçi varsayımları. Kernel'de adres 0 map edilmiş olabildiği için derleyicinin "buraya erişilemez" çıkarımı da yanlış sonuç verir. Bu yüzden kernel derlemelerinde `-fno-strict-aliasing` ve `-fno-delete-null-pointer-checks` yaygın olarak kullanılır. + +**Freestanding C.** Standart iki uyum düzeyi tanımlar: hosted ve freestanding. Freestanding ortamda yalnızca kütüphane işlevi içermeyen başlıklar bulunur: `stddef.h`, `stdint.h`, `stdbool.h`, `limits.h`, `stdarg.h`, `float.h`, `stdalign.h`, `stdnoreturn.h` ve `iso646.h`. `printf` ve `malloc` yoktur, ihtiyaç duyulduğunda yazılır. Buna karşılık derleyici, kaynakta çağrı geçmese bile `memcpy`, `memset`, `memmove` ve `memcmp` çağrıları üretebilir; bu dört işlevi kernel'in sağlaması gerekir. + +**Bağlantı (linkage) ve bağlayıcı sembolleri.** `static` ve `extern` anahtar sözcüklerinin sembol görünürlüğüne etkisi, kodu belirli bir bölüme yerleştiren `section` özniteliği ve bağlayıcı betiğinde tanımlanan sembollerin C tarafından nasıl okunacağı bilinmelidir. Bağlayıcı sembolünün değeri değil adresi anlamlıdır; bu yüzden dizi tipiyle tanımlanır: + +```c +// Bağlayıcı betiğinde tanımlanmış sembol. +extern char _kernel_sonu[]; + +uintptr_t ilk_bos_adres = (uintptr_t)_kernel_sonu; +``` + +**Inline assembly.** GCC ve Clang'ın genişletilmiş `asm` söz dizimi; çıkış ve giriş kısıtları, bozulan register'ların (clobber) bildirilmesi ve `"memory"` clobber'ının anlamı. Port I/O, `cpuid`, control register erişimi ve bariyerler bu yolla yazılır. + +Bu başlıkların çoğu Aşama 1'den itibaren gerekir; `volatile` ve inline assembly ilk sürücüde, bağlayıcı sembolleri ilk bellek yöneticisinde karşınıza çıkar. + +## Assembly bilgisi + +Assembly'yi baştan sona yazabilmek gerekmez. Gereken şey okuyabilmek ve gerektiğinde kısa parçalar yazabilmektir. Kernel'in assembly ile yazılması zorunlu olan kısımları sınırlıdır ama atlanamaz: boot girişi, interrupt giriş kodu, context switch, tanımlayıcı tablo yükleme (`lgdt`, `lidt`), adres alanı değiştirme (`mov cr3`) ve kullanıcı moduna geçiş (`iretq`, `sysretq`). + +**İşlemci modeli.** x86-64'te 16 genel amaçlı register, `rip`, `rflags`, control register'lar (`cr0`, `cr2`, `cr3`, `cr4`) ve MSR'ler (Model Specific Register). Bu register'ların hangisinin ne işe yaradığını bilmek, disassembly okumanın ön şartıdır. + +**Söz dizimi farkları.** GAS varsayılan olarak AT&T söz dizimini, NASM Intel söz dizimini kullanır. İkisinde işlenen sırası terstir. Hangi söz diziminde çalıştığınızı bilmek ve okuduğunuz örneğin hangisiyle yazıldığını ayırt etmek gerekir. + +**Çağrı kuralı.** C ile assembly'nin birbirini çağırabilmesi bir ABI (Application Binary Interface) sözleşmesine dayanır. x86-64 üzerinde System V ABI'de tamsayı argümanları sırasıyla `rdi`, `rsi`, `rdx`, `rcx`, `r8` ve `r9` register'larından geçer, dönüş değeri `rax`'tedir. `rbx`, `rbp` ve `r12`–`r15` çağrılan tarafından korunur. `call` anında yığın 16 bayta hizalı olmalıdır. + +Aynı ABI'nin kernel'i doğrudan ilgilendiren bir ayrıntısı daha vardır: `rsp`'nin altındaki 128 baytlık red zone. Yaprak fonksiyonlar bu alanı yığın işaretçisini değiştirmeden kullanabilir. Bir interrupt geldiğinde işlemci ve handler bu alanın üzerine yazar. Bu yüzden kernel kodu `-mno-red-zone` ile derlenir. + +```asm +; NASM söz dizimi. Interrupt girişinde işlemci yalnızca bir kısım bilgiyi +; yığına iter; kalan register'ları saklamak handler'ın işidir. +isr_ortak: + push rax + push rcx + ; ... diğer register'ların itilmesi atlandı + mov rdi, rsp ; System V ABI: ilk argüman rdi + call interrupt_isle + ; ... register'ların geri yüklenmesi atlandı + iretq +``` + +Örnek yalnızca argüman geçişini göstermek için kısaltılmıştır. Eksiksiz bir giriş kodunun tüm genel amaçlı register'ları saklaması, hata kodu iten ve itmeyen vektörleri ayırması ve segment register'larını ele alması gerekir. + +**System call kuralı.** `syscall` komutu `rcx` ve `r11` register'larını kendisi kullandığı için Linux'un x86-64 system call arayüzünde dördüncü argüman `rcx` yerine `r10`'dan geçirilir. Bu, çağrı kuralının donanım tarafından şekillendirildiği tipik bir örnektir. + +Assembly Aşama 1'den itibaren gerekir ve Aşama 4'te, context switch yazılırken zorunlu hale gelir. + +## Bilgisayar mimarisi bilgisi + +Kernel donanımın davranışını varsayamaz; ölçüt her zaman mimari manual'ıdır. Aşağıdaki kavramların en azından tanımını bilerek başlamak gerekir, ayrıntıları ilgili bölümlerde ele alınır. + +**Ayrıcalık seviyeleri ve mod geçişleri.** Kullanıcı modu ile kernel modu arasındaki ayrımın donanım tarafından zorlandığı, geçişin yalnızca belirli kapılardan (interrupt, exception, system call komutu) yapılabildiği. + +**Bellek hiyerarşisi.** Register, önbellek, ana bellek ve disk arasındaki erişim maliyeti farkı. Önbellek satırı kavramı ve hizalamanın performansla ilişkisi. + +**Sanal bellek ve MMU.** Sanal adresin fiziksel adrese çevrildiği, çevirinin sayfa tablolarıyla tanımlandığı ve TLB'nin (Translation Lookaside Buffer) bu çevirileri önbelleklediği. Sayfa tablosu değiştiğinde TLB'nin geçersiz kılınması gerektiği. + +**Interrupt mekanizması.** Aygıtın sinyal ürettiği, işlemcinin çalışan kodu keserek bir tablodaki adrese daldığı ve dönüşte önceki bağlamı geri yüklediği. + +**G/Ç yöntemleri.** x86'da ayrı bir G/Ç adres alanına erişen port I/O (`in`, `out`) ile aygıt register'larının bellek adreslerine eşlendiği MMIO (Memory-Mapped I/O) ayrımı. ARM64 ve RISC-V'de yalnızca MMIO vardır. + +**Bayt sıralaması ve hizalama.** x86-64 küçük endian çalışır; ARM64 yapılandırılabilir olsa da pratikte küçük endian kullanılır. Aygıt ve dosya sistemi formatlarında sıralamanın açıkça belirtilmesi gerekir. + +**Atomiklik ve bellek sıralaması.** Çok çekirdekli bir sistemde belleğe yapılan erişimlerin programda yazıldığı sırayla görünmeyebileceği. x86-64 görece güçlü bir sıralama modeli sunar, ARM64 zayıf sıralamalıdır ve bariyer kullanımı zorunludur. Bu konu Aşama 4'e kadar ertelenebilir, ancak ilk spinlock yazıldığı an gerekli hale gelir. + +**Sayı sistemleri.** Onaltılık gösterim, ikinin tümleyeni ve bit alanlarının okunması. Manual'lardaki tabloların tamamı bu gösterimle yazılmıştır. + +## Araç zinciri ve bağlayıcı bilgisi + +Kernel geliştirmede yaşanan ilk sorunların önemli bir kısmı kernel kodunda değil, derleme ve bağlama aşamasında çıkar. Bu yüzden araç zincirinin ne yaptığını bilmek ön gereksinimdir. + +- **Derleme aşamaları.** Ön işleme, derleme, assembly ve bağlama adımlarının ayrı ayrı ne ürettiği. +- **Nesne dosyası ve semboller.** Sembol tablosu, tanımlı ve tanımsız semboller, yer değiştirme (relocation) kayıtları. +- **ELF formatı.** Bölümler (`.text`, `.rodata`, `.data`, `.bss`), program başlıkları ve giriş noktası. `.bss` bölümünün dosyada yer kaplamadığı, yalnızca boyutuyla tanımlandığı. +- **Bağlayıcı betiği.** Bölümlerin bellekte nereye yerleşeceğini belirleyen `SECTIONS` bloğu, konum sayacı ve yükleme adresi (LMA) ile çalışma adresi (VMA) ayrımı. Higher-half kernel'lerde bu ayrım doğrudan işlevseldir. +- **Make.** Hedef, bağımlılık ve kural üçlüsü. Ayrıntı `build-sistemi.md` notundadır. +- **İnceleme araçları.** `objdump -d`, `readelf -S`, `nm` ve `addr2line`. Bir çökme adresini kaynak satırına geri götürebilmek, hata ayıklamanın temel becerisidir. + +Bu grup Aşama 0'da gerekir; ayrıntısı `cross-compiler.md` ve `build-sistemi.md` notlarındadır. + +## İşletim sistemi kavramları + +Kernel yazmadan önce işletim sistemi teorisini bilmek zorunlu değildir, ancak kavramların adını bilmek okunan kaynakları anlamlı kılar: process ve thread ayrımı, zamanlama, eşzamanlılık ve yarış durumu, karşılıklı dışlama ve deadlock, sanal bellek, dosya sistemi modeli. Bu kavramların tamamı *Operating Systems: Three Easy Pieces* kitabında ücretsiz olarak bulunabilir ve bu notlarla paralel okunabilir. + +Teori ile implementasyon arasındaki fark küçümsenmemelidir. Kitapta bir paragrafla anlatılan context switch, gerçekte doğru sırayla yazılması gereken bir assembly rutinidir. + +## Gerekmeyenler + +Alanın zorluğu hakkındaki yaygın kanılar, gereğinden uzun bir hazırlık aşamasına yol açar. Aşağıdakiler ön gereksinim değildir: + +- **C uzmanı olmak.** Yukarıdaki başlıklar C'nin tamamını değil, kernel'de kullanılan alt kümesini kapsar. +- **Assembly'yi baştan yazabilmek.** Okumak ve kısa rutinler yazabilmek yeterlidir. +- **Elektronik veya donanım tasarımı bilmek.** Bir aygıtla konuşmak için gereken bilgi, aygıtın veri sayfasında yazılıdır. +- **C kullanmak zorunda olmak.** Rust (`no_std`), Zig ve C++'ın freestanding alt kümesiyle de kernel yazılabilir. Bu durumda dilin kendi kısıtları (Rust'ta `core`, panic handler ve `unsafe` sınırları) ek bir öğrenme yükü getirir; buna karşılık bulunabilecek örneklerin çoğu C ile yazılmıştır. +- **İleri matematik.** Alan ağırlıklı olarak durum yönetimi ve dikkatli okuma gerektirir. +- **Belirli bir ders veya derece.** Gereken bilginin tamamı kamuya açık kaynaklarda mevcuttur. + +## Kendinizi sınamak için + +Aşağıdaki soruları yanıtlayabiliyorsanız eşiği geçmişsiniz demektir. Yanıtlayamadıklarınız, önce hangi konuya bakmanız gerektiğini gösterir. + +- İki `uint32_t` ve bir `uint8_t` alanı olan bir struct'ın boyutu neden 9 değil 12 bayttır? +- `volatile uint32_t *const p` ile `uint32_t *volatile p` arasındaki fark nedir? +- Bir adresi 4096 sınırına yukarı hizalayan ifadeyi bit işlemleriyle yazabiliyor musunuz? +- `objdump -d` çıktısında bir fonksiyonun ilk argümanının hangi register'dan geldiğini bulabiliyor musunuz? +- 64 bitlik bir sayfa tablosu girdisinde 12. bitin değerini okuyan ifadeyi yazabiliyor musunuz? +- `readelf -S` çıktısında `.bss` bölümü neden dosyada yer kaplamaz? +- Derleyicinin kendiliğinden ürettiği bir `memset` çağrısı, standart kütüphane olmayan bir ortamda neden bağlama hatası verir? + +## Sık yapılan hatalar + +- Her şeyi önceden öğrenmeye çalışmak. Eksik bilgi, ihtiyaç anında en hızlı öğrenilen bilgidir. +- Standart kütüphane alışkanlıklarını kernel'e taşımak. `printf` ve `malloc`, kullanılmadan önce yazılması gereken işlevlerdir. +- Tanımsız davranışı "çalışıyor" diye görmezden gelmek. Optimizasyon seviyesi veya derleyici sürümü değiştiğinde davranış da değişir. +- `int` ve `long` boyutlarını varsaymak. Donanım yapılarında sabit genişlikli tipler kullanılır. +- Derleyicinin ürettiği koda hiç bakmamak. Disassembly okumak çoğu zaman kaynağa bakmaktan daha hızlı sonuç verir. +- Assembly'yi tamamen atlamak. Kernel'in assembly ile yazılması zorunlu kısmı küçüktür, ancak atlanamaz. +- Yalnızca öğretici takip edip manual'a hiç bakmamak. Öğretici bir yolu gösterir, manual ölçütü tanımlar. + +## İlgili notlar + +- [OSDev nedir](osdev-nedir.md) — alanın kapsamı ve temel kavramlar +- [Nereden başlanır: yol haritası](yol-haritasi.md) — aşamaların tanımı ve sırası +- [01 — Mimari](../01-mimari/) — işlemci modeli, register'lar ve ayrıcalık seviyeleri +- [03 — Assembly](../03-assembly/) — söz dizimi, çağrı kuralı ve inline assembly +- [Terimler sözlüğü](../TERIMLER.md) — terim kullanımı + +## Kaynaklar + +- ISO/IEC 9899:2018 (C17), Bölüm 4 — Conformance (freestanding ortam tanımı ve zorunlu başlıklar) +- Brian W. Kernighan, Dennis M. Ritchie, *The C Programming Language*, 2. baskı +- System V Application Binary Interface — AMD64 Architecture Processor Supplement, Sürüm 1.0, Bölüm 3.2 (Function Calling Sequence); (erişim: 22 Ağustos 2026) +- GCC dokümantasyonu, "How to Use Inline Assembly Language in C Code"; (erişim: 22 Ağustos 2026) +- Intel® 64 and IA-32 Architectures Software Developer's Manual, Cilt 1, Bölüm 3 — Basic Execution Environment +- Intel® 64 and IA-32 Architectures Software Developer's Manual, Cilt 3A, Bölüm 8.2 — Memory Ordering +- Arm® Architecture Reference Manual for A-profile architecture, Bölüm B2 — The AArch64 Application Level Memory Model +- Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification, Sürüm 1.2, Bölüm 1 — Object Files +- GNU Binutils dokümantasyonu, "Using ld" — Scripts; (erişim: 22 Ağustos 2026) +- John R. Levine, *Linkers and Loaders*, Bölüm 3 — Object Files +- Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau, *Operating Systems: Three Easy Pieces*; (erişim: 22 Ağustos 2026) +- David A. Patterson, John L. Hennessy, *Computer Organization and Design*, 5. baskı, Bölüm 2 — Instructions: Language of the Computer +- OSDev Wiki, "Required Knowledge"; (erişim: 22 Ağustos 2026) diff --git a/TERIMLER.md b/TERIMLER.md index 38035aa..978c732 100644 --- a/TERIMLER.md +++ b/TERIMLER.md @@ -60,7 +60,10 @@ Amaç, metni İngilizce kelimelerle doldurmak değildir. Türkçesi varken İngi | debugging | hata ayıklama | | | emulator | emülatör | | | alignment | hizalama | | +| padding | dolgu | hizalama için eklenen boşluk | | overflow | taşma | | +| undefined behavior | tanımsız davranış | standardın tanımlamadığı davranış | +| calling convention | çağrı kuralı | bkz. `ABI` | | lock | kilit | bkz. `spinlock` | | performance | performans | | | default | varsayılan | | @@ -108,6 +111,9 @@ Bu terimler çevrilmez. Türkçe ek gerektiğinde kesme işareti kullanılır. | socket | ağ uç noktası | | | journaling | günlükleme | | | endianness | bayt sıralaması | | +| ABI | ikili düzeydeki arayüz sözleşmesi | çağrı kuralını ve veri düzenini kapsar, kısaltmasıyla aranıyor | +| freestanding | standart kütüphanesiz C ortamı | C standardının kendi terimi | +| MMIO / port I/O | aygıt register'larına erişim yöntemleri | manual'daki adlarıyla kullanılır | ## Ek alma kuralları From 86d933cea9fb74de881117fb3ac8786abe6fda48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20K=C4=B1l=C4=B1=C3=A7?= Date: Sun, 23 Aug 2026 01:12:44 +0300 Subject: [PATCH 2/2] docs: 00-giris/gelistirme-ortami.md notu --- 00-giris/README.md | 2 +- 00-giris/gelistirme-ortami.md | 179 ++++++++++++++++++++++++++++++++++ TERIMLER.md | 1 + 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 00-giris/gelistirme-ortami.md diff --git a/00-giris/README.md b/00-giris/README.md index 72865f9..1d9dd0c 100644 --- a/00-giris/README.md +++ b/00-giris/README.md @@ -11,7 +11,7 @@ Bu bölüm, sonraki bölümlerde anlatılan konuları denemek için gereken çal | OSDev nedir, neyi kapsar | [osdev-nedir.md](osdev-nedir.md) | ✅ | | Nereden başlanır: yol haritası | [yol-haritasi.md](yol-haritasi.md) | ✅ | | Ön gereksinimler (C, assembly, bilgisayar mimarisi) | [on-gereksinimler.md](on-gereksinimler.md) | ✅ | -| Geliştirme ortamı kurulumu (Linux / WSL) | `gelistirme-ortami.md` | ⬜ | +| Geliştirme ortamı kurulumu (Linux / WSL) | [gelistirme-ortami.md](gelistirme-ortami.md) | ✅ | | Cross-compiler hazırlama (GCC, Clang) | `cross-compiler.md` | ⬜ | | Build sistemi: Make ve alternatifleri | `build-sistemi.md` | ⬜ | | QEMU ile emülasyon | `qemu.md` | ⬜ | diff --git a/00-giris/gelistirme-ortami.md b/00-giris/gelistirme-ortami.md new file mode 100644 index 0000000..5f218fd --- /dev/null +++ b/00-giris/gelistirme-ortami.md @@ -0,0 +1,179 @@ +# Geliştirme ortamı kurulumu + +Kernel geliştirmede kullanılan araçların neredeyse tamamı POSIX uyumlu bir ortam varsayar. GNU binutils, GCC, GNU Make, QEMU ve GRUB'un imaj araçları bu ortamda geliştirilir, belgelenir ve test edilir. Bulacağınız her örnek Makefile, her derleme betiği ve her hata ayıklama tarifi bir kabuk komutuyla yazılmıştır. Bu yüzden geliştirme ortamı sorusu pratikte tek bir soruya iner: elinizin altında çalışan bir Linux kabuğu var mı? + +Bu not, Windows, macOS veya Linux üzerinde çalışan bir makineyi kernel geliştirmeye hazır hale getirmeyi kapsar: hangi kurulum biçiminin hangi durumda uygun olduğu, hangi paketlerin ne için gerektiği ve kurulumun doğru çalıştığının nasıl doğrulanacağı. Hedef mimariye özgü cross-compiler'ın hazırlanması ayrı bir konudur ve `cross-compiler.md` notunda ele alınır. + +## Ön koşullar + +- [OSDev nedir](osdev-nedir.md) +- [Nereden başlanır: yol haritası](yol-haritasi.md) + +## Kapsam + +Bu not x86-64 hedefini ve Debian/Ubuntu tabanlı bir dağıtımı esas alır. Paket adları dağıtımdan dağıtıma değişir; araçların kendisi ve kullanım biçimi değişmez. + +## Ortam seçenekleri + +| Seçenek | Uygun olduğu durum | Dikkat edilmesi gereken | +| --- | --- | --- | +| Doğrudan Linux | Makine zaten Linux çalıştırıyor | Gerçek donanımda test için USB'den açılış kolaydır | +| WSL2 (Windows) | Günlük sistemi Windows olanlar | Dosyalar Linux dosya sisteminde tutulmalı | +| Sanal makine | Windows veya macOS, izole ortam istenmesi | İç içe sanallaştırma kapalıysa QEMU hızlandırması çalışmaz | +| macOS | Mevcut makine macOS | Native format ELF değil Mach-O'dur, cross araçları zorunludur | +| Windows (MSYS2 / Cygwin) | Diğer seçenekler mümkün değilse | Yol, satır sonu ve eksik araç sorunları sık yaşanır | + +Windows kullanıyorsanız WSL2 en az sürtünmeli seçenektir: gerçek bir Linux kernel'i üzerinde çalışır, dosya sistemi Windows tarafından da görülebilir ve ayrı bir sanal makine yönetmek gerekmez. macOS'ta Homebrew ile araçların çoğu kurulabilir, ancak sistemin nesne dosyası formatı Mach-O olduğu için ELF üreten bir cross-compiler ve GNU ld kurulumu baştan zorunludur. + +## WSL2 kurulumu + +Yönetici yetkisiyle açılmış bir PowerShell penceresinde: + +```powershell +wsl --install -d Ubuntu-24.04 +``` + +Bu komut WSL bileşenlerini, sanal makine platformunu ve belirtilen dağıtımı kurar. İşlemcinin sanallaştırma desteğinin firmware'de açık olması gerekir. Kurulumdan sonra: + +```powershell +wsl --update +wsl --status +``` + +Kurulumun WSL2 sürümünü kullandığını doğrulayın; WSL1 gerçek bir Linux kernel'i çalıştırmaz ve bazı araçlarda beklenmedik davranışlara yol açar. + +**Dosyaların nerede duracağı önemlidir.** Depoyu `/mnt/c/...` altında, yani Windows dosya sisteminde tutmak derleme süresini belirgin biçimde uzatır; bu yol Windows ile Linux arasında bir dosya sistemi köprüsü üzerinden geçer. Çalışma dizinini Linux tarafında (`~/projeler/...`) tutun. Windows tarafından erişmek gerekirse `\\wsl$\Ubuntu-24.04\home\...` yolu kullanılabilir. + +**Satır sonları.** Windows tarafında klonlanmış bir depo CRLF satır sonlarıyla gelirse kabuk betikleri `bad interpreter` hatası verir, bağlayıcı betikleri ve assembly dosyaları beklenmedik biçimde ayrıştırılır. Bu depodaki `.gitattributes` dosyası `* text=auto eol=lf` kuralıyla çalışma kopyasını LF'de tutar. Kendi projenizde de aynı kuralı koyun veya klonlamayı WSL içinden yapın. + +## Paketler + +Debian ve Ubuntu üzerinde temel kurulum: + +```sh +sudo apt update +sudo apt install -y build-essential nasm gdb git make \ + qemu-system-x86 xorriso mtools dosfstools \ + grub-pc-bin grub-common \ + bison flex texinfo libgmp-dev libmpc-dev libmpfr-dev +``` + +Paketlerin ne işe yaradığı: + +| Paket | Ne için gerekir | +| --- | --- | +| `build-essential` | GCC, GNU Make ve binutils (`ld`, `objdump`, `readelf`, `nm`) | +| `nasm` | Intel söz dizimli assembly dosyaları | +| `gdb` | QEMU'ya bağlanarak kernel'i adım adım izlemek | +| `qemu-system-x86` | x86-64 hedefinin emülasyonu | +| `xorriso`, `mtools`, `dosfstools` | `grub-mkrescue` ile önyüklenebilir ISO ve FAT imajı üretmek | +| `grub-pc-bin`, `grub-common` | GRUB'un BIOS modülleri ve imaj araçları | +| `bison`, `flex`, `texinfo`, `libgmp-dev`, `libmpc-dev`, `libmpfr-dev` | GCC ve binutils'i kaynaktan derleyerek cross-compiler kurmak | + +Son satırdaki paketler yalnızca cross-compiler'ı kaynaktan derleyecekseniz gerekir. Dağıtımın hazır cross paketlerini kullanacaksanız bu adım atlanabilir; seçenekler `cross-compiler.md` notunda karşılaştırılır. + +Diğer dağıtımlarda paket adları farklıdır. Fedora'da `dnf install gcc make binutils nasm gdb qemu-system-x86 xorriso mtools grub2-tools-extra`, Arch Linux'ta `pacman -S base-devel nasm gdb qemu-system-x86 xorriso mtools grub` karşılığı kurulumu sağlar. + +## Kurulumun doğrulanması + +Önce araçların bulunduğunu doğrulayın: + +```sh +gcc --version +ld --version +nasm -v +qemu-system-x86_64 --version +gdb --version +grub-mkrescue --version +``` + +Sürüm numaralarını görmek araçların kurulu olduğunu gösterir, birlikte çalıştıklarını göstermez. Bunun için uçtan uca küçük bir test yapmak gerekir. Aşağıdaki 512 baytlık boot sektörü, BIOS'un yüklediği ilk sektörden tek bir karakter yazar: + +```asm +; NASM söz dizimi. BIOS bu sektörü 0x7C00 adresine yükleyip denetimi devreder. +bits 16 +org 0x7c00 + +start: + mov ah, 0x0e ; BIOS teletype çıktısı + mov al, 'T' + int 0x10 +bekle: + hlt + jmp bekle + +times 510 - ($ - $$) db 0 +dw 0xaa55 ; boot sektörü imzası +``` + +```sh +nasm -f bin deneme.asm -o deneme.img +qemu-system-x86_64 -drive format=raw,file=deneme.img +``` + +Açılan pencerede tek bir `T` harfi görünüyorsa assembler, imaj üretimi ve emülatör birlikte çalışıyor demektir. Örnek sadeleştirilmiştir: sayfa ve renk seçen `bh`/`bl` register'ları ayarlanmamıştır ve kod 16 bit gerçek modda çalışır. Kernel bu biçimde yazılmaz; bu yalnızca araç zincirini doğrulayan bir testtir. + +WSL'de pencere WSLg üzerinden açılır. Grafik arayüzün bulunmadığı bir ortamda `-display curses` seçeneği metin modundaki ekranı terminale çizer. + +## QEMU ve GDB'yi birlikte kullanmak + +QEMU, GDB'nin bağlanabileceği bir sunucu açabilir. `-s` seçeneği 1234 numaralı porttan dinlemeyi, `-S` ise ilk komut çalıştırılmadan durmayı sağlar: + +```sh +qemu-system-x86_64 -drive format=raw,file=deneme.img -s -S +``` + +Başka bir terminalde: + +```sh +gdb -ex "target remote localhost:1234" +``` + +Kernel'i ELF olarak derlediğinizde sembol tablosunu `file kernel.elf` komutuyla yükleyerek fonksiyon adlarıyla çalışabilirsiniz. Ayrıntılar `gdb.md` notundadır. + +**Donanım hızlandırması.** Linux üzerinde `/dev/kvm` erişimi olan bir kullanıcı QEMU'yu `-accel kvm` ile çalıştırarak belirgin hız kazanır; bunun için kullanıcının `kvm` grubunda olması gerekir. WSL2 ve sanal makine kurulumlarında iç içe sanallaştırma her yapılandırmada bulunmaz. Hızlandırma olmadan çalışan yazılım emülasyonu (TCG) geliştirme için yeterlidir, üstelik yorumlayıcı yürütme bazı hataları daha görünür kılar. + +## Editör ve dil sunucusu + +Kernel kaynağı, host sistemin başlıklarını kullanmadığı için editörün varsayılan yapılandırması çoğu satırı hatalı gösterir. clangd kullanılıyorsa derleme komutlarının `compile_commands.json` dosyasına aktarılması gerekir; `bear -- make` bu dosyayı mevcut Makefile'ı değiştirmeden üretir. Böylece `-ffreestanding`, `-nostdinc` ve hedef mimariye özgü seçenekler dil sunucusuna da bildirilmiş olur. + +Windows tarafında bir editör kullanıp WSL içinde derliyorsanız, editörün uzak (remote) eklentisiyle Linux tarafına bağlanması derleyici, hata ayıklayıcı ve dosya yollarının tutarlı kalmasını sağlar. + +## Git yapılandırması + +```sh +git config --global user.name "Adınız" +git config --global user.email "eposta@ornek.com" +git config --global core.autocrlf false +``` + +`core.autocrlf` değerinin Linux tarafında `false` kalması gerekir. Windows kurulumlarında varsayılan `true` olabilir; bu ayar dosyaları çalışma kopyasında CRLF'e çevirerek yukarıda anlatılan sorunlara yol açar. + +## Sık yapılan hatalar + +- Depoyu WSL'de `/mnt/c` altında tutmak. Derleme belirgin biçimde yavaşlar. +- CRLF satır sonlarıyla çalışmak. Kabuk betikleri, bağlayıcı betikleri ve assembly dosyaları sessizce bozulur. +- Host derleyicisini kernel derlemek için kullanmak. Host GCC altında bir işletim sistemi olduğunu varsayar; `-ffreestanding` bu farkın yalnızca bir kısmını kapatır. +- `grub-mkrescue` çalıştırırken `xorriso` veya `mtools` kurmamış olmak. Hata mesajı çoğu zaman eksik paketi doğrudan söylemez. +- QEMU'yu Windows tarafından, imajı ise WSL içinden vererek çalıştırmak. İki taraf farklı yol biçimleri kullanır. +- Kurulumu doğrulamadan kernel yazmaya başlamak. İlk hatanın kaynağını kernel kodunda aramak zaman kaybettirir. +- Sürüm numaralarını görmeyi yeterli saymak. Araçların birlikte çalıştığı ancak uçtan uca bir testle anlaşılır. + +## İlgili notlar + +- [Ön gereksinimler](on-gereksinimler.md) — C, assembly ve araç zinciri bilgisi +- [Nereden başlanır: yol haritası](yol-haritasi.md) — Aşama 0 ve sonrası +- [02 — Boot](../02-boot/) — boot protokolleri ve imaj üretimi +- [Kaynaklar](../resources/) — araç ve dokümantasyon listeleri + +## Kaynaklar + +- Microsoft, "How to install Linux on Windows with WSL"; (erişim: 22 Ağustos 2026) +- Microsoft, "Comparing WSL Versions"; (erişim: 22 Ağustos 2026) +- QEMU dokümantasyonu, "QEMU System Emulation User's Guide" — Invocation ve Debugging; (erişim: 22 Ağustos 2026) +- NASM — The Netwide Assembler Manual, Bölüm 2 — Running NASM; (erişim: 22 Ağustos 2026) +- GNU GRUB Manual, "Making a GRUB bootable CD-ROM"; (erişim: 22 Ağustos 2026) +- GNU Make Manual, Bölüm 2 — An Introduction to Makefiles; (erişim: 22 Ağustos 2026) +- GDB dokümantasyonu, "Connecting to a Remote Target"; (erişim: 22 Ağustos 2026) +- clangd dokümantasyonu, "JSON Compilation Database"; (erişim: 22 Ağustos 2026) +- OSDev Wiki, "QEMU"; (erişim: 22 Ağustos 2026) diff --git a/TERIMLER.md b/TERIMLER.md index 978c732..34e7bdb 100644 --- a/TERIMLER.md +++ b/TERIMLER.md @@ -114,6 +114,7 @@ Bu terimler çevrilmez. Türkçe ek gerektiğinde kesme işareti kullanılır. | ABI | ikili düzeydeki arayüz sözleşmesi | çağrı kuralını ve veri düzenini kapsar, kısaltmasıyla aranıyor | | freestanding | standart kütüphanesiz C ortamı | C standardının kendi terimi | | MMIO / port I/O | aygıt register'larına erişim yöntemleri | manual'daki adlarıyla kullanılır | +| host / target | geliştirme yapılan makine ve hedeflenen sistem | cross-compiler bağlamında ikisi birlikte kullanılıyor | ## Ek alma kuralları