Mikro Linux Dağıtımı Yapmak (2023)
(popovicu.com)- Linux çekirdeğini doğrudan derleyip asgari bir kullanıcı alanı kurarak bir “mikro Linux dağıtımı” oluşturma sürecini adım adım anlatıyor
- İşletim sistemi çekirdeğinin rolünü, Linux dağıtımının bileşenlerini ve çekirdek ile kullanıcı alanı arasındaki ilişkiyi temelden ele alıyor
- Örnek olarak RISC-V mimarisini (QEMU’nun
riscv64 virtmakinesi) kullanıyor, ancak aynı ilkelerin x86 gibi diğer mimarilere de uygulanabileceğini gösteriyor initsüreci,initramfsve Go ile yazılmış basit bir kabuk içeren doğrudan çalıştırılabilir asgari bir Linux ortamı kuruyor- Son olarak
u-rootprojesini kullanarak gerçekte faydalı bir mikro dağıtım yapma yöntemini tanıtıyor ve bunu Linux sistem yapısının genelini anlamaya yardımcı olan bir başlangıç kılavuzu olarak tamamlıyor
İşletim sistemi çekirdeği nedir
- Çekirdek, donanım kaynaklarını yönetmekten ve programların çalışmasını denetlemekten sorumlu işletim sisteminin temel bileşenidir
- Tek çekirdekli bir ortamda bile birden fazla program aynı anda çalışıyormuş gibi görünmesini sağlayan çoklu görev yönetimi sunar
- Çekirdek, giriş/çıkış aygıtı denetimini soyutlar; böylece uygulamaların donanımın ayrıntılı adresleri veya yazmaç değerleriyle doğrudan uğraşmasına gerek kalmaz
- Örneğin bir program yalnızca “standart çıktıya mesaj yaz” isteğinde bulunur; gerçek donanım etkileşimini çekirdek yürütür
- Dosya sistemi arayüzü üzerinden yüksek seviyeli veri erişimi sağlar
- Dosya, yalnızca disk verisi değil; çekirdekle iletişim kuran mantıksal bir arayüz olarak çalışır
- Çekirdek, süreçler arası yalıtım ve iletişim modeli sağlayarak her uygulamanın bağımsız çalışmasına ya da iş birliği yapmasına olanak tanır
- Linux çekirdeği açık kaynaktır, çeşitli mimarilerde çalışabilir ve dünya genelinde en yaygın kullanılan çekirdeklerden biridir
Linux dağıtımı nedir
- Yalnızca Linux çekirdeği, kullanıcının bir web tarayıcısı ya da GUI uygulaması çalıştırmasına yetmez; çekirdeğin üzerinde çeşitli yazılım katmanlarından oluşan bir altyapı gerekir
- Ağ yapılandırması, IP atama, VPN yönetimi gibi işler çekirdeğin değil, üst katmandaki kullanıcı alanı programlarının sorumluluğundadır
- Bu nedenle Linux dağıtımı, çekirdek + kullanıcı alanı altyapısının birleşimi olarak tanımlanır
- Dağıtım; çekirdeğin sunduğu temel işlevlerin üzerine paketler, araçlar, yapılandırmalar ve başlatma süreci (
init) ekler - Dağıtımların karmaşıklığı değişkendir; Arch Linux gibi asgari yapıdan Ubuntu gibi kullanıcı dostu yapılara kadar uzanır
Çekirdek dışındaki altyapı: kullanıcı alanı ve init süreci
- Çekirdek önyüklemeyi tamamladıktan sonra ilk olarak PID 1 olan
initsürecini çalıştırırinit, sonrasında gelen tüm kullanıcı alanı süreçlerinin atasıdır ve sistem servisleriyle araçları sırayla başlatır
inittarafından çalıştırılan çeşitli süreç ve araçların bütünü, Linux dağıtımının fiilî bileşenlerini oluşturur- Dağıtım karmaşıklaştıkça gereksiz işlevler birikip “bloated” olduğu yönünde eleştiri alabilir
- Buna karşılık, özel bir mikro dağıtım yaparak yalnızca gerekli işlevleri içeren hafif bir sistem kurulabilir
RISC-V için Linux çekirdeği derlemek
x86ortamında çapraz derleme araç zinciri kullanılarak RISC-V için çekirdek derlenirkernel.orgüzerindenlinux-6.5.2.tar.xzkaynak kodu indirilipmake ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfigçalıştırılır
menuconfigile çekirdek ayarları görsel olarak düzenlenebilirmake -j16ile paralel derleme yapıldıktan sonraarch/riscv/boot/Imageüretilir- QEMU’da
qemu-system-riscv64 -machine virt -kernel arch/riscv/boot/Imageile önyüklenir- Önyükleme günlüğünde SBI katmanının algılanması, UART başlatma ve printk etkinleştirme gibi mesajlar görülebilir
İlk engel: kök dosya sistemi yok
- Çekirdek önyüklemesi sırasında
VFS: Unable to mount root fshatasıyla kernel panic oluşur- Neden: kök dosya sistemi (
initramfs) sağlanmamıştır
- Neden: kök dosya sistemi (
- Dosya sistemi yalnızca disk üzerinde değil, RAM tabanlı (
initramfs) olarak da kurulabilir initramfs,cpiobiçiminde paketlenir ve QEMU’da-initrdseçeneğiyle yüklenebilir
initramfs kurmak ve “Hello world” çalıştırmak
- Asgari gereksinim,
/initikilisinin bulunmasıdırinit.cyazıldıktan sonra statik bağlama (-static) ile derlenircpio -o -H newc < file_list.txt > initramfs.cpioile paketlenir
- QEMU çalıştırıldığında “Hello world” yazdırılır, ancak
initsonlandığı için yeniden kernel panic oluşur- Çözüm:
init’in çıkmaması için sonsuz döngü eklemek
- Çözüm:
Go ile yazılmış basit bir kabuk eklemek
init,forkveexeclkullanarak/little_shellçalıştırırlittle_shell.go, kullanıcı girdisini alıp komutu ekrana geri yazan basit bir kabuktur- RISC-V için
GOOS=linux GOARCH=riscv64 go build little_shell.goile derlenir
- RISC-V için
- Hem
inithem delittle_shell, çıktıyı UART üzerinden paylaşır- Standart giriş/çıkış dosya tanıtıcılarıyla yönetilir ve
forksırasında miras alınır
- Standart giriş/çıkış dosya tanıtıcılarıyla yönetilir ve
- Sonuç olarak “Hello from init” ile kabuk girdisinin dönüşümlü çıktığı temel bir Linux ortamı tamamlanır
Çekirdeğin rolünün özeti
- Donanım soyutlama: kullanıcı programları UART’ı veya aygıt ayrıntılarını bilmeden çıktı üretebilir
- Yüksek seviyeli arayüz sağlama: dosya sistemi üzerinden başka ikililere (
little_shell) erişim sağlanır - Süreç yalıtımı:
initve kabuk bağımsız bellek alanlarında çalışır - Çekirdek, karmaşık donanım üzerinde kararlı ve taşınabilir bir çalışma temeli sunar
İşletim sisteminin tanımı
- Kimi zaman yalnızca çekirdek işletim sistemi sayılır, kimi zaman da dağıtımın bütünü işletim sistemi olarak görülür
- Asıl önemli olan, çekirdek ile kullanıcı alanı arasındaki rol sınırlarını ve etkileşim yapısını anlamaktır
u-root ile gerçekten faydalı bir mikro dağıtım yapmak
- u-root projesi, Go tabanlı bir kullanıcı alanı araç seti sunar
u-root, Linux çekirdeği üzerinde çalışan kullanıcı alanı önyükleyicisi ve kabuk ortamını içerir
- Kurulumdan sonra
GOOS=linux GOARCH=riscv64 u-rootkomutuylainitramfsotomatik olarak oluşturulur- Oluşan
/tmp/initramfs.linux_riscv64.cpiodosyası QEMU’da çalıştırılabilir
- Oluşan
- Önyükleme sırasında “Welcome to u-root!” afişiyle birlikte varsayılan kabuk istemi sunulur
ls,pwd,echogibi temel komutlar desteklenir ve sekme tamamlama özelliği bulunur
Ağ bağlantısı pratiği
- QEMU’ya
virtio-net-devicevevirtio-rng-pciaygıtları eklenir-device virtio-net-device,netdev=usernet -netdev user,id=usernetseçenekleri kullanılır
u-rootiçindekidhclientile DHCP üzerinden otomatik IP atanır- Örnek:
eth0arayüzüne10.0.2.15/24atanması
- Örnek:
wget http://google.comile harici ağa başarıyla erişilir veindex.htmlindirildiği doğrulanır
Paket yöneticisi ve init’in önemi
- Genel amaçlı dağıtımlar, yazılımı dinamik olarak kurup güncellemek için paket yöneticileri kullanır
- Bu çalışmada ise gömülü sistem yaklaşımı benimsenir; tüm imajın yeniden derlenmesi gerekir
init, yalnızca basit bir süreç başlatıcısı değil; aygıt başlatma, servis yönetimi ve sistem önyükleme denetiminin temel bileşenidiru-rootiçindekiinitkaynak kodu incelenerek çeşitli aygıtların (/dev) nasıl ayarlandığı görülebilir
GitHub deposu
- Bu kılavuzun tüm kodu ve örnekleri popovicu/linux-micro-distro deposunda sunuluyor
initramfsimajı oluşturulabilir ve çalışma adımları yeniden üretilebilir
1 yorum
Hacker News görüşleri
Aylardır mikro Linux dağıtımını kendim yapıyorum
Kullanıcı modu, tek bir statik binary'den oluşuyor ve confidential microVM container desteği için sadece birkaç dosya içeriyor
Özellikle initramfs yapısı ilgi çekici. Kernel'in cpio arşivini açıp tmpfs'ye girerek /init'i çalıştırma süreci adeta sihir gibi
Birden fazla cpio arşivi art arda eklenebiliyor, her biri sıkıştırılabiliyor ve sırayla overlay ediliyor
Bu basit ama zarif tasarım sayesinde, açma kodunu kendim yazarken çok şey öğrendim
Son zamanlarda qemu, büyük mimarilerde uftrace desteği sunmaya başladı
Uzmanlar “bunu nasıl debug edeceğim?” diye sorduğunda, işte cevap bu oluyor
İlgili ayrıntılar için bu başlığa bakılabilir
Ben de benzer bir proje üzerinde çalışıyorum — azathos
İçinde kendi yaptığım toy init, shell ve birkaç yardımcı araç var
Debug için GNU coreutils ekledim ve şu anda framebuffer üzerinde pencere çizme özelliğine odaklanıyorum
Bu proje gerçekten harika. 98'de floppy tabanlı bir “dağıtım” yapıp Windows PC imaging işini UDP broadcast ile yaptığımız günleri hatırlattı
“make bzimage”, init script hataları, sonsuz reboot döngüleri… çok anı var
Bugünkü yaklaşımın da çok farklı olmaması ilginç. Raspberry Pi için port edilse hem eğlenceli hem öğretici olurdu. Belki ben de denerim
Sonunda bir arkadaşım sftp içeriğini CD'ye yazıp vermişti; o zamanlar sadece 2x hızda yazılabiliyordu
Bunu bir cloud image olarak (ör. Vultr, DigitalOcean) çalıştırmanın ya da GUI açıp Firefox çalıştırmanın ne kadar zor olacağını merak ediyorum
Başka bir dağıtımla boot edip ardından kexec ile kendi kernel'ini çalıştırarak bellekte kurulum yapmak da mümkün
Gerçek bir uygulama örneği için nixos-anywhere incelenebilir
Düşünüldüğünden daha basit bir iş
Bu projenin Raspberry Pi hedefli bir sürümü olsa gerçekten çok ilginç olurdu
İnsan neden böyle bir şeyi kendisi yapar diye merak ettim; Linux'u keşfetmek için neden sadece Gentoo kullanılmıyor diye düşündüm
User space özelleştirmesi mümkün olsa da Linux'un kendisini öğrenmek için çok uygun değil
Sadece stage3 tarball'a bakmak bile zaten “mini dağıtım” seviyesinde olduğunu gösteriyor
Öğrenmek için gerçekten harika; hızlıca bir şey ortaya çıkarmak istiyorsanız buildroot iyi bir seçenek
Bu yazı sayesinde gerçekten çok şey öğrendim. Bilgi yoğunluğu yüksek bir gönderi olduğu için teşekkürler