# Kök Dosya Sistemi Oluşturma

Gömülü sistemimizin oluşturulmasında kök dosya sisteminin üretimi önemli adımların başında gelmektedir.

Boot yükleyici ve Linux çekirdeği ile ilgili işlemler tamamlandıktan sonra, çekirdek tarafından **/** kök dizini altına bağlanacak dosya sistemimizi hazırlamalıyız. Dosya sistemimizin temellerini ise **Busybox** ile oluşturacağuz.

**Busybox** projesi **1995** yılında, Özgür Yazılım dünyasının önemli figürlerinden [Bruce Perens](http://en.wikipedia.org/wiki/Bruce_Perens) tarafından geliştirilmeye başlanmıştır. Projenin temel hedefi, 1.44 MB'lık tek bir disket içerisine temel bir Linux kök dosya sistemini ve Linux kurulum uygulamasını sığdırmak idi. O tarihlerde tipik bir Linux kurulum süreci, 2 disket ile başlıyordu. Birinci diskette Linux çekirdeği yer alıyordu. Kök dosya sistemi ise 2. disket üzerinden okunuyordu.

Linux dağıtımının kurulumu süresince bize yardımcı olan kurulum (*installer*) uygulaması da herhangi bir Linux uygulamasından farklı değildir. Dolayısıyla çalışabilmesi için alt tarafta başta standart C kütüphanesi olmak üzere, çalışan bir Linux dosya sistemine de ihtiyaç duymaktadır. Bunun yanı sıra kurulumun çeşitli aşamalarında **fdisk**, **mount**, **cp**, **mkdir**, .. vb. temel Linux araçlarının da sistemde yer alması gereklidir.

Busybox projesi derlendiğinde tek bir uygulama dosyası (**busybox**) oluşmaktadır. Bu tek uygulama içerisinde, pek çok temel Linux uygulamasına ait fonksiyonlar (kabuk, editör, dosya sistemi işlemler, disk bölümleme ve biçimlendirme araçları vb.) yer almaktadır. Busybox uygulaması içerisindeki bu fonksiyonları kullanmak için, ilgili fonksiyon ve fonksiyonun parametreleri busybox uygulamasına verilmelidir. Örnek olarak sistemde `mkdir` komutuyla `yeni` adında bir dizin yaratmak istersek, bunu `busybox` ile şu şekilde yapabiliriz:

```
$ busybox mkdir yeni
```

Eğer busybox uygulamasını derlerken `mkdir` fonksiyonlarını içeren `applet`'i de dahil etmiş isek, işlem gerçekleşecektir.

Busybox uygulamamız içerisinde hangi fonksiyonlara destek olduğunu görmek için, uygulamayı parametre vermeden çalıştırıp çıktıyı inceleyebiliriz:

```
$ busybox
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
or: busybox --install [-s] [DIR]
or: function [arguments]...

BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable.  Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.

Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl, bunzip2,
bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio,
crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd,
dnsdomainname, dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd, false,
fatattr, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold, free, freeramdisk, fsck, fsck.minix, fstrim, fsync,
ftpd, ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id,
ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule,
iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, logread,
losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom,
mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint,
mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd, od, openvt, passwd, patch, pgrep, pidof,
ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun,
rdate, rdev, readahead, readlink, readprofile, realpath, reboot, reformime, remove-shell, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm,
rpm2cpio, rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch, setconsole, setfont, setkeycodes,
setlogcons, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, shuf, slattach, sleep, smemcap, softlimit, sort,
split, start-stop-daemon, stat, strings, stty, su, sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar,
tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl, ubiattach,
ubidetach, ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, umount, uname, unexpand, uniq, unix2dos, unlink, unlzma, unlzop, unxz,
unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xz,
xzcat, yes, zcat, zcip
```

Busybox içerisinde yer alan tüm fonksiyonları, yukarıdaki örnekte gösterdiğimiz şekliyle busybox uygulamasına parametre olarak geçirmek suretiyle kullanmaya kalksaydık, özellikle kabuk betiklerimiz gereksiz tekrarlar nedeniyle oldukça çirkin görünecek, betiklerin okunabilirliği de önemli oranda azalacaktı.

Busybox bu problemi çok basit ama zekice bir yöntemle çözmektedir. Tek bir uygulamadan ibaret olmasına rağmen, `make install` komutu verildiğinde, busybox içerisinde desteği eklenmiş tüm fonksiyonlar (uygulamalar) için kendisini gösterecek şekilde sembolik linkler oluşturmaktadır. Örnek olarak, `/bin/mkdir` linki `/bin/busybox`'ı göstermekte, `/bin/cp` linki de aynı şekilde `/bin/busybox`'ı işaret etmektedir. Bu şekilde tüm gerekli linkler üretildiğinde artık uygulamaları `busybox mkdir` şeklinde değil sadece `mkdir` şeklinde çağırmamız mümkün olmaktadır. Sonuçta tüm bu linkler yüzünden aynı uygulama çalışmakta, ancak her defasında farklı isimle çağırmış olduğumuzdan `argv[0]` adresinde çağrıldığı programın ismi (örneğin mkdir) yer almaktadır. Busybox içerisindeki komut satırını parse eden bölüm, çağrılma biçimi `busybox` dışındaki bir değer ise ve bu değere ilişkin destekler uygulama içerisinde derlenmişse, kendi içinde ilgili fonksiyonu çağırmak suretiyle istenen amacı gerçekleştirmektedir.

## Konfigürasyon ve Derleme

Busybox içerisinde pek çok bileşenle geldiğinden, derleme süreci öncesinde hangi bileşenlerden oluşan bir busybox uygulaması üretmek istediğimizi belirlememiz, bunun için bir konfigürasyon dosyası üretmemiz gerekiyor.

Seçenek / kombinasyon sayısı bir kernel derleme süreci kadar devasa olmasa da, hatırı sayılır miktarda seçenek kümesi olduğunu söyleyebiliriz. Tıpkı kernel derleme konfigürasyonu sürecinde olduğu gibi, busybox konfigürasyon ve derleme işlemleri için de **Kbuild** sistemi kullanılmaktadır.

Menuconfig arayüzü üzerinden konfigürasyon sürecimizin hedefi olan `.config` dosyasını üretebiliriz. Bunun için `make menuconfig` veya aşağıdaki **make** hedeflerinden biriyle `.config` dosyamızı oluşturabiliriz:

| Make Hedefi        | Açıklama                                                                   |
| ------------------ | -------------------------------------------------------------------------- |
| menuconfig         | İnteraktif menü tabanlı seçi arabirimini çalıştırır                        |
| defconfig          | Hemen her seçeneğin aktifleştirildiği genel bir konfigürasyon sağlar       |
| allyesconfig       | Tüm olası seçeneklerin aktifleştirildiği bir konfigürasyon sağlar          |
| allnoconfig        | Tüm seçeneklerin inaktif edildiği, minimum bir konfigürasyon sağlar        |
| android\_defconfig | Android platformu için derleme yapılacaksa genel bir seçenek kümesi sağlar |

Seçim işlemi tamamlandıktan sonra

```
$ make
```

komutuyla derleme işlemi yapılabilir. Paralel derleme özelliğini `-j` parametresi ile devreye alıp (genelde işlemci çekirdek sayısının 2 katına kadar değer girebilirsiniz) derleme sürecini hızlandırabilirsiniz:

```
$ make -j 8
```

> **NOT:** Bu noktadan sonraki çapraz derleme örneklerinde, `/home/training/toolchains` dizini altına `gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux` toolchain'inin açıldığı ve PATH ortam değişkeninin uygun şekilde ayarlandığı varsayılmıştır. Cross-Compiler prefix'i `arm-linux-gnueabihf-` şeklinde olup **EABIHF** yani **Hard-Float** türünde bir toolchain'dir.

Busybox uygulamasını hedef platform için çapraz derlemek istediğimizde, kernel derleme sürecindeki benzer şekilde `ARCH` ve `CROSS_COMPILE` değişkenlerine atama yapmamız gerekecektir:

```
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j 8
```

Bu şekilde çapraz derleme süreci tamamlanacaktır.

İşlem bitiminde busybox uygulamasını tüm gerekli linkleriyle birlikte bir dizin yapısı içerisinde (aslında kök dosya sistemimizin ilk şablonu da diyebiliriz) `make install` komutuyla oluşturabiliriz. Bu komut eğer `CONFIG_PREFIX` değişkenine `.config` dosyası üretimi sürecinde farklı bir değer atanmadı ise bulunulan dizin altında, `_install` şeklinde bir alt dizin açacak ve tüm linkleri ve uygulama dosyasını bu alt dizinlerde oluşturacaktır.

```
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- CONFIG_PREFIX=/opt/cross/rootfs install
```

Yukarıdaki örnekte ARM mimarisi için çapraz derleme işlemi sonrası busybox uygulaması ve gerekli linkleri, `/opt/cross/rootfs` dizini altında oluşturulacaktır.

## NFS Üzerinden Sistemi Açarak İlerleme

> Not: Bu noktada NFS Sunucu Kurulumu ve NfsRoot bölümlerini henüz okumadı iseniz incelemeniz önerilir. Kök dosya sistemi ile ilgili burada verilen örnekler **BeagleBoneBlack** cihazı üzerinde çalıştırılmıştır.

Örneklerimizde öntanımlı `beaglebone_defconfig` ile derlenmiş çekirdek, aşağıdaki gibi **U-boot** komutları ile açılmaktadır:

```
setenv serverip 192.168.100.1
setenv ipaddr 192.168.100.5
setenv console ttyO0,115200n8
setenv rootpath /opt/cross/rootfs
setenv bootargs console=${console} root=/dev/nfs nfsroot=${serverip}:${rootpath},vers=3 rw ip=${ipaddr}
tftp 0x80200000 uImage-dtb.am335x-boneblack
bootm
```

Yukarıdaki gibi minik dosya sistemimizi `/opt/cross/rootfs` dizini altında hazır ettikten sonra, bu dizini NFS sunucumuz üzerinden paylaşıma açıp, cihazımız üzerinden yeni oluşturduğumuz bu dosya sistemiyle açılış yapmayı deneyelim.

```
[    5.320738] IP-Config: Guessing netmask 255.255.255.0
[    5.326212] IP-Config: Complete:
[    5.329625]      device=eth0, hwaddr=d0:5f:b8:ef:61:07, ipaddr=192.168.100.5, mask=255.255.255.0, gw=255.255.255.255
[    5.340641]      host=192.168.100.5, domain=, nis-domain=(none)
[    5.346837]      bootserver=255.255.255.255, rootserver=192.168.100.1, rootpath=
[    5.354377] ALSA device list:
[    5.357663]   #0: TI BeagleBone Black
[    5.369033] VFS: Mounted root (nfs filesystem) on device 0:12.
[    5.375638] devtmpfs: error mounting -2
[    5.379967] Freeing init memory: 216K
[    5.394642] Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
```

Açılış sürecimizin yukarıda belirtilen şekliyle sonlandığını gördük.

Daha önceki aşamalarda, Linux çekirdeğinin açılıştaki tüm işlemleri başarılı olarak tamamlaması halinde son 2 işlem olarak, kök dosya sistemini mount edip, kök dosya sistemi üzerinden bir adet uygulamayı başlatacağını ifade etmiştik. Yukarıdaki çıktıya baktığımızda kök dosya sisteminin NFS üzerinden başarılı bir şekilde mount edildiğini görmekteyiz:

```
[    5.369033] VFS: Mounted root (nfs filesystem) on device 0:12.
```

Fakat daha sonra `init` uygulamasının çalıştırılamadığını ve kernel panic durumu oluştuğunu görmekteyiz:

```
[    5.394642] Kernel panic - not syncing: No init found.
```

Neden böyle bir problem oluştu?

Problemin nedeni üretmiş olduğumuz dosya sistemimizde `/bin/busybox`'ı gösteren bir çok link olmasına rağmen, toplamda sadece **1** adet binary uygulama bulunmakta, paylaşımlı kütüphane dosyası ise hiç bulunmamaktadır. Hatta paylaşımlı kütüphaneleri tutacağımız `lib` dizini dahi henüz sistemimizde mevcut değildir. Yapmamız gereken, hedef platform için çapraz derleme yaptığımız `busybox` uygulamamızın bağımlı olduğu kütüphaneleri bularak, kök dosya sistemimizdeki `lib` dizini altına kopyalamaktır.

Öncelikle derlemiş olduğumuz `busybox` binary dosyasının kütüphane bağımlılıklarını bulalım. Bunun için `readelf` uygulamasını `-d` parametresi ile çağırabiliriz:

```
$ readelf -d busybox | grep Shared
  0x00000001 (NEEDED)       Shared library: [libm.so.6]
  0x00000001 (NEEDED)       Shared library: [libc.so.6]
```

Görüldüğü üzere `libc.so.6` ve `libm.so.6` kütüphanelerine ihtiyaç duymaktadır. Öncelikle kök dosya sistemimizde henüz mevcut olmayan `lib` dizinini oluşturalım:

```
$ mkdir /opt/cross/rootfs/lib
```

Sonrasında ihtiyaç duyulan 2 kütüphaneyi kopyalayalım. Peki bu kütüphaneleri nereden kopyalayacağız? Kendi geliştirme bilgisayarımızın `/lib` dizini altındakileri kopyalayamayız.

Oluşturacağımız kök dosya sistemine zaman zaman bu şekilde gereken kütüphaneleri kopyalamamız gerekecektir. Bu işlemleri çoğunlukla öncelikle ilgili kütüphaneyi ayrı bir yerde hedef platform için derleyerek, sonrasında kütüphane dosyalarını kök dosya sistemimiz altına kopyalayarak gerçekleştireceğiz.

Ancak `libc.so.6`, `libm.so.6` gibi temel kütüphaneler zaten kullandığımız toolchain içerisinde yer almaktadır. Bu kütüphaneleri yeniden derlemek, bir tür toolchain üretim süreci de gerektirdiğinden, çapraz derlemeyle ilgili bölümde de anlattığımız üzere yeniden üretmek yerine toolchain içerisinden çıkan versiyonlarını kullanmak daha sağlıklıdır.

Kullandığımız ARM eabihf toolchain'i için bu dosyalar, toolchain ana dizinini referans aldığımızda, `./arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf` dizini altında yer alır. Bulmakta sorun yaşarsanız toolchain ana dizininde iken:

```
$ find -name libc.so.6
```

gibi bir komutla da arama yapıp bulabilirsiniz.

Şimdi her iki kütüphaneyi kök dosya sistemimize kopyalayalım:

```
$ cp ./arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/libc.so.6 /opt/cross/rootfs/lib/
$ cp /arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/libm.so.6 /opt/cross/rootfs/lib/
```

Sistemimizi tekrar NFS üzerinden açtığımızda problemin devam ettiğini göreceğiz. **Busybox** uygulamamızın ihtiyaç duyduğu kütüphaneleri kök dosya sistemimize attık ancak paylaşımlı kütüphane bağımlılığı olan herhangi bir uygulamayı çalıştırabilmek için aynı zamanda `ld.so` kütüphanesine de ihtiyaç bulunmaktadır. Bu kütüphane toolchain versiyonlarına göre `ld-linux.so.2`, `ld-linux.so.3`, `ld-linux-armhf.so.3` gibi isimlerde bulunabilir. Bizim kullandığımız ARM eabihf toolchaini içerisinde bu dosya, `ld-linux-armhf.so.3` şeklindedir ve bunun da kök dosya sistemine kopyalanması gereklidir:

```
$ cp ./arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 /opt/cross/rootfs/lib/
```

ARM eabihf toolchain ile çalışan sistemimiz için son bir işlem daha yapmamız gerekiyor. `ld-linux-armhf.so.3` loader uygulaması, aynı anda eabihf ve eabi sistemleri destekleyebilmek için, yükleyeceği diğer kütüphaneleri `/lib/arm-linux-gnueabihf` dizini altında arar. Aynı anda her iki ARM ABI ile çalışmak pek karşılaşılan bir durum değildir. Bu nedenle genellikle `/lib/arm-linux-gnueabihf` dizini `/lib` dizinini gösteren bir sembolik link olarak oluşturulur:

```
$ cd /opt/cross/rootfs/lib && ln -s . arm-linux-gnueabihf
```

Artık tüm bileşenlerimiz hazır görünüyor. Cihazımızı tekrar NFS üzerinden açmayı denediğimizde, bu defa açılış sürecinin gerçekleştiğini görmekteyiz.

## `/etc/inittab` İyileştirmeleri

Artık açılan bir sistemimiz var. Fakat göreceğiniz üzere seri konsol ekranımızda aşağıdaki mesajlar sürekli olarak çıkmakta:

```
can't open /dev/tty2: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty4: No such file or directory
can't open /dev/tty2: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty4: No such file or directory
...
```

Sistemimiz açılmış ve çalışıyor durumda olmasına rağmen bu hata mesajları yüzünden konsolu efektif kullanamıyoruz. Buradaki problem sistemimizde henüz bir `/etc/inittab` dosyası olmadığı için busybox init uygulamasının öntanımlı bir `inittab` dosya içeriği varmış gibi çalışmasından kaynaklanıyor. `/dev/ttyXX` aygıtları sistemimizde yer almadığından uygulamayı çalıştıramamakta ve tekrar tekrar yaptığı denemelerden kaynaklanan hata mesajları görüntülenmektedir.

Örnek bir `inittab` dosyasını busybox kaynak kodlarını açtığımız dizinde, `examples/inittab` yolunda bulabiliriz. Bu dosyanın içeriği **Init Süreci**'nin anlatıldığı bölümde detaylandırılmıştır.

Sistemimiz için aşağıdaki `inittab` dosyasını kullanacağız:

```
::sysinit:/etc/acilis
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/kapanis
```

Yukarıdaki içeriğe sahip dosyayı `/opt/cross/rootfs/etc/inittab` şeklinde oluşturup ardından sitemimizi tekrar açmayı denediğimizde, daha önce aldığımız hata mesajlarının ortadan kalktığını ama yenilerinin geldiğini görmekteyiz:

```
can't run '/etc/acilis': No such file or directory

Please press Enter to activate this console.
getty: can't open '/dev/null': No such file or directory
getty: can't open '/dev/null': No such file or directory
getty: can't open '/dev/null': No such file or directory
getty: can't open '/dev/null': No such file or directory
getty: can't open '/dev/null': No such file or directory
...
```

`/etc/acilis` dosyamızı henüz hazırlamadığımız için onunla ilgili aldığımız hata normaldir. Ancak sonrasında sürekli `/dev/null` dosyasının yer almadığına dair hatalar almaktayız ve bu hata mesajları yüzünden gene konsolumuzu kullanamıyoruz. Kullandığımız çekirdek içerisinde **DEVTMPFS** ve **DEVTMPFS\_MOUNT** desteği açıktır dolayısıyla `/dev` dizini altındaki aygıt dosyalarının çekirdek tarafından otomatik üretilmesi gerekirdi (detaylar için **Devtmps Dosya Sistemi** bölümüne bakınız). Buna rağmen `/dev` dizini altına bu özel dosya sisteminin çekirdek tarafından otomatik olarak bağlanamadığını görüyoruz. Bunun çok basit bir nedeni var: minik dosya sistemimizde henüz `/dev` dizini mevcut değil.

Mount işleminin başarılı olabilmesi için gerekli şartlardan biri, mount edilecek dizinin de öncesinde sistemde bulunmasıdır (örneğimizde `/dev` dizini).

Bu sorunu çözmek için kök dosya sistemimizde aşağıdaki komutla `/dev` dizinini oluşturalım:

```
$ mkdir /opt/cross/rootfs/dev
```

Sonrasında sistemi tekrar NFS üzerinden açalım:

```
[    5.368528] VFS: Mounted root (nfs filesystem) on device 0:12.
[    5.375468] devtmpfs: mounted
[    5.378895] Freeing init memory: 216K
can't run '/etc/acilis': No such file or directory

Please press Enter to activate this console. 
/ #
```

Nihayet sistemimizi görece uygun bir şekilde açmayı başardık. Mesajları incelediğimizde `devtmpfs` mount işleminin gerçekleştiğini görüyoruz. `/etc/acilis` betiğimiz henüz hazır olmadığından hata alıyoruz ancak konsola düşmeyi başardık. `ls /dev` komutuyla `/dev` dizini altındaki dosyaları görebiliriz.

Şimdi çalışan uygulamaların listesini `ps` komutuyla almayı deneyelim:

```
/ # ps
PID   USER     TIME   COMMAND
ps: can't open '/proc': No such file or directory
```

Görüldüğü üzere `/proc` dizininin sistemde olmadığına dair bir hata alıyoruz ve process listesini de göremiyoruz.

Sistemimizi yeniden başlatmayı deneyelim:

```
/ # reboot
reboot: can't open '/proc': No such file or directory
```

Bu işlem için de `/proc` dizinine ihtiyaç olduğu görülüyor. Çalışan bir Linux sisteminde `proc` dosya sisteminin `/proc` altına mount edilmiş durumda olması önemlidir. Bu dizin altındaki pek çok dosya ve dizin üzerinden, kullanıcı kipindeki uygulamalar çekirdek ile haberleşebilir ve bir takım işlemleri gerçekleştirebilirler.

Şu ana kadar `proc` dosya sistemini mount etmiş olmamamıza rağmen sistemimiz -yeterince işlevsel olmasa da- çalışıyordu, dolayısıyla bu tarz işlemler için çekirdek tarafından bir yardım beklememeliyiz. Bu süreci kullanıcı kipinde gerçekleştirmemiz lazım. Sistem her açıldığında `mount` komutu ile `proc` dosya sistemini `/proc` dizini altına bağlamalıyız.

`/dev` dizini için yaptığımız örnekte olduğu gibi, öncesinde `/proc` dizinini kök dosya sistemimizde oluşturalım:

```
$ mkdir /opt/cross/rootfs/proc
```

Şimdi `/etc/acilis` betiğini `/opt/cross/rootfs/etc/acilis` ismiyle oluşturmaya başlayalım:

```
#! /bin/sh
echo "Sistem acilisi basladi"
echo "proc dosya sistemi baglaniyor"
mount -t proc none /proc
```

Dosyayı oluşturduktan sonra çalıştırma haklarını vermemiz gerekiyor:

```
$ chmod 755 /opt/cross/rootfs/etc/acilis
```

Tekrar sistemi NFS üzerinden açtığımızda hiç hata almadan sistemin açıldığını görebiliriz:

```
[    5.374822] devtmpfs: mounted
[    5.378254] Freeing init memory: 216K
Sistem acilisi basladi
proc dosya sistemi baglaniyor

Please press Enter to activate this console. 
/ #
```

Artık `ps`, `top`, `ifconfig`, `reboot` vb. pek çok uygulama olması gerektiği gibi çalışmaya başlayacaktır. `reboot` komutunu tekrar deneyelim:

```
/ # reboot
can't run '/etc/kapanis': No such file or directory
The system is going down NOW!
Sent SIGTERM to all processes
```

Reboot gerçekleşti ancak `/etc/kapanis` uygulaması henüz hazır olmadığından bir hata mesajı aldık. Bu dosyayı da oluşturalım. Temel olarak kapanış sürecinde, tüm mount edilmiş dosya sistemlerinin unmount edilmesini sağlamamız yerinde olacaktır. Unmount işlemi Linux *Page Cache* tablolarının depolama ortamlarına yazılmasını tetikler, böylece kapanış sırasında veri kaybı sorunu yaşamazsınız. Aksi takdirde **Write-Back** mekanizması nedeniyle veri kayıplarıyla karşılaşabilirsiniz.

```
#! /bin/sh

echo "Sistem kapatiliyor"
umount -a -r
```

Aynı şekilde çalıştırma haklarını vermemiz gerekiyor:

```
$ chmod 755 /opt/cross/rootfs/etc/kapanis
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://murat-demirten.gitbook.io/gomulu-linux/prepare.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
