- initrd, çekirdeğin doğrudan yorumlayıp çalıştırdığı bir program birimi olarak tanımlanıyor ve Linux bir tür yorumlayıcı olarak yeniden ele alınıyor
kexec, base64, cpio kullanılarak kendi kendini yeniden başlatan özyinelemeli bir Linux dağıtımı kuruluyor; initrd kendisini yeniden çalıştırıyor
/init betiği kendi cpio imajını çıktılıyorsa, Quine biçiminde kendini kopyalayan bir initrd oluşuyor
- ELF yürütme yapısı ve
ld.so, binfmt_misc üzerinden yorumlayıcı katmanlarının çekirdeğe kadar uzanan yapısı açıklanıyor
kexec veya QEMU kullanıldığında Linux üzerinde başka bir Linux'u kuyruk özyinelemeli olarak çalıştırmak mümkün oluyor; böylece çekirdek, sanallaştırma ve yorumlayıcı arasındaki sınırlar deneysel olarak genişletiliyor
rkx.gz tersine mühendisliği ve kendi üzerine özyinelemeli initrd yapısı
curl https://astrid.tech/rkx.gz | gunzip | sudo sh komutu, 20 MB boyutunda base64 kodlu bir kabuk betiğini indirip çalıştırıyor
- Betik root yetkisini doğruluyor ve
kexec, base64, cpio varlığını denetliyor
- base64 verisini çözüp
r adlı bir cpio arşivi oluşturuyor, ardından içinden k adlı çekirdek imajını çıkarıyor
kexec ile k çekirdek, r ise ramdisk olarak yüklenip çalıştırılıyor
r.cpio içinde /bin, /init, k dosyaları bulunuyor; k, Linux 6.18.18 çekirdek imajı, /init ise kabuk betiği biçiminde
/init, /proc dosya sistemini bağlıyor, ardından geçerli dosya sistemini /r içine cpio olarak paketleyip kexec ile /k ve /r dosyalarını yeniden çalıştırıyor
- Sonuç olarak kendi kendini sürekli yeniden başlatan özyinelemeli bir Linux dağıtımı ortaya çıkıyor
Linux çekirdeğine yorumlayıcı olarak bakış
- initrd, yalnızca önyükleme için kullanılan bir ramdisk değil, Linux çekirdeğinin yorumlayıp çalıştırdığı bir program olarak görülebilir
curl | sh veya python3 script.py gibi, initrd de çekirdek tarafından çalıştırılan bir giriş programı biçimindedir
- Dolayısıyla Linux çekirdeği, initrd'yi yorumlayan bir yorumlayıcı gibi işlev görür
- Bu yapı, kuyruk özyineleme optimizasyonuna (tail-call optimization) benzer
kexec, önceki çekirdeğin üzerine yazmak yerine onu yeni bir bellek alanına yükleyip çalıştırır
- Her çekirdek önceki durumu korumaz; yeni bir “stack frame” ile yer değiştirir
Quine ve initrd'nin kendini kopyalaması
- Quine, kendi kendisini üreten program anlamına gelir
/init betiği son bölümde cat /r çalıştıracak şekilde yapılırsa, kendisiyle aynı cpio çıktısını üretir
- Bu durumda Linux initrd yorumlayıcısının bir Quine'ı oluşur
- Tüm dosyalar RAM üzerindeki
tmpfs içinde bulunduğundan gerçek disk G/Ç işlemi gerçekleşmez
ELF, ld.so ve yorumlayıcı katmanları
- ELF yürütülebilir dosyaları, başlıklarında yorumlayıcı (
ld-linux-x86-64.so.2) yolunu taşır
- Çalıştırma sırasında çekirdek önce
ld.so'yu başlatır; ardından ld.so, ELF'in dinamik kütüphanelerini yükleyip programı çalıştırır
- Bu nedenle ELF de bir tür yorumlayıcı dili olarak görülebilir
/bin/sh, ld.so tarafından yorumlanır; ld.so ise çekirdek tarafından doğrudan yorumlanır
ld.so statik bağlantılı bir ELF olduğundan çekirdek tarafından doğrudan çalıştırılabilir
- Böylece yorumlayıcı katmanlarının taban durumu (base case) oluşur
binfmt_misc ile CPIO çalıştırma
binfmt_misc kullanılarak belirli magic byte'lara sahip dosyalar belirtilen yorumlayıcıyla çalıştırılabilir
- QEMU ile CPIO'yu initrd olarak çalıştıran bir betik yorumlayıcı olarak kaydedilebilir
- QEMU, belirtilen çekirdek ve initrd ile sanal makineyi önyükler
- Sonuçta CPIO dosyasının yorumlayıcısı, QEMU'nun çalıştırdığı Linux çekirdeği olur
Özyinelemeli yorumlayıcılar ve “en tuhaf döngü”
- QEMU tabanlı yorumlayıcı yeni bir Linux ortamı için yeni bir stack frame oluşturur
- Linux üzerinde başka bir Linux çalıştıran bu yapı, bellek sınırına kadar iç içe geçebilir
- Yerine
kexec tabanlı yorumlayıcı kullanılırsa kuyruk çağrısı optimize edilmiş özyinelemeli Linux çalıştırma mümkün olur
/init içinde binfmt_misc kaydedilip /r çalıştırılacak şekilde yapılandırılırsa
kendi kendisini çalıştıran bir initrd tamamlanmış olur
/r, CPIO biçimindeki bir sonraki init sürecidir ve çalıştırıldığında yeniden kendisini yorumlar
Sonuç
- initrd yalnızca bir önyükleme aracı değil, Linux çekirdeğinin yorumladığı bir program birimidir
kexec ve binfmt_misc ile Linux'un kendisini bir yorumlayıcı gibi özyinelemeli biçimde çalıştırmak mümkündür
- Bu yapı, çekirdek, sanallaştırma, yorumlayıcı ve kendini kopyalayan programlar arasındaki sınırları bulanıklaştıran deneysel bir kavramdır
- İlgili kaynak kodu GitHub deposu ifd3f/rekexec içinde yayımlanmıştır
2 yorum
Cehalet cesaret getirir derler ya... Keşke bu tür yazılardan kaçınılsa.
Hacker News görüşleri
Bu yazıyı okurken çok fazla yanlış anlama yüzünden acı çektim
cpio arşivi bir dosya sistemi değildir. Yazar initramfs kullanıyor; bu da tmpfs tabanlıdır. Linux, cpio'yu tmpfs'e çıkarabilir. Dosya ve dizin arşivi kendi başına bir program değildir
Bir şeyin benzer görünmesi onun aynı olduğu anlamına gelmez. İkili program CPU'da çalışır; eğer bir yorumlayıcı varsa bu donanım ortamının içinde gizlidir. Bu, çekirdeğin kapsamı dışındadır
Bir shell script çalıştırmak için, o scripti yorumlayacak bir shell gerekir. Yazar bu kısmı atlıyor ve çekirdekle shell programını karıştırıyor
Linux, initramfs veya ramdisk olmadan da derlenebilir ve yine de dosya sistemindeki userland'i çalıştırabilir
“Linux initrd interpreter” ifadesi gerçekten çok yanlış bir açıklama
Her OS, çekirdek yetkileriyle çalışan bir makine kodu yorumlayıcısı değil mi?
Bu yazı, “Linux bir yorumlayıcıdır” şeklinde bir zihinsel model olarak bakınca fena değil, ama harfi harfine alınırsa yanlış
CPU komutları düzeyinde yorumlama değil; çekirdeğin ELF, shebang script'leri ve initramfs gibi yürütme biçimlerini orkestre etmesi olarak bakılırsa daha anlamlı. Karışıklık muhtemelen ‘yorumlayıcı’ kelimesinin iki farklı anlamının birbirine karışmasından doğuyor
Asıl mesele benzetmenin doğru olup olmaması değil; 'çalıştırma' kavramının ne kadar ortama bağımlı olduğunu göstermesi
“Her şey yorumlayıcı mı?”
Turing'in Theta Combinator'ü
Serinin önceki yazısında yazar, Contabo'nun object storage'ını kullanmak istemediği için VPS imajını kendisinin yaptığını söylüyor
Aylık 1,50 dolardan tasarruf etmek için 50 saat harcamakla, token'lara 250 bin dolar harcamak gibi iki uç arasında bir denge noktası olduğunu düşünüyorum.
Altyapı maliyetlerini karşılayamıyorsanız, sorun teknik beceriden çok sosyal etkenler de olabilir. Doom'u
curlile çalıştırmaya takıntılı olmak bana çok üretken gelmiyorman ld.soçıktısına bakarsanız, ELF'nin.interpbölümünde saklanan dinamik bağlayıcının çalıştırıldığı açıkça yazıyor. Bölüm adının kendisi de ilginçLinux, programlanabilir bir arayüz olarak çok kullanışlı. Windows'ta da mümkün ama Linux'un daha uygun olduğunu düşünüyorum
GUI'nin Windows'ta daha iyi olduğunu düşünüyorum ama GNOME ya da KDE de rahat değil. Bu yüzden fluxbox, icewm, bazen de xfce veya mate-desktop kullanıyorum. Bugünlerde basit ve hızlı ortamları tercih ediyorum. İşlerimin çoğunu komut satırı ve kod düzenleme ile hallediyorum