- Kendi dağıtımınızı oluşturmak: Bölüm 1
- Kendi dağıtımınızı oluşturmak: Bölüm 3
- Kendi dağıtımınızı oluşturmak: Bölüm 2
Geçen bölümde initramfs imajı oluşturmayı ve test etmeyi anlatmıştık. Bu bölümde minimal kök dizin (rootfs) oluşturmayı ve static ve dynamic dosyalar arasındaki farkları anlatacağız.
Static ve Dynamic derleme
Static bir dosya herhangi bir bağımlılığa ihtiyaç duymazken dynamic derlenmiş bir dosyanın bağımlılıkları bulunur. Bir dosyanın dynamic olup olmadığını anlamak için ldd komutu kullanılır.
$ ldd busybox not a dynamic executable $ ldd /bin/bash linux-vdso.so.1 (0x00007ffd63d6a000) libreadline.so.8 => /lib64/libreadline.so.8 (0x00007f6121182000) libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007f6121141000) libc.so.6 => /lib64/libc.so.6 (0x00007f6120f71000) libtinfow.so.6 => /lib64/libtinfow.so.6 (0x00007f6120f30000) /lib64/ld-linux-x86-64.so.2 (0x00007f61212d2000)
Bütün dynamic derlemiş dosyalar libc.so.6 dosyasına ve ld-linux-x86-64.so.2 interpreter dosyasına ihtiyaç duyar. Bunun dışında kalanlar uygulamanın kullandığı ek kütüphanelerden gelen bağımlılıklardır. Linux adğıtımlarındaki bağımlılık ağacı bunlar dikkate alınarak oluşturulur.
Şimdi aşağıdaki gibi bir C kaynak kodumuz olsun ve bu kaynak kodu derleyelim.
#include <stdio.h> int main(){ puts("Hello Word"); return 0; }
# dynamic derleyelim gcc -o main.dynamic main.c # static derleyelim gcc -o main.static main.c -static
ldd komutu ile her ikisini de kontrol edebilirsiniz.
Static dosyaları boyutu daha yüksektir çünkü gerekli olan tüm kütüphaneler tek bir dosyaya eklendiği için boyutunun artmasına neden olur. Bu yüzden dağıtımlarda genellikle static yerine dynamic derleme tercih edilir.
Minimal rootfs oluşturma
Şimdi dynamic derlenmiş bir dosyamızdan rootfs oluşturalım. Bunun için öncelikle dosyamızı boş bir dizine kopyalayalım ve file komutunu kullanarak interpreter adını öğrenelim.
$ file main main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped
Burada /lib64/ld-linux-x86-64.so.2 dosyası bizim dizinimizde de aynı yerde bulunmalıdır. Bu sebeple lib64 dizini açalım ve içerisine kopyalayalım.
$ mkdir lib64 $ install /lib64/ld-linux-x86-64.so.2 lib64/
Linux dağıtımlarında /lib dizini bulunur. Bizdeki lib64 dizinini buraya sembolik bağ atabiliriz.
$ ln -s lib64 lib
Şimdi de ldd komutunu kullanarak bağımlılıklarını bulalım ve onları da kopyalayalım.
$ ldd main linux-vdso.so.1 (0x00007ffd1efe6000) libc.so.6 => /lib64/libc.so.6 (0x00007f0af6a13000) /lib64/ld-linux-x86-64.so.2 (0x00007f0af6bfe000) # interpreter zaten kopyalandığı için ikinci kere kopyalamıyoruz. # linux-vdso.so.1 sistemde dosya olarak bulunmaz. linux çekirdeğinden gelir. Onu da kopyalamıyoruz. # Bu durumda sadece libc.so.6 dosyamızı kopyalamamız gerekiyor. $ install /lib64/libc.so.6 lib64
Şimdi rootfs oluşturmuş olduk. Test etmek için chroot <rootfs> /main komutunu kullanabiliriz.
$ chroot . /main Hello Word
Gördüğünüz gibi minimal rootfs elde ettik ve çalıştırdık. İstersek rootfs dizinimizi initramfs haline getirebiliriz. Derlediğimiz dosyayı /init dosyası yerine koyalım ve tekrar paketleyelim. Aşağıdaki gibi kernel panic hatası verecektir. Bunun sebebi sistemin ana sürecinin (pid 1) kapatılmamasının gerekliliğidir.
Initramfs içerisindeki init linux dağıtımlarında sistemin kurulu olduğu bölümü bağlayıp içerisindeki servis yöneticisini başlatmak için kullanılır. Servis yöneticileri ise asla kapanmamak üzere tasarlanmıştır. Biz bu örneğimizdeki C kodunu aşağıdaki gibi değiştirerek kapanmasını engelleyebiliriz.
#include <stdio.h> int main(){ puts("Hello Word"); while(1); return 0; }
Şimdi tekrar derleyip initramfs imajımızı paketleyelim.
Gördüğünüz gibi kodumuz çıkış yapmadığı için kernel panic hatası almıyoruz.