Как ядро ​​Linux может получить доступ к назначенным файлам initramfs / initrd?

8

Я пытаюсь понять процесс загрузки машины в целом с момента нажатия кнопки питания. Есть одна часть от начального загрузчика до стадии initramfs, которую я не совсем понимаю среди других небольших кусочков.

Учитывая эту конфигурацию Grub для записи, взятой из недавней установки Ubuntu по умолчанию:

insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 96fb7310-5adb-4f66-bf59-04acd08d76a3
echo    'Loading Linux x.y.z ...'
linux   /vmlinuz-x.y.z root=/dev/mapper/some-device-name ro nomodeset 
echo    'Loading initial ramdisk ...'
initrd  /initrd.img-x.y.z

Что это на самом деле делает с точки зрения состояния системы и памяти? Я понимаю, что задача Grub - «загрузить и запустить ядро», и у него есть собственный набор модулей для доступа к файлам на устройствах (или в сети), чтобы получить к ним доступ. В приведенном здесь примере insmod, set rootи search- но это только с точки зрения Grub, а не совместно с ядром, верно?

Я также предполагаю, что Grub загружает (копию?) Ядра в память ( linuxкоманду ) и запускает его, чтобы начать выполнение. (очевидно, два разных шага - так, как?) Указанные параметры можно прочитать в ядре и интерпретировать (это большая строка, отображенная в памяти где-нибудь?) и предоставить опции для организации запрошенных вещей.

Я тоже вижу эту initrdопцию. Это указывает на мои сжатые gzip initramfs, необходимые для загрузки фактического корневого устройства, указанного в root=. Но как этот initramfs предоставляется ядру? Ему не передаются адреса памяти, куда он может его загрузить, и он не может получить к нему доступ, так как он загружается уже до запуска ядра. В некоторой документации по ядру говорится, что эта файловая система initramfs доступна через устройство /dev/ram0, но я не вижу, как она становится доступным файлом устройства для начала. Я думаю, что под водой что-то происходит, я не вижу.

Я также не вижу, как это относится к другим загрузчикам, включая встроенные платформы, например, с использованием U-boot / Coreboot. Делает ли это то же самое, что и Grub (те же стандартные адреса памяти?), И в какой степени они сравниваются с Grub в отношении загрузки ядра / initrd?

Просто чтобы прояснить мои вопросы, я думаю, что я понимаю, почему существуют различные стадии загрузки и какие переходы происходят, но я не понимаю, как они происходят и какова точная ответственность каждого из этапов. У меня такое чувство, что я упускаю какой-то «стандарт», к которому все это сводится.

Я был бы признателен за некоторые объяснения по этому поводу.

gertvdijk
источник
Обратите внимание на неявную bootкоманду в конце последовательности. Я не совсем уверен , что именно он делает в Grub, но если вы используете командную строку Grub для ввода этих команд вручную, вам нужно, bootили он будет сидеть вечно grub>(или, по крайней мере, до тех пор, пока вам не надоест и вы не выключите компьютер). ). Предыдущие команды «просто» настраивают среду.
CVN
@ MichaelKjörling Насколько я понимаю, теперь bootпроцессор перейдет к адресу загруженного ядра (начало выполнения). Для пункта меню это неявно определено. см это .
gertvdijk

Ответы:

5

В общем, должен быть какой-то протокол, потому что обычно недостаточно просто загрузить файл в память и перейти в определенное место, но вы должны либо передать дополнительные аргументы, такие как параметры ядра, то есть получить доступ к аргументам memdisk из DOS .

Поскольку это зависит от аппаратного обеспечения (например, arm отличается от x86), вам нужно найти правильную информацию, см. Эту статью о загрузке arm или протоколе загрузки Linux / x86 для некоторых примеров.

Ульрих Дангел
источник
6

Загрузчик сохраняет initrd в определенном месте в памяти и сообщает ядру адрес памяти образа initrd. В большинстве современных систем Linux используется схема initramfs с использованием dracut , которая на самом деле представляет собой архив cpio (а не образ диска), который распаковывается в файловую систему tmpfs, созданную ядром вскоре после выполнения.

jsbillings
источник
Я получил это далеко; но как загрузчик сообщает ядру о расположении в памяти? Где ядро ​​получает этот адрес памяти?
gertvdijk
3
@gertvdijk взгляните на kernel.org/doc/Documentation/x86/boot.txt, где описано, как загрузчик взаимодействует с ядром, то есть загрузчик должен предоставлять параметры ядра и т. д.
Ульрих Дангель
@UlrichDangel Отлично! Именно то, что я искал. Очевидно, это аппаратно-зависимый (в данном случае x86) протокол, описывающий все это. Напишите это как ответ с коротким описанием, и я приму это.
gertvdijk