Jak zapełnić katalog / dev podczas budowania własnego initrd?

9

Próbuję dowiedzieć się czegoś o initrd. Postępowałem zgodnie z tym samouczkiem, aby zbudować własny initrd od zera, i zainstalowałem na nim busyboksa. Następnie zrobiłem .iso z niego za pomocą isolinux, aby móc przetestować go w virtualbox. Działa świetnie!

Mam podstawowe polecenia z busybox, więc chciałem zamontować system plików. Ale katalog / dev jest prawie pusty (bez sda), z wyjątkiem niektórych plików, które utworzyłem podczas korzystania z samouczka. Dowiedziałem się o udev i myślę, że tego właśnie potrzebuję. Nie jestem jednak pewien, jak to zrobić.

Czy powinienem po prostu pobrać najnowszy kod źródłowy z udev, skompilować go i dodać do mojego initrd? A potem wywołaj / bin / udev czy coś takiego w moim skrypcie init? Czy jest inny / lepszy sposób na zapełnienie katalogu / dev?

Edycja: Kilka dodatkowych informacji i aktualizacji na temat tego, co już zrobiłem.

  • Testuję wszystko w wirtualnym pudełku. Właśnie zainstalowałem ubuntu minimal w wirtualnym pudełku, zrobiłem .iso z mojego initrd, a następnie uruchomiłem z iso w virtualbox.
  • Użyłem vmlinuz, /lib/modulesktóre były obecne na debian-businesscard.iso i skopiowałem je do mojego initrd, który utworzyłem, wykonując samouczek, który wcześniej podłączyłem.
  • Jądro ma CONFIG_DEVTMPFS=y
  • Niektóre urządzenia pojawiają się w /dev, jak tty0-tty63 i niektóre inne, ale nie sda ​​/ hda.
  • Uruchomiłem lspci -kw moim obecnie działającym systemie operacyjnym i wirtualnym polu, aby sprawdzić, które moduły są w użyciu. SATA Controllermówi, że używa ahcijako modułu.
  • Kiedy modprobe -v ahciwykonuję, dużo narzeka na „nieznany symbol: ata_some_stuff”, ale potem zwraca coś w stylu SCSI Subsystem initialized, ATA-6: VBOX HARDDISKi Direct-Access ATA VBOX HARDDISK. Jednak nadal nie znaleziono urządzeń na dysku twardym /dev.

Mój obecny /init/skrypt wygląda następująco:

#!/bin/ash
mount -t devtmpfs none /dev
mount -t proc /proc /proc
mount -t sysfs none /sys
modprobe -v ahci
echo "Hello world"
exec /bin/ash --login

Czy ktoś ma pojęcie, co robię źle i co powinienem robić zamiast tego?

Carlito
źródło

Odpowiedzi:

12

Odpowiedź Gillesa jest prawidłowa, ale stara szkoła :-). Kolejną rzeczą wartą uwagi (bardziej drobiazgową w terminologii niż cokolwiek innego) jest to, że link do którego prowadzą linki to instrukcje, jak tworzyć initramfs, a nie initrd. Oba są podobne i służą temu samemu celowi, ale różnią się sposobem przechowywania i ładowania obrazu.

W każdym razie odpowiedź na twoje pytanie jest naprawdę bardzo prosta.

  1. Włącz devtmpfsw jądrze ( CONFIG_DEVTMPFS=y)
  2. Uruchom mount -t devtmpfs none /devjako pierwszą rzecz w initskrypcie.

Otóż ​​to. Devtmpfs zapełni się /devpodobnie jak udev. Nie trzeba nawet wstępnie wypełnione /dev(w obrazie initramfs) z podstawami jak null, zerolub console.

Patrick
źródło
Dzięki za komentarz. Uruchomiłem twoje polecenie i mam teraz więcej urządzeń, ale wciąż nie mam sda ani hda do zamontowania. Czy jest coś, o czym zapomniałem? Używam jądra vmlinuz, które otrzymałem z systemu live Debiana, czy powinienem skompilować własny?
Carlito
@Carlito Czy to jądro ma włączoną funkcję devtmpfs (sprawdź plik konfiguracyjny)? Debian niedawno przeszedł na devtmpfs.
Gilles 'SO - przestań być zły'
@Gilles Nie podano pliku konfiguracyjnego, ale załadowałem jądro, które dostałem z Debiana, plik konfiguracyjny powiedział CONFIG_DEVTMPFS=y, ale nadal nie otrzymuję żadnych urządzeń SDA. Myślę, że dzieje się tak, ponieważ nie załadowałem żadnych modułów (lsmod nic nie zwraca). Jakie moduły należy załadować, aby uzyskać urządzenia z systemem plików? Czy jest coś jeszcze, o czym zapomniałem?
Carlito
@ Carlito tak, jeśli pojawiają się inne rzeczy /dev, po prostu nie napędy, wtedy devtmpfs działa i prawdopodobnie brakuje Ci modułu kontrolera dysku (jak się domyślasz). Niestety jedynym sposobem, aby dowiedzieć się, którego sterownika / modułu potrzebujesz, jest albo odczytanie informacji dla każdego z nich w konfiguracji jądra, albo uruchomienie lspci -kw działającym systemie Linux (który pokaże, jakiego sterownika jądra używają różne komponenty twojego systemu) .
Patrick
1
@ CiroSantilli709 大 抓捕 六四 事件 法轮功CONFIG_DEVTMPFS_MOUNT=ynie ma żadnego wpływu na initramfs. Z tekstu pomocy jądra: „Ta opcja nie wpływa na uruchamianie oparte na initramfs, tutaj system plików devtmpfs zawsze musi być montowany ręcznie po zamontowaniu rootfs”
Patrick
4

Udev zapełni się /devautomatycznie na podstawie sterowników załadowanych do jądra i urządzeń wykrytych przez te sterowniki. Nazwy urządzeń i ich uprawnienia oparte są na zestawie reguł, które administratorzy mogą dostosować. Większość systemów Linux powinna używać udev; wyjątkiem są systemy (zwykle osadzone), w których konfiguracja sprzętu jest znana w momencie konfigurowania systemu i nie będzie się później zmieniać.

Zazwyczaj dzwonisz udevdość wcześnie w sekwencji startowej. Jedną z niewielu rzeczy, które powinieneś (musisz?) Zrobić, to mount /proci /sys. Po uruchomieniu demona, wywołaj, udevadm trigger --action=add; udevadm settleaby udev przetworzył wszystkie oczekujące zdarzenia z jądra ( trigger) i zaczekaj, aż zdarzenia zostaną przetworzone przed kontynuowaniem ( settle). Następnie możesz zlokalizować urządzenie zawierające główny system plików.

Oprócz udevdpliku binarnego, będziesz potrzebować innych części udevna initrd. Obejmuje to pliki konfiguracyjne w /etc/udev, konfigurację podstawową /lib/udevoraz pliki binarne pomocnicze, takie jak scsi_idrównież /lib/udev. Potrzebujesz wszystkich programów, które są wywoływane z reguł udev, które dołączasz do initrd.

Pod koniec initrd, przed przeniesieniem kontroli na prawdziwą partycję root, musisz zatrzymać się udevdjak każdy inny program z initrd. To nie usuwa żadnego urządzenia z /dev. Użyj, mount --move /dev /root/devaby przenieść zamontowanego /devdo prawdziwego katalogu głównego.

Gentoo ma przewodnik po initramfs i stronę wiki initramfs, które wymieniają między innymi udev. Initramfs jest nowoczesnym następcą initrd, wykorzystującym archiwum CPIO zamiast obrazu systemu plików oraz z innym interfejsem procesu (na initrd /linuxrcmusi wyjść, podczas gdy na initramfs /initmusi mieć execinit z prawdziwego katalogu głównego); większość systemów zmieniła się w tych dniach (nawet jeśli plik nadal może mieć nazwę initrd).

Gilles „SO- przestań być zły”
źródło
Dzięki za odpowiedź. Doszedłem do wniosku, że faktycznie zrobiłem initramfs zamiast initrd. Ale używam jądra vmlinuz, które dostałem z systemu live Debiana, czy powinienem skompilować do tego własne jądro (więc wiem, które moduły są dostępne do ładowania twardych dysków), czy też istnieje rodzaj minimalnej wersji, której mógłbym używać z podstawowymi modułami ? Prawdopodobnie pobiorę najnowszy udev i spróbuję go skompilować i uruchomić.
Carlito
@ Carlito Polecam najpierw spróbować z jądrem Debiana, ponieważ zapominanie o niezbędnym sterowniku jest częstym błędem podczas kompilacji własnego jądra.
Gilles 'SO - przestań być zły'
Ale jak mam je zdobyć? Właśnie skopiowałem vmlinuz, który znalazłem w debian-businesscard.iso (prawdopodobnie nie najlepszy pomysł). Czy powinienem po prostu skopiować standardowe jądro, które otrzymałem z Ubuntu lub Debiana oraz cały katalog / lib / modules?
Carlito
@ Carlito Będziesz potrzebował co najmniej wszystkich modułów niezbędnych do Twojego sprzętu. Przeglądanie listy może być trudne. Najlepszym sposobem, aby dowiedzieć się, czego potrzebujesz, jest uruchomienie lsmodna działającym systemie. Zacznij więc od nich wszystkich, a następnie inteligentnie przycinaj, jeśli chcesz zaoszczędzić miejsce.
Gilles „SO- przestań być zły”