Init işlemi Linux'ta bir kabuk betiği olabilir mi?


14

Ben burada özel bir initramfs kurma hakkında bir eğitim geçiyordu :

Eksik olan tek şey / init, initramfs kökünde, yüklendikten sonra çekirdek tarafından yürütülen yürütülebilir dosyadır. Sys-apps / busybox tamamen işlevsel bir kabuk içerdiğinden, / init ikili dosyanızı basit bir kabuk betiği olarak yazabileceğiniz anlamına gelir (derlemek zorunda olduğunuz Assembler veya C'de yazılmış karmaşık bir uygulama yapmak yerine).

ile başlayan bir kabuk komut dosyası olarak init örneği verir. #!/bin/busybox sh

Şimdiye kadar, init'in başlatılan ana süreç olduğu ve diğer tüm kullanıcı alanı sürecinin sonunda initin çocukları olduğu izlenimindeydim. Bununla birlikte, verilen örnekte, ilk işlem aslında bin/busybox/ shdaha sonra initin üretildiği işlemdir .

Bu doğru bir yorum mu? Örneğin, bu noktada kullanılabilir bir tercümanım olsaydı, init'i bir Python betiği vb. Olarak yazabilir miydim?

Yanıtlar:


12

init "çocukken" (bir çocuk süreç olarak) değil, execşöyle olur:

# Boot the real thing.
exec switch_root /mnt/root /sbin/init

exectüm süreç yerine geçer. Son init, Initramfs'dekilerden önce olmasına rağmen hala ilk süreçtir (pid 1).

/initPid 1 ile bir Busybox kabuk betiği olan Initramfs , Busybox'a execs switch_root(şimdi switch_rootpid 1'dir); bu program bağlama noktalarını değiştirir, böylece /mnt/rootyeni olur /.

switch_rootsonra tekrar execetmek s /sbin/initgerçek kök dosya sisteminin; böylece pid 1 ile gerçek init sisteminizi ilk işlem yapar, bu da herhangi bir sayıda alt süreci ortaya çıkarabilir.

Eğer bir şekilde Python'u Initramfs'inize pişirmeyi başarırsanız, kesinlikle bir Python betiği ile de yapılabilir. Yine de busybox'ı eklemeyi planlamıyorsanız, bazı işlevlerini özenle yeniden uygulamak zorunda kalacaksınız ( switch_rootve genellikle basit bir komutla yapacağınız her şey gibi ).

Ancak, komut dosyası ikili dosyalarına ( CONFIG_BINFMT_SCRIPT=y) izin vermeyen çekirdeklerde çalışmaz veya daha çok böyle bir durumda yorumlayıcıyı doğrudan başlatmanız ve komut dosyanızı bir şekilde yüklemesini sağlamanız gerekir.


/gelmez yarılıp içine - bitti monte edilir (Bu bellekten tasarruf etmektir önce olsa genellikle içeriği tüm silinir) . Öyle hala orada . switch_rootsistem çağrısı yapar switchroot- bu, çekirdek 2.6'daki önyükleme işlemini değiştirdiklerinde çekirdek geliştiricilerin sağladığı şeydir. initramfs gerektirecek bir şey. Büyüyü yapan çekirdek.
mikeserv

1
Bir switchrootsistem çağrısı gerçekten benim için haber olurdu. Bunun için bir kaynağın var mı? Switch_root.c kaynak koduna bakarsanız, oldukça manuel bir işlem gibi görünüyor ve Documentation / filesystems / ramfs-rootfs-initramfs.txt dosyasında açıklananla aynı. Ayrıca her şeyi silip üzerine monte ederseniz, bu noktada oldukça yok oldu, değil mi?
frostschutz

pivot_root, diğer taraftan, bir sistem çağrısıdır. Yine de kullanılmaz switch_rootve bazı çemberlerden atlamaksızın kullanılamaz ve her iki şekilde de bu cevap için hiçbir şey önemli değil, bu yüzden tamamen kaldırdım. Çok kötü, büyü ve ince havaya kaybolanın gerçekten iyi çalıştığını düşündüm ... :-P
frostschutz

Belki de yanlış bir fikrim var switch_root- ki bunun için üzgünüm ve bana gösterdiğiniz için teşekkür ederim - ama yine de hiçbir şey yok olmaz. initramfs kök ısrar ettiler, herkes için her zaman var - bu olduğunu kökü.
mikeserv

1
Gibi Söyleyecek bağlantılı dokümanlar : Ama Initramfs rootfs geçerli: sen ne pivot_root rootfs, ne de devreden çıkarın. Bunun yerine, alanı ( find -xdev / -exec rm '{}' ';') boşaltmak için rootfs'den her şeyi silin , rootfs'yi yeni root ( cd /newmount; mount --move . /; chroot .) ile aşın , stdin / stdout / stderr öğesini new / dev / console'a ekleyin ve yeni init'i yürütün .
mikeserv

4

Linux çekirdeğinin yönetici sistemi, yerel olarak çeteleri anlıyor

Yürütülen dosya sihirli baytlarla başladığında #!, çekirdeğe şu şekilde kullanmasını söylerler #!/bin/sh:

  • yap ve execsistem çağrısı
  • yürütülebilir ile /bin/sh
  • ve CLI bağımsız değişkeni ile: geçerli komut dosyasının yolu

Bu, aşağıdakilerle normal bir kullanıcı kabuğu kabuğu çalıştırdığınızda gerçekleşenle tamamen aynıdır:

./myscript.sh

Dosya .ELFbunun yerine sihirli baytlarla başlamışsa #!, çekirdek çalıştırmak için ELF yükleyiciyi seçerdi.

Daha fazla ayrıntı için: Neden insanlar bir Python betiğinin ilk satırına #! / Usr / bin / env python shebang yazıyor? | Yığın Taşması

Bunu aklınızda bulundurduktan sonra /init, bir kabuk betiği de dahil olmak üzere çekirdeğin yürütebileceği herhangi bir şey olabileceğini ve /bin/shbu durumda neden ilk çalıştırılabilir olacağını kabul etmek kolaylaşır .

İşte denemek isteyenler için en az çalıştırılabilir bir örnek: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init

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.