Как заполнить каталог / dev при создании собственного initrd?

9

Я пытаюсь узнать кое-что о initrd. Я следовал этому руководству, чтобы создать свой собственный initrd с нуля, и я установил на нем busybox. Затем я сделал .iso из него с isolinux, чтобы я мог проверить его в virtualbox. Работает отлично!

У меня есть основные команды от busybox, поэтому я хотел смонтировать файловую систему. Но каталог / dev почти пуст (без sda), за исключением некоторых файлов, которые я создал, следуя руководству. Я узнал об Udev и думаю, что это то, что мне нужно. Однако я не уверен, как пойти на это.

Должен ли я просто взять последний исходный код из udev, скомпилировать его и добавить в мой initrd? А потом вызвать / bin / udev или что-то подобное в моем скрипте инициализации? Или есть другой / лучший способ заполнить каталог / dev?

Изменить: некоторая дополнительная информация и обновления о том, что я уже сделал.

  • Я тестирую все в виртуальной коробке. Я просто установил Ubuntu Minimal в виртуальный ящик, сделал .iso из моего initrd, а затем загрузился с ISO в VirtualBox.
  • Я использовал vmlinuz, /lib/modulesкоторый присутствовал в файле debian-businesscard.iso, и скопировал его в свой initrd, который я создал, следуя руководству, которое я связал ранее.
  • Ядро имеет CONFIG_DEVTMPFS=y
  • Некоторые устройства отображаются /dev, например, tty0-tty63 и некоторые другие, но не sda / hda.
  • Запустил lspci -kв моей в настоящее время работающей ОС и в виртуальном окне, чтобы проверить, какие модули используются. SATA Controllerговорит, что использует в ahciкачестве модуля.
  • Когда я выполняю modprobe -v ahciего, он много жалуется на «неизвестный символ: ata_some_stuff», но после этого он возвращает что-то вроде SCSI Subsystem initialized, ATA-6: VBOX HARDDISKи Direct-Access ATA VBOX HARDDISK. Тем не менее, все еще не найдено устройств с жестким диском /dev.

Мой текущий /init/сценарий выглядит следующим образом:

#!/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

Кто-нибудь знает, что я делаю неправильно и что я должен делать вместо этого?

Карлито
источник

Ответы:

12

Хотя ответ Жиля правильный, это старая школа :-). Еще один примечательный момент (более точный в терминологии, чем что-либо другое) - это руководство, на которое вы ссылаетесь, это инструкции о том, как создать initramfs, а не initrd. Они похожи и служат одной и той же цели, но отличаются тем, как изображение сохраняется и загружается.

В любом случае, ответ на ваш вопрос на самом деле очень прост.

  1. Включить devtmpfsв ядре ( CONFIG_DEVTMPFS=y)
  2. Запустите mount -t devtmpfs none /devкак самое первое в вашем initскрипте.

Вот и все. Devtmpfs будет заполняться так /devже, как udev. Вам даже не нужно предварительно заполнить /dev(в initramfs изображение) с основами , как null, zeroили console.

Патрик
источник
Спасибо за ваш комментарий. Я выполнил вашу команду, и теперь у меня есть больше устройств, но все еще нет ни sda, ни hda для монтирования. Есть что-то, что я забыл сделать? Я использую ядро ​​vmlinuz, которое я получил от системы Debian Live. Должен ли я скомпилировать свое собственное?
Карлито
@Carlito Включено ли в этом ядре devtmpfs (проверьте файл конфигурации)? Debian только недавно перешел на devtmpfs.
Жиль "ТАК - перестань быть злым"
@Gilles Конфигурационный файл не поставляется, но я загрузил ядро, полученное из debian, говорится в файле конфигурации CONFIG_DEVTMPFS=y, но я все еще не получаю никаких устройств sda. Я думаю, это потому, что я не загружал никаких модулей (lsmod ничего не возвращает). Какие модули я должен загрузить, чтобы получить устройства файловой системы? Или я что-то еще забыл?
Карлито
@Carlito Да, если у вас есть другие вещи /dev, кроме дисков, то devtmpfs работает, и вы, вероятно, пропускаете модуль контроллера диска (как вы уже догадались). К сожалению, единственный способ узнать, какой драйвер / модуль вам нужен, это либо прочитать информацию для каждого из них в конфигурации ядра, либо запустить lspci -kв работающей системе Linux (которая покажет вам, какой драйвер ядра используют различные компоненты вашей системы). ,
Патрик
1
@ CiroSantilli709 大 抓捕 六四 事件 法轮功CONFIG_DEVTMPFS_MOUNT=yне влияет на initramfs. Из текста справки ядра: «Эта опция не влияет на загрузку на основе initramfs, здесь файловую систему devtmpfs всегда нужно монтировать вручную после монтирования
Патрик
4

Udev заполняется /devавтоматически в зависимости от драйверов, загруженных в ядро, и устройств, которые эти драйверы обнаруживают. Имена устройств и их разрешения основаны на наборе правил, которые администраторы могут настроить. Большинство систем Linux должны использовать udev; Исключение составляют системы (обычно встроенные), в которых конфигурация оборудования известна во время настройки системы и впоследствии не изменится.

Вы обычно звоните udevдовольно рано в вашей последовательности запуска. Одной из немногих вещей, которые вы должны (должны?) Сделать до этого, является mount /procи /sys. После запуска демона вызовите udevadm trigger --action=add; udevadm settleudev для обработки всех ожидающих событий из ядра ( trigger) и дождитесь обработки событий, прежде чем продолжить ( settle). Затем вы можете перейти к поиску устройства, содержащего корневую файловую систему.

Помимо udevdдвоичного файла, вам понадобятся другие части udevвашего initrd. Это включает в себя файлы конфигурации в /etc/udevбазовой конфигурации, /lib/udevа также вспомогательные двоичные файлы, такие как scsi_idтакже в /lib/udev. Вам нужны все программы, которые вызываются из правил udev, которые вы включаете в initrd.

В конце initrd, перед передачей управления реальному корневому разделу, вам нужно будет остановиться, udevdкак и любая другая программа из initrd. Это не удаляет любое устройство из /dev. Используйте mount --move /dev /root/devдля перемещения подключенного /devк настоящему корню.

В Gentoo есть руководство по initramfs и вики-страница initramfs, в которых упоминается udev. Initramfs - это современный преемник initrd, использующий архив cpio, а не образ файловой системы, и с другим интерфейсом процесса (на initrd /linuxrcдолжен завершиться, тогда как на initramfs /initдолжен быть execinit от реального корня); большинство систем переключились в эти дни (даже если файл все еще может называться initrd).

Жиль "ТАК - перестань быть злым"
источник
Спасибо за Ваш ответ. Я пришел к выводу, что на самом деле я сделал initramfs вместо initrd. Но я использую ядро ​​vmlinuz, которое я получил от Debian Live System, должен ли я скомпилировать собственное ядро ​​для этого (так что я знаю, какие есть модули для загрузки жестких дисков), или есть какая-то минимальная версия, которую я мог бы использовать с базовыми модулями ? Я, вероятно, скачаю последнюю версию udev и попробую скомпилировать и запустить ее.
Карлито
@Carlito Я рекомендую сначала попробовать ядро ​​Debian, так как забывание необходимого драйвера является распространенной ошибкой при компиляции собственного ядра.
Жиль "ТАК - перестань быть злым"
Но как бы я получить один? Я только что скопировал vmlinuz, который нашел в debian-businesscard.iso (вероятно, не самая лучшая идея). Должен ли я просто скопировать стандартное ядро, которое я получил из ubuntu или debian, и весь каталог / lib / modules?
Карлито
@Carlito Вам понадобятся как минимум все модули, необходимые для вашего оборудования. Может быть трудно найти все, что вам нужно, просматривая список. Лучший способ узнать, что вам нужно - это запустить lsmodна работающей системе. Поэтому начните со всех из них, а затем обрезайте с умом, если вам нужно сэкономить место.
Жиль "ТАК - перестань быть злым"