Dosya Sisteminin Hazırlanması
Bu bölümde Raspberry Pi board'umuz için busybox ile basit bir dosya sistemi hazırlanmasına yönelik çalışmalar anlatılacaktır. Dosya sistemi hazırlanmasıyla ilgili daha detaylı bilgiler için Kök Dosya Sistemi Oluşturma başlıklı bölümün de incelenmesini öneririz.
Busybox
Öncelikle güncel busybox kaynak kodlarını indirip diskimizde bir dizine açmalıyız:
$ wget http://www.busybox.net/downloads/busybox-1.23.2.tar.bz2
$ tar xf busybox-1.23.2.tar.bz2
$ cd busybox-1.23.2
Ardından öntanımlı konfigürasyonunu oluşturup, PATH
ortam değişkenimiz içerisinde daha önce ayarlanmış olan toolchain önekini kullanarak çapraz derleme işlemimizi gerçekleştirebiliriz:
$ make defconfig
$ make CROSS_COMPILE=arm-bcm2708hardfp-linux-gnueabi- -j4
Derleme işlemi tamamlandıktan sonra busybox
uygulaması ana dizinde oluşacaktır. Daha önce anlatıldığı gibi busybox uygulamasını içerdiği diğer uygulamalara ait linkleri de oluşturmak suretiyle kullanmamız gereklidir. Bu linkleri oluşturmak için make install
komutunu verebiliriz ancak bu durumda ilgili linkler bulunduğumuz yerde _install
adlı bir dizinde üretilecektir. Bunun yerine örneğin /opt/rpi
şeklinde genel bir dizin açıp orayı kök dosya sistemi olarak hazırlamak daha yerinde bir karar olacaktır. Aşağıdaki gibi CONFIG_PREFIX
değişkenine atama yapmak suretiyle linklerin ilgili dizinde oluşturulması sağlanabilir:
$ sudo mkdir /opt/rpi
$ sudo chown -R $USER /opt/rpi
# Yukarıdaki 2 komutla /opt/rpi dizinini oluşturup yazma yetkilerini
# kendi kullanıcımıza vermiş olduk. Bu amaçla herhangi başka bir dizini de kullanabilirsiniz
$ make CROSS_COMPILE=arm-bcm2708hardfp-linux-gnueabi- CONFIG_PREFIX=/opt/rpi install
İşlem başarıyla tamamlandıktan sonra /opt/rpi
altında aşağıdaki dosya ve dizinlerin oluştuğu görülecektir:
$ ls -l /opt/rpi/
total 8
drwxr-xr-x 2 demirten demirten 4096 Jun 23 15:59 bin
lrwxrwxrwx 1 demirten demirten 11 Jun 23 15:59 linuxrc -> bin/busybox
drwxr-xr-x 2 demirten demirten 4096 Jun 23 15:59 sbin
drwxr-xr-x 4 demirten demirten 27 Jun 23 15:59 usr
Yukarıdaki dizin yapısı kök dosya sistemimizin temelini oluşturmaktadır. Ancak bir kaç ek dokunuşa daha ihtiyaç olacaktır.
Sistemimizi yukarıdaki kök dosya sistemiyle açmaya çalışacak olursa, kernel tarafında aşağıdakine benzer bir hata alırız:
...
[ 2.492921] devtmpfs: error mounting -2
...
Yukarıdaki hata mesajında devtmpfs
dosya sisteminin mount edilemediği söylenmektedir. Konuyla ilgili daha ayrıntılı bilgiye Devtmpfs Dosya Sistemi bölümümüzden erişebilirsiniz. Bu sürecin doğru işlemesini sağlamak için hazırladığımız yeni kök dosya sistemi içerisinde /dev
dizinini aşağıdaki komutla oluşturmalıyız:
$ mkdir /opt/rpi/dev
Kütüphanelerin Taşınması
Busybox sayesinde tek bir uygulama ile pek çok komuta birden sahip olduk, ancak busybox uygulamasının çalışabilmesi için gereken libc.so.6
, libm.so.6
ve libcrypt.so.1
kütüphaneleri ile paylaşımlı kütüphane kullanan tüm uygulamalar için gerekli olan ld-linux.so.3
kütüphanesi de kök dosya sistemimizde /lib
dizini altında yer almalıdır.
Bunun için öncelikle /lib
dizinimizi oluşturalım:
$ mkdir /opt/rpi/lib
Ardından ilgili kütüphanelerin kullandığımız toolchain içerisinden çıkan versiyonlarını bu dizin altına kopyalayalım. Bu noktada Çapraz Derleme ve Gerekli Ekipmanlar başlığından da faydalanabilirsiniz.
Raspberry Pi için daha önce edindiğimiz tools
dizini altındaki arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi
toolchain'ini kullanmaktaydık. Burası toolchain ana dizinidir (Raspberry Pi için tools
arşivinden 4 adet toolchain çıkmaktadır, biz burada örneklerimizde kullandığımız versiyon ile ilerliyoruz, diğer toolchain'leri kullandı iseniz sonraki komutları da bu doğrultuda değiştirmeniz gerekecektir).
Toolchain ana dizini altında arm-bcm2708hardfp-linux-gnueabi --> lib
dizin yapısı içerisinde ihtiyaç duyduğumuz kütüphaneler bulunmaktadır. Toolchain ana dizininde iken aşağıdaki komutlarla bunları kök dosya sistemimize kopyalayalım:
$ cd arm-bcm2708hardfp-linux-gnueabi/lib
$ cp libc.so.6 libm.so.6 libcrypt.so.1 ld-linux.so.3 /opt/rpi/lib/
Artık hem busybox uygulamamız hem de uygulamanın çalışması için gereken tüm bileşenler hazır. Şimdi temel açılış ve kapanış betiklerimizi hazırlayalım.
Açılış Betiğinin Hazırlanması
Linux sistemlerde açılış sürecini yöneten SysV Init uygulamasının küçük bir versiyonu busybox içerisinden çıkmakta ve /sbin/init
şeklinde kök dosya sistemi üzerinde linki üretilmektedir.
init
uygulaması gömülü sistemimizde de ilk çalışacak uygulama olup, çalışmaya başladığında /etc/inittab
dosyasını okumaktadır. Bu dosya mevcut değilse, kendisi öntanımlı ayarlarıyla açılacaktır. Açılış ve kapanış sürecini tam kontrolümüz altına almak için /etc/inittab
dosyasını oluşturmalıyız. Dosyanın bir örneğine busybox kaynak kod dizini altında examples/inittab
şeklinde erişebilirsiniz.
Bizim kullanacağımız temel inittab
dosyası aşağıdaki gibi olacaktır:
::sysinit:/etc/acilis
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/kapanis
Yukarıdaki dosya init
uygulaması tarafından okunduğunda şunlar anlaşılır:
- Sistemde
init
tarafından çalıştırılacak ilk uygulama/etc/acilis
olacaktır - Sistemin çekirdek tarafında ayarlanmış olan konsol aygıtı üzerinde, askfirst yöntemiyle
/bin/sh
kabuğu çalıştırılacaktır - Sisteme doğrudan bağlı bir klavye olması halinde CTRL-ALT-DEL tuş kombinasyonu kullanıldığında
/sbin/reboot
uygulaması çalıştırılacaktır - Sistem kapanış sürecine geçtiğinde
/etc/kapanis
uygulaması çalıştırılacaktır
/etc/acilis
betiğinin küçük bir örneği aşağıdaki gibidir:
#! /bin/sh
echo "Sistem aciliyor..."
# Proc dosya sistemini mount edelim
mount -t proc none /proc
# Sysfs dosya sistemini mount edelim
mount -t sysfs none /sys
# Opsiyonel olarak /tmp dizinini bellek üzerinde
# tmpfs dosya sistemiyle oluşturalım
mount -t tmpfs none /tmp
# devtmpfs /dev üzerine overwrite edeceğinden
# mount etmeden önce dizini oluşturalım
mkdir -p /dev/pts && mount -t devpts none /dev/pts
Yukarıdaki açılış betiğine, kullanacağınız diğer servis ve uygulamaları başlatacak komutları da ekleyerek nihai sisteminizi üretebilirsiniz.
Kapanış betiğinde ise çalışan uygulamalarınıza TERM
sinyali yollayıp biraz beklemek, halan kapanmadı iseler KILL
sinyali göndererek uygulamaları sonlandırmak ve son adımda yazılabilir olarak kullandığınız disk bölümlerini unmount etmeli veya read-only (salt okunur) modda yeniden mount (remount) etmelisiniz. Yazılabilir modda mount edilmiş olan bir bölümü read-only remount etmek, Linux çekirdeği tarafından fiziksel olarak diske yazılmak için bekletilen tüm verilerin yazılmasını tetikler, böylelikle kapanışta veri kaybı yaşamamış olursunuz. Bu işlemi yapmamanız halinde, cihazın kontrolsüz kapatılmasındakine benzer sorunlarla karşılaşırsınız. Aşağıda basit bir /etc/kapanis
betik örneği verilmiştir:
#! /bin/sh
echo "Sistem kapaniyor"
# Tüm uygulamalara TERM sinyali gönder
kill -s SIGTERM -1
# 3 saniye bekle
sleep 3
# Halen uygulama kaldı ise KILL sinyali gönder
kill -s SIGKILL -1
# Tüm mount edilmiş bölümlerin unmount edilmesini sağlayalım
# -r parametresi, umount işlemi başarısız olursa
# read-only modda remount edilmesini sağlar
umount -a -r
quiet
Parametresi
Çekirdek boot parametreleri arasına (bir sonraki bölümde cmdline.txt
dosyasına yazacağımız) quiet
parametresini eklemeniz halinde açılış sırasında sistem konsoluna çok daha az mesaj çıkartılır.
Bu işlem açılış süresinin de bir miktar kısalmasını sağlamaktadır. Sistemi ilk ayağa kaldırırken tüm çekirdek açılış mesajlarını konsolda görmek yerinde olacaktır. Ancak sistem kararlı hale geldikten sonra quiet
parametresini eklemek suretiyle süreci hızlandırmanız önerilir. Bu parametre ile açılışta göremediğiniz mesajlara sonraki bir anda dmesg
komut çıktısından gene erişebilirsiniz.
Bu parametrenin mevcut çekirdek konfigürasyonumuzdaki etkisini test etmek için şöyle bir yöntem izleyebiliriz. Eğer kullanıcı kipinde çalıştırılan ilk uygulama (init
) üzerinden yukarıdaki örnekte çalıştırdığımız /etc/acilis
betiğimizde ilk iş olarak çekirdek mesajları tampon bölgesine bir mesaj gönderecek olursa, quiet
parametresinin olduğu ve olmadığı açılışları karşılaştırabiliriz.
Çekirdek mesajlarının tutulduğu tampon alanına, /dev/kmsg
özel aygıt dosyasına yazmak suretiyle biz de bir mesaj koyabiliriz. Yukarıdaki örneğini verdiğimiz /etc/acilis
betiği içerisinde diğer komutları çalıştırmadan önce aşağıdaki satırı ekleyelim:
echo "quiet test mesaji" > /dev/kmsg
Ardından quiet
parametresinin olduğu ve olmadığı durumlarda, dmesg | grep "test mesaji"
komutu ile mesajların çıkartılma zamanlarına bakarak karşılaştıralım:
quiet
olmadığında:
dmesg | grep "test mesaji"
[ 2.698438] quiet test mesaji
quiet
olduğu durumda:
dmesg | grep "test mesaji"
[ 1.615022] quiet test mesaji
Görüldüğü üzere 1 saniyenin üzerinde bir zaman kazancı söz konusudur.
Kullandığınız çekirdek konfigürasyonu, GPU tarafına ayrılan bellek (16 MB olduğunda GPU'daki bazı fonksiyonlar devre dışı kalmaktadır, Sistem Konfigürasyonu sayfasında detayına bakabilirsiniz), ARM CPU overclock ve turbo parametrelerinin durumuna göre bu süreler değişkenlik gösterebilir. Yaptığımız testlerde kullanıcı kipinde uygulama çalıştırmaya minimum 1.1 saniye içerisinde gelebildiğimizi gördük.