8 puan yazan GN⁺ 2023-07-24 | 1 yorum | WhatsApp'ta paylaş
  • Bu, bilgisayarda bir program çalıştırıldığında gerçekte neler olduğunu en başından sonuna kadar anlamaya çalışan kişisel bir öğrenme projesinin giriş bölümü
  • Temel sorular, programın CPU’da doğrudan çalıştırılıp çalıştırılmadığına, sistem çağrısının nasıl işlediğine ve birden fazla programın aynı anda nasıl çalıştığına uzanıyor
  • Üniversite derslerinin dışında kapsamlı sistem kaynakları bulmak zor olduğundan, kalitesi değişen kaynaklar ve çelişen bilgiler arasından doğru olanı bizzat ayıklamak gerekmiş
  • Birkaç haftalık araştırma yapıp neredeyse 40 sayfalık not hazırlarken, bilgisayarın açılıştan program çalıştırmaya kadar uzanan sürecini daha iyi anlamaya başlamış
  • Zaten bildiğini düşünen okurların bile yeni şeyler öğrenebileceğini söyleyerek, zamanı olmayanlara önce 3. bölümü okumalarını öneriyor

Program çalıştırmayı anlama yolculuğunun başlangıcı

  • Bu yazının çıkış noktası, bilgisayarda bir program çalıştırıldığında tam olarak neler olduğudur
  • Düşük seviye bilgi birikimi bir ölçüde vardı, ancak farklı parçaları tek bir akış içinde birleştirmekte zorlanılmış
  • Sorular üç kola ayrılıyor
    • Program gerçekten doğrudan CPU’da mı çalışıyor
    • Sistem çağrıları nedir ve pratikte nasıl çalışır
    • Birden fazla program aynı anda nasıl çalışır

Araştırma süreci ve okuma sırası

  • Kapsamlı sistem kaynakları az olduğu için birçok kaynağı doğrudan araştırmak gerekmiş; kaynakların kalitesi ve içeriği de birbirinden farklıymış
  • Birkaç haftalık araştırma ve neredeyse 40 sayfalık not sayesinde, başlangıç sürecinden program çalıştırmaya kadar bilgisayarın nasıl işlediği daha iyi anlaşılmış
  • Amaç, yazarın kendi arayıp bulmak istediği türden tek ve sağlam bir açıklama yazısını bizzat oluşturmak
  • Konuyu zaten bildiğini düşünen ya da zamanı olmayan okurlara önce 3. bölüm’ü okumaları öneriliyor
  • Sonraki yazı 1. bölüm: The “Basics” ile devam ediyor

1 yorum

 
GN⁺ 2023-07-24
Hacker News yorumları
  • Bunu yapan kişiyim. Okuduğunuz ve Hacker News’e yakışır şekilde birçok düzeltme önerdiğiniz için teşekkürler. Putting the "You" in CPU hâlâ yoğun biçimde üzerinde çalışılan bir iş; aslında biraz daha cilalayıp içerik ekledikten sonra gelecek hafta civarı HN’de paylaşmayı düşünüyordum.
    17 yaşındayım; 1 yıl önce liseyi bıraktım ve Hack Club’da (https://hackclub.com/) tam zamanlı çalışmaya başladım. Kendimi bildim bileli programlama yapıyorum; yaklaşık 6 yıl önce de programlamaya ve diğer ilgi alanlarıma daha fazla odaklanmak için evde eğitime başladım.
    Tamamen kendi kendime öğrendim; üniversitede sistemler dersi almadım ve “bir şey çalıştırınca ne olur?” sorusuna verdiğim yanıttan memnun değildim. Bu yüzden mümkün olduğunca derine inerek çok uzun zaman harcadım ve bu süreçte işletim sistemleri ile donanımın öğrenmesi gerçekten eğlenceli olduğunu, ancak bu konudaki çevrimiçi kaynakların çoğu zaman berbat olduğunu fark ettim.
    Araştırma yaparken sık sık 2014’ten kalma ders slaydı PDF’lerine ya da aslında yanlış veya aşırı basitleştirilmiş StackOverflow yanıtlarına ulaşıyordum. Bu yüzden Putting the "You" in CPU’yu, bu alanı kendi kendine öğrenmek isteyenler için daha iyi bir kaynak olması umuduyla yazdım. SMP hakkında hâlâ birkaç paragraf daha yazmam gerektiği için kusursuz değil; ama gördüğüm kaynakların çoğundan çok daha iyi olduğunu düşünüyorum. Çizimleri ve şemaları da ilk kez hazırladım; ilerleyen bölümlere doğru daha iyi oldular ve sondaki birkaç çizimle epey gurur duyuyorum.
    Tamamı GitHub’da açık kaynak olarak yer alıyor: https://github.com/hackclub/putting-the-you-in-cpu

    • Son zamanlarda ben de sık sık “bu tür çevrimiçi kaynaklar çok berbat” diye düşünüyorum. Özellikle Linux çekirdeğinin ayrıntılı blok diyagramını, sayfa tablolarının nasıl çalıştığını, platformlara göre fonksiyon çağırma ABI’larının karşılaştırmasını, düşük seviyeli ağ protokolü ayrıntılarını, ayrılmış Linux PID numaraları gibi şeyleri ararken böyle oluyor.
      Bazen yanıtı Reddit başlıklarında buluyorum ama genelde araya gürültü karışmış oluyor; ayrıca bilginin saklanacağı yer olarak Reddit’in güvenilir olup olmadığından da şüpheliyim. StackOverflow belirli bir işi çözmeye yönelik sorular ağırlıklı olduğundan yanıtlar da kaçınılmaz olarak kısa oluyor; bu yüzden özellikle pek yardımcı olmuyor.
      Genel bilgi için artık Google’ın bozulmuş aramasını atlayıp doğrudan Wikipedia’ya gidiyorum; ama Wikipedia’nın da teknik konuları ne kadar derinlikte ele alabileceğinin bir sınırı var. Bilgisayarların iç yapısına dair ayrıntıları kapsamlı biçimde toplayan bir wiki gerekmez mi diye düşünüyorum. Dağınık kaynak çok, ama tek yerde toplansalar gerçekten harika olurdu.
    • Ben de o yaşlarda benzer sorular taşıyordum ve Linux kaynak kodunda pek çok ilginç yanıt bulmuştum. Tabii o zamanlar çok daha basitti. Özellikle osdev topluluğu ve Intel sistem mimarisi belgeleri büyük bir dönüm noktası olmuştu; hatırladığım kadarıyla 3a ya da 3b bölümlerinde çok değerli bilgiler vardı.
      O belgeler, dünyanın şu anda nasıl olduğundan çok, nasıl olabileceğini anlatıyor. OSDEV yapınca 32 bit işlemcilerin PAE ile 36 bit adreslemeyi nasıl yaptığı, 64 bit işlemcilerin daha fazla para koparmak için 52 bit adreslemeyi nasıl kullandığı gibi pek çok eğlenceli şeyi öğreniyorsunuz.
      Bilgisayarın 16 bit modda başlayıp long mode’a geçmesi için neden sistem düzeyinde assembly cambazlıkları gerektiğini, 8 bit modun neden hâlâ kaldığını da öğreniyorsunuz. İkili dosya yüklemeyi öğrenmek hoşunuza gittiyse hâlâ şaşıracağınız çok şey var. Örneğin 64 bit modda bile bellek segmentasyonu kalmış durumda, ama long mode’da düz eşlemeye zorlanıyor.
    • Harika iş. İşletim sistemi geliştirmeye giriş için iyi bir kaynak; çok ayrıntı var ama sindirmesi kolay. 2. bölümdeki dipnot #2’nin son kısmı biraz düzeltilse iyi olur. Bazı programlama dillerindeki asenkron paradigmanın işbirlikçi çoklu görev olduğu yansıtılmalı. Bir süreç içinde işbirlikçi çoklu görev kullanmak genellikle güvenli kabul edilir, ama bunun arzu edilir olup olmadığı ayrı bir konu. Bildiğim kadarıyla Erlang sağlamlık için öncelikli çalıştırmayı koruyor.
  • Böyle kaynakları seviyorum. Son zamanlarda RISC-V dünyasına adım atıyorum ve özgür/açık kaynak yazılımı ileri taşımaya çalışanların, yeni çıkan çeşitli tek kartlı bilgisayarlarda yazılımların iyi çalışmasını sağlamak için bu tür bilgilere ihtiyaç duyacağı açık görünüyor.

    • Bu arada RISC-V komut kodlaması, Thumb-2 gibi birkaç istisna dışında inceleyebileceğiniz şeyler arasında oldukça tuhaf olanlardan. Bu şekilde yapılmasının iyi nedenleri vardı; ama hex dump okumayı düşünüyorsanız RISC-V size kolaylık göstermeyecek. Diğer çoğu açıdan basit olsa bile durum böyle.
    • Lisans veya daha üst düzeyde eğitim aldıysanız, programcıların genelde bu konuları zaten bildiğini düşünüyorum. En azından bilgisayar mimarisi ve işletim sistemleri derslerini atlamadılarsa.
      Benim durumumda bilgisayarların nasıl çalıştığını öğrenirken bir komut kümesi mimarisi tanımlamak, simülatör ve assembler uygulamak, doğrudan assembly yazmak yaygındı. Daha hevesli olanlar bunu FPGA ile gerçekleştirir ya da LLVM backend’i yazardı.
      İşletim sistemi tarafında da aynı. Öğrenmek için doğrudan bir kernel uygulamak ya da en azından mevcut bir kerneli değiştirmek oldukça yaygın bir süreç.
  • Bilgisayarların çok temel düzeyde nasıl çalıştığını daha iyi anlamak istiyorsanız Charles Petzold’un Code kitabını gerçekten öneririm. İlk ilkelerden başlayıp oldukça yüksek bir seviyeye kadar çıkıyor.

  • Bu kaynağın iyi yaptığı şeylerden biri, bilgiyi toplama sürecindeki beklenti ile gerçek öğrenme sonucunu göstermesi. “y yüzünden x olduğunu sanıyordum, ama aslında b yüzünden a imiş!” gibi.
    Yanlış anlamaları ortadan kaldırmak çoğu zaman yeni bilgi oluşturmanın temel adımlarından biridir; yazarın, okurun bilgiyi işlerken kendi yanlış anlamalarını aşması gerektiğini kabul etmesi yardımcı oluyor. “Doğru cevap bu, farklı düşündüysen aptalsın” tavrına göre çok daha okur dostu.

    1. bölümde fork() dönüş değeri açıklaması yanlış. Yazılanın tersine, ebeveynde çocuğun PID’si, çocukta ise 0 dönmeli. Bu bölüm için bir pull request açtım.
    • Gerçekten çok teşekkürler, hata yapmışım. Kod örneğini düzelttim ve birleştirdim.
  • add eax, 512 ifadesinin 05 00 02 00 00 olarak çevrildiği açıklamada, ilk bayt olan 05’in EAX register’ına 16 bitlik bir sayı ekleyen opcode olduğu, kalan baytların da little endian biçimindeki 512 (0x200) olduğu söyleniyor
    Ancak bu açıklama 5 baytlık komutun yalnızca ilk 3 baytını açıklıyor. Kalan 00’ların ne olduğunu merak ediyorum. Muhtemelen opcode’un EAX’e 32 bitlik bir sayı eklediğini yazmak istemiş olabilir mi?

    • “he” değil “she”; ve doğru. O kısmın 32 bit diye yazılması gerekiyordu sanırım. İyi yakalamışsın
    • x86’dan bahsediyorsak doğru. eax register’ı 32 bit genişliğindedir; aynı register’ın alt 16 biti ise ax olarak adlandırılır
  • Güzel bir yazı. Kendi kendini yetiştirmiş bir web geliştiricisi olarak bu tür materyallerin çok değerli olduğunu düşünüyorum. Çeşitli soyutlamaların dışına çıkıp işlerin gerçekte nasıl yürüdüğünü daha somut anlamaya yardımcı oluyor

  • İyi bir kaynak gibi görünüyor; konuya epey hızlı giriyor ve biraz da eğlenceli. Beklediğim kadar “monad tutorial” havasında değil. Daha fazla okumayı düşünüyorum

    • Beğenmene sevindim. İleride geri bildirimin olursa duymak isterim
  • Güzel bir kaynak. Yine de kernel hakkında aklımda bir soru kaldı. [0]’da shebang’in kernel tarafından işlendiği ve tüm dosya yüklenmeden buf içinden alındığı için her zaman buf uzunluğunda kesildiği açıklanıyor
    Dört yıl önce biri, kernel’ın 128 karakteri aşan yolları kesmesinden rahatsız olup tampon boyutunu iki katına çıkararak kesilme noktasını da iki katına çıkarmış. Bu yüzden bugün Linux’ta shebang satırı 256 karakteri aşarsa 256 karakterden sonrası tamamen kayboluyor
    Birinin dosya yolunun neden sessizce kesildiğini anlamıyorum. Bunu hele hele kernel yapmamalı. 256 baytlık bir dosya yolu mantıksız olabilir, ama 256 baytlık bir yol+argüman dizgesi bir gün neredeyse kesinlikle karşımıza çıkar. Betikleri sessizce bozmak yanlış
    [0]: https://cpu.land/how-to-run-a-program

    • Yazar olarak kesinlikle katılıyorum. shebang’in sınırlarını anlamak için kernel’ın çalıştırma mantığını bilmek gerekmemeli. Bu aptalca bir tasarım ve muhtemelen bu noktayı daha fazla vurgulamalıydım
      Birkaç yıl önce biri, çok uzun shebang’lerde en azından sessizce başarısız olmak yerine açıkça başarısız olması için kernel’a yama yapmayı denedi. Fakat NixOS’ta sorun çıktı. Nix’e yakışır şekilde, uzun nix-store yolları kullanan aşırı uzun shebang’ler zaten kullanılıyordu. Önceden sessizce kesiliyor ama yine de çalışıyordu; bir anda tüm bu betikler başarısız olunca geriye dönük uyumluluk bozuldu. Bu yüzden yamanın geri alınması gerekti ve sonrasında benzer bir değişiklik gelemedi
      Ayrıntılar için bkz. https://lwn.net/Articles/779997/
    • shebang’e karmaşık argümanlar koymamak gerekir. shebang, mevcut dosyanın yorumlayıcı konumunu belirtmek içindir
      shebang kendi başına birden fazla argümanı bile doğru düzgün işleyemez. #!/bin/program -args somescript yazarsanız ['/bin/program','-args somescript'] şeklinde ayrılır; bu da neredeyse her zaman istenen sonuç değildir. Bu Linux’a özgüdür; ayrıca shebang tüm Unix’lerde evrensel olarak taşınabilir de değildir
      Karmaşık bir şey yapmak istiyorsanız #!/bin/sh kullanıp, mevcut dosyada gerekli argümanlarla exec etmek daha iyidir
      Bağlantıda eksik kalan bir nokta, mevcut yolda yorumlayıcıyı bulmak için env kullanılabilmesidir. Örneğin #!/usr/bin/env python3, kullanıcının kullandığı python3ü konumunu bilmeden bulur
      Bu, Python yorumlayıcısı için PATH’i üzerine yazarak çalışan sanal ortamlarda çalıştırılacak betikler için yararlı olabilir. Ancak kurulumu yapılan programlarda bunu yapmamak gerekir. Kurulu bir programın, kullanıcının hangi yorumlayıcıyı kullanacağını kontrol etmesine izin verilmemeli; mutlak yol kullanılmalıdır
      env’de, bu sınırla başa çıkmak için tek bir dizgeden komut satırını ayrıştırabilen -S seçeneği vardır. Yine de yıllardır shebang satırında numaralardan kaçınan biri olarak, en iyi ihtimalle şüpheli bir pratik gibi görünüyor
    • Tamponun diskin blok boyutuna eşit ayarlanmamış olması daha da şaşırtıcı. Genelde 512 bayttır ama her zaman öyle değildir