Linux'u tamamen önyüklemek için gereken minimum kök dosya sistemi uygulamaları nelerdir?


17

Bu kullanıcı alanı uygulamaları hakkında bir soru, ama beni dinleyin!

Linux'un işlevsel bir dağıtımını başlatmak için üç "uygulama" gereklidir:

  1. Bootloader - Zor bir gereksinim olmamasına rağmen, genellikle U-Boot gömülüdür.

  2. Çekirdek - Bu oldukça basit.

  3. Kök Dosya Sistemi - Onsuz bir kabuğa önyükleme yapılamaz. Çekirdeğin önyüklendiği ve initform olarak adlandırılan dosya sistemini içerir .

Sorum # 3 ile ilgili. Birisi son derece minimal bir rootfs oluşturmak istiyorsa (bu soru için sadece GUI yok, sadece kabuk diyelim), bir kabuğa önyükleme yapmak için hangi dosyalar / programlar gereklidir?


Minimali tanımlayın. Superuser.com/a/991733/128124 adresinde açıklandığı gibi sadece tek bir yürütülebilir dosyayı kullanabilirsiniz. Her çıkış veya panik yapamayacağı için sonsuz bir döngüye veya uzun bir uykuya ihtiyacınız vardır. Benzer soru: unix.stackexchange.com/questions/17122/…
Ciro Santilli 事件 改造 中心 法轮功 六四 事件

Yanıtlar:


33

Bu tamamen cihazınızda hangi servislerin olmasını istediğinize bağlıdır.

Programlar

Linux önyüklemesini doğrudan bir kabuğa dönüştürebilirsiniz . Üretimde - orada oturan bir kabuk olmasını isteyenler - çok yararlı değil, ancak etkileşimli bir önyükleyiciniz olduğunda bir müdahale mekanizması olarak yararlıdır: init=/bin/shçekirdek komut satırına geçin. Tüm Linux sistemlerinde (ve tüm unix sistemlerinde) Bourne / POSIX tarzı bir kabuk bulunur /bin/sh.

Bir dizi kabuk yardımcı programına ihtiyacınız olacak . BusyBox çok yaygın bir seçimdir; o dosya ve metin işlemleri (bir kabuk ve ortak programları içeren cp, grepağ kur, ...) ( ping, ifconfig, ...), proses manipülasyon ( ps, nice, ...) ve diğer çeşitli sistem araçları ( fdisk, mount, syslogd, ...). BusyBox son derece yapılandırılabilir: uygulamanız için doğru boyut / işlevsellikten ödün vermek için hangi araçları istediğinizi ve hatta derleme sırasında tek tek özellikleri seçebilirsiniz. Bunun dışında sh, gerçekten sen misin olmadan bir şey yapamaz o çıplak asgari mount, umountve halt, ama aynı zamanda yok etmek atipik olurdu cat, cp, mv, rm,mkdir, rmdir, ps, syncVe birkaç tane daha. BusyBox busybox, her yardımcı program için sembolik bir bağlantı ile adlandırılan tek bir ikili olarak kurulur .

Normal bir unix sistemindeki ilk işleme denir init. Görevi diğer hizmetleri başlatmaktır. BusyBox bir init sistemi içerir. initİkili /sbindosyaya ek olarak (genellikle içinde bulunur ), /etc/inittabhangi hizmetlerin başlatılacağını gösteren yapılandırma dosyalarına (genellikle denilen - bazı modern init değiştirme işlemleri bu dosyayla ortadan kaldırılır, ancak küçük bir gömülü sistemde bulamazsınız) ihtiyacınız olacaktır. ve ne zaman. BusyBox /etc/inittabiçin isteğe bağlıdır; eksikse, konsolda bir kök kabuk alırsınız ve komut dosyası /etc/init.d/rcS(varsayılan konum) önyükleme sırasında yürütülür.

Tabii ki, cihazınızı kullanışlı hale getiren programların ötesinde ihtiyacınız olan tek şey bu. Örneğin, bir OpenWrt varyantı çalıştıran ev yönlendiricimde yalnızca programlar BusyBox nvram( NVRAM'deki ayarları okumak ve değiştirmek için) ve ağ yardımcı programlarıdır.

Tüm yürütülebilir dosyalarınız statik olarak bağlı olmadıkça, dinamik yükleyiciye ( ld.solibc seçimine ve işlemci mimarilerine bağlı olarak farklı adlarla çağrılabilir) ve gerektirdiği tüm dinamik kütüphanelere ( /lib/lib*.sobelki de bunlardan bazıları /usr/lib) ihtiyacınız olacaktır. çalıştırılabilir.

Dizin yapısı

Dosya Sistemi Hiyerarşi Standart Linux sistemlerinin ortak dizin yapısını açıklar. Masaüstü ve sunucu kurulumlarına yöneliktir: birçoğu gömülü bir sistemde atlanabilir. İşte tipik bir minimum.

  • /bin: yürütülebilir programlar (bazıları /usr/binbunun yerine olabilir ).
  • /dev: cihaz düğümleri (aşağıya bakınız)
  • /etc: yapılandırma dosyaları
  • /lib: dinamik yükleyici dahil paylaşılan kütüphaneler (tüm yürütülebilir dosyalar statik olarak bağlı değilse)
  • /proc: proc dosya sistemi için bağlama noktası
  • /sbin: yürütülebilir programlar. İle ayrım /binDİR /sbinsadece sistem yöneticisi için yararlı olan programlar için, ama bu ayrım gömülü cihazlarda anlamlı değildir. /sbinİle sembolik bir bağlantı yapabilirsiniz /bin.
  • /mnt: bakım sırasında bir çizik bağlama noktası olarak salt okunur kök dosya sistemlerine sahip olmak kullanışlı
  • /sys: sysfs dosya sistemi için bağlama noktası
  • /tmp: geçici dosyalar için konum (genellikle bir tmpfsbağlama)
  • /usr: Alt dizinlerinin bulunduğu bin, libve sbin. /usrkök dosya sisteminde bulunmayan ekstra dosyalar için var. Buna sahip değilseniz /usr, kök dizine sembolik bir bağlantı yapabilirsiniz .

Cihaz dosyaları

Aşağıda bazı tipik girişler verilmiştir /dev:

  • console
  • full (ona yazmak her zaman “cihazda boş alan kalmaz” raporunu verir)
  • log(günlük girişlerini göndermek için programların kullandığı bir soket), ondan bir syslogddaemon (BusyBox gibi) okuyorsanız
  • null (her zaman boş olan bir dosya gibi davranır)
  • ptmxve bir ptsdizin kullanmak istiyorum, sözde terminalleri (konsol yani daha herhangi bir uç, diğer) - Cihaz ağ örn ise ve Telnet veya SSH içinde istediğiniz
  • random (rastgele bayt döndürür, engelleme riski)
  • tty (her zaman programın terminalini belirler)
  • urandom (rastgele bayt döndürür, hiçbir zaman engellemez, ancak yeni önyüklenen bir cihazda rastgele olmayabilir)
  • zero (sonsuz bir boş bayt dizisi içerir)

Bunun ötesinde, donanımınız için girişlere ihtiyacınız olacak (ağ arayüzleri hariç, bunlar içeri girmiyor /dev): seri bağlantı noktaları, depolama vb.

Katıştırılmış aygıtlar için, aygıt girişlerini normalde doğrudan kök dosya sisteminde oluşturabilirsiniz. İleri teknoloji sistemlerde girişler MAKEDEVoluşturmak için bir komut dosyası /devbulunur, ancak katıştırılmış bir sistemde komut dosyası genellikle görüntüye dahil edilmez. Bazı donanımlar çalışırken takılabilirse (örneğin, aygıtta bir USB ana bilgisayar bağlantı noktası varsa), udev/dev tarafından yönetilmelidir (kök dosya sisteminde hala minimum bir ayarınız olabilir).

Önyükleme zamanı eylemleri

Kök dosya sisteminin ötesinde, normal çalışma için birkaç tane daha bağlamanız gerekir:

  • procfs on /proc(hemen hemen vazgeçilmez)
  • sysfs on /sys(hemen hemen vazgeçilmez)
  • tmpfsdosya sistemi açık /tmp(programların, flash veya salt okunur olabilecek kök dosya sisteminden ziyade RAM'de olacak geçici dosyalar oluşturmasına izin vermek için)
  • dinamikse tmpfs, devfs veya devtmpfs açık /dev(yukarıdaki “Cihaz dosyaları” nda udev konusuna bakın)
  • /dev/pts[sözde terminaller kullanmak istiyorsanız devpts on ( ptsyukarıdaki konuya bakınız)

Bir /etc/fstabdosya ve çağrı yapabilir mount -aveya mountmanuel olarak çalıştırabilirsiniz .

Günlük yazmak için herhangi bir yeriniz varsa, bir syslog arka plan programı (ayrıca program ilgilenmezse klogdçekirdek günlükleri syslogdiçin) başlatın.

Bundan sonra, cihaz uygulamaya özel hizmetleri başlatmaya hazırdır.

Bir kök dosya sistemi nasıl yapılır

Bu uzun ve çeşitli bir hikaye, bu yüzden burada yapacağım tek şey birkaç işaret vermek.

Kök dosya sistemi RAM'de (ROM veya flash'ta (genellikle sıkıştırılmış) bir görüntüden yüklü) veya disk tabanlı bir dosya sisteminde (ROM veya flashta depolanır) veya varsa ağdan (genellikle TFTP üzerinden ) yüklenebilir . Kök dosya sistemi RAM içindeyse , onu initramfs yapın - açılışta içeriği oluşturulan bir RAM dosya sistemi.

Gömülü sistemler için kök görüntüleri birleştirmek için birçok çerçeve mevcuttur. BusyBox SSS'de birkaç işaretçi var . Buildroot , Linux çekirdeğine ve BusyBox'a benzer bir kurulumla tam bir kök görüntü oluşturmanıza izin veren popüler bir tanesidir. OpenEmbedded böyle bir çerçevedir.

Wikipedia'da popüler yerleşik Linux dağıtımlarının (eksik) bir listesi vardır . Yakınınızda bulunabilecek gömülü Linux'un bir örneği, ağ cihazları için ( Openinker'in ev yönlendiricilerinde popüler olan) OpenWrt işletim sistemleri ailesidir. Deneyimle öğrenmek istiyorsanız, Scratch'tan Linux'u deneyebilirsiniz , ancak hobi uzmanları için yerleşik cihazlara değil masaüstü sistemlerine yöneliktir.

Linux ve Linux çekirdeği hakkında bir not

Linux çekirdeğinde pişirilen tek davranış, önyükleme zamanında başlatılan ilk programdır. ( Burada initrd ve initramfs inceliklerine girmeyeceğim .) Geleneksel olarak init olarak adlandırılan bu programın işlem kimliği 1 ve belirli ayrıcalıkları ( KILL sinyallerine bağışıklık ) ve sorumlulukları ( yetim yetimleri ) vardır. Bir Linux çekirdeği ile bir sistemi çalıştırmak ve ilk süreç olarak istediğini başlamak ama sonra ne var Linux çekirdeği dayalı bir işletim sistemidir ve normalde “Linux” denir değil ne olabilir -  Linux , içinde sağduyu terimi, çekirdeği Linux çekirdeği olan Unix benzeri bir işletim sistemidir.. Örneğin Android, Unix benzeri olmayan ancak Linux çekirdeğine dayanan bir işletim sistemidir.


Mükemmel cevap. Sadece açılışı belirtilen içine ihtiyaçları daha yaygın bilgi olması yani, muhtemelen, için Linux Kernel vs Linux bu kadar büyük bir katkı aranır ne başlık b / c Linux.
MDMoore313

@BigHomie Unutmayın, Özgür Yazılım Vakfı hepimizden GNU / Linux dememizi ister, çünkü çoğu (hepsi?) "Linux dağıtımları" çekirdeği Linux olsa bile yazılım GNU'dur (dolayısıyla GNU / Linux).
BenjiWiebe

Meh, bunun için kimsenin vakti yok. O zaman dağıtımım Busybox / Linux olarak mı adlandırılmalı ?? Biliyorum biliyorum, bu sadece onun havalandırma Stallworth değil;)
MDMoore313 29:14

1
@ BenjiWiebe Veya GNU / X11 / Apache / Linux / TeX / Perl / Python / FreeCiv . RMS dışında herkes buna “Linux” diyor.
Gilles 'SO- kötü olmayı bırak'

@Gilles Sanırım, Debian dışında. :)
CV

5

İhtiyacınız olan tek şey, dosya sistemine ayrı bir şekilde yerleştirilmiş statik olarak bağlı bir yürütülebilir dosyadır. Başka dosyaya ihtiyacınız yok. Bu yürütülebilir dosya başlatma sürecidir. Meşgul kutusu olabilir. Bu size kendi içinde bir kabuk ve bir dizi başka yardımcı program sağlar. Kök dosya sistemi okuma-yazma, oluşturma / geliştirme düğümleri, yürütme gerçek başlatma vb.


Meşgul kutusunun geldiğini biliyordum. Bakalım başka bir şey var mı?
MDMoore313

4

Herhangi bir kabuk yardımcı programına ihtiyacınız yoksa, statik olarak bağlı bir mkshikili (örn. Linux / i386'da klibc - 130K'ya karşı) yapacaktır. Bir ihtiyaç /linuxrcyoksa /initya /sbin/initsenaryoyu bu sadece çağrılar mksh -l -T!/dev/tty1bir döngü içinde:

#!/bin/mksh
while true; do
    /bin/mksh -l -T!/dev/tty1
done

-T!$ttySeçeneği bir son ektir mkshgöz önüne alındığında, terminal üzerinde yeni bir kabuk yumurtlamaya ve bunun için beklemek söyler. (Bundan önce, orada sadece oldu -T-bir programm ve dæmonise için -T$tty. Bu kadar güzel değildi. Bir terminal üzerinde spawn ama bunun için beklemek) -l(okur hangi seçeneği sadece bir giriş kabuğu çalıştırmak için bunu söyler /etc/profile, ~/.profileve ~/.mkshrc).

Bu terminalinizin /dev/tty1yerine geçer. (Daha fazla büyü ile terminal otomatik olarak bulunabilir. /dev/consoleSize tam iş kontrolü vermeyecektir.)

Bunun /devçalışması için birkaç dosyaya ihtiyacınız var :

  • / Dev / konsol
  • / Dev / null
  • / Dev / TTY
  • / Dev / tty1

Çekirdek seçeneği ile önyükleme, devtmpfs.mount=1doldurulmuş bir gereksinimi ortadan kaldırır /dev, sadece boş bir dizin olmasına izin verin (bağlama noktası olarak kullanılmaya uygundur).

Normalde bazı yardımcı programlara sahip olmak isteyeceksiniz (klibc, busybox, beastiebox, toybox veya araç kutusundan), ancak gerçekten gerekli değildir.

~/.mkshrc$ PS1'i ve bazı temel kabuk takma adlarını ve işlevlerini ayarlayan bir dosya eklemek isteyebilirsiniz .

Bir zamanlar mksh (ve örnek mkshrc dosyasını) ve klibc-utils kullanarak Linux / m68k için 171K sıkıştırılmış (371K sıkıştırılmamış) initrd yaptım. (Bu daha önce -T! Kabuğuna eklenmişti, bu yüzden bunun /dev/tty2yerine giriş kabuğunu ortaya çıkardı ve kullanıcıya terminalleri değiştirmesini söyleyen konsola bir mesaj yazdı.) İyi çalışıyor.

Bu gerçekten çıplak bir minimum kurulum. Diğer cevaplar biraz daha öne çıkan sistemlere mükemmel tavsiyeler veriyor. Bu gerçekten özel bir durum.

Feragatname: Ben mksh geliştiricisiyim.


Bu harika bir cevap, paylaşım için teşekkürler ve ayrıca teşekkürler mksh.
JoshuaRLi

2

Minimal init merhaba dünya programı adım adım

resim açıklamasını buraya girin

Sonsuz bir döngü ile biten herhangi bir bağımlılık olmadan merhaba bir dünya derleyin. init.S:

.global _start
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $message, %rsi
    mov $message_len, %rdx
    syscall
    jmp .
    message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
    .equ message_len, . - message

sys_exitÇekirdek panikleri kullanamayız .

Sonra:

mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"

Bu /init, çekirdek dünyamızın çalışacağı ilk kullanıcı alanı programı olan merhaba dünyamızla bir dosya sistemi oluşturur . Ayrıca daha fazla dosya ekleyebilirdik d/ve /initçekirdek çalıştığında bunlara programdan erişilebilir .

Sonra cdLinux çekirdek ağacına, yapı her zamanki gibi ve QEMU'da çalıştırın:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"

Ve bir çizgi görmelisiniz:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

emülatör ekranında! Son satır olmadığını unutmayın, bu yüzden biraz daha yukarı bakmanız gerekir.

Statik olarak bağlarsanız C programlarını da kullanabilirsiniz:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}

ile:

gcc -static init.c -o init

USB açıkken gerçek donanım üzerinde çalışabilirsiniz /dev/sdX ve:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX

Bu konuda harika bir kaynak: http://landley.net/writing/rootfs-howto.html Ayrıca gen_initramfs_list.sh, işlemin otomatikleştirilmesine yardımcı olmak için Linux çekirdek kaynak ağacından bir komut dosyası olan nasıl kullanılacağını da açıklar .

Sonraki adım: BusyBox'ı sistemle etkileşime girecek şekilde ayarlayın: https://github.com/cirosantilli/runlinux

Ubuntu 16.10, QEMU 2.6.1 üzerinde test edilmiştir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.