Przechodziłem samouczek na temat konfigurowania niestandardowego initramfs, w którym napisano:
Jedyne czego brakuje to / init, plik wykonywalny w katalogu głównym initramfs, który jest wykonywany przez jądro po załadowaniu. Ponieważ sys-apps / busybox zawiera w pełni funkcjonalną powłokę, oznacza to, że możesz napisać swój plik binarny / init jako prosty skrypt powłoki (zamiast robić z niego skomplikowaną aplikację napisaną w Asemblerze lub C, którą musisz skompilować).
i podaje przykład init jako skrypt powłoki, który zaczyna się od #!/bin/busybox sh
Do tej pory miałem wrażenie, że init jest głównym procesem, który jest uruchamiany i że wszystkie inne procesy przestrzeni użytkownika są ostatecznie potomkami init. Jednak w podanym przykładzie tak naprawdę pierwszy proces jest bin/busybox/ sh
inicjowany.
Czy to poprawna interpretacja? Gdybym na przykład miał w tym momencie dostępnego interpretera, mógłbym napisać init jako skrypt Pythona itp.?
źródło
/
nie rozpływa się w powietrzu - jest zamontowany (choć zwykle cała zawartość jest usuwana przed zapisaniem pamięci) . Jest tam jeszcze .switch_root
robi syscallswitchroot
- to jest to, co zapewnia jądro, gdy zmienili proces rozruchu w jądrze 2.6. coś, co wymaga initramfs. To jądro robi magię.switchroot
Syscall rzeczywiście byłoby dla mnie nowość. Czy masz na to źródło? Jeśli spojrzysz na kod źródłowy switch_root.c, wydaje się, że jest to proces dość ręczny i taki sam, jak opisano w Documentation / filesystems / ramfs-rootfs-initramfs.txt. A jeśli wszystko usuniesz i zamontujesz, w tym momencie prawie zniknie, nie sądzisz?pivot_root
z drugiej strony jest wywołaniem systemowym. Nie jest jednak używanyswitch_root
i nie można go używać bez przeskakiwania przez kilka obręczy, a tak czy inaczej nie ma znaczenia dla tej odpowiedzi, więc po prostu ją usunąłem. Szkoda, myślałem, że magia i zniknięcie w powietrzu działają naprawdę dobrze ... :-Pswitch_root
- za co przepraszam i dziękuję za pokazanie mi - ale i tak niczego nie znika. initramfs powtarzał korzeniowe i jest tam zawsze dla wszystkich - to jest korzeń.find -xdev / -exec rm '{}' ';'
), zamontuj rootfs za pomocą nowego root (cd /newmount; mount --move . /; chroot .
), dołącz stdin / stdout / stderr do nowego / dev / console i uruchom nową init.Wywołanie systemowe jądra Linuksa natywnie nie docenia shebangów
Kiedy wykonywany plik zaczyna się od bajtów magicznych
#!
, informuje jądro, aby używało go#!/bin/sh
jako:exec
wywołanie systemowe/bin/sh
Dokładnie tak samo dzieje się po uruchomieniu zwykłego skryptu powłoki użytkownika z:
Gdyby plik zaczął się od bajtów magicznych
.ELF
zamiast#!
, jądro wybrałoby moduł ładujący ELF, aby go uruchomić.Więcej informacji: Dlaczego ludzie piszą #! / Usr / bin / env shebang python w pierwszym wierszu skryptu Python? | Przepełnienie stosu
Kiedy to sobie przypomnisz, łatwo będzie zaakceptować, że
/init
może to być wszystko co jądro może wykonać, w tym skrypt powłoki, a także dlaczego/bin/sh
będzie to pierwszy plik wykonywalny w tym przypadku.Oto minimalny uruchamialny przykład dla tych, którzy chcą go wypróbować: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init
źródło