Как Linux работает с отдельным разделом / boot?

11

Мне интересно узнать, как Linux работает с отдельными загрузочными разделами. Я не заинтересован в том, чтобы делать это на самом деле, но я хотел бы знать, как это работает под капотом.

Рассмотрим жесткий диск sda, который имеет два раздела sda1и sda2. Допустим, sda2это rootраздел, /который содержит ОС Linux.

Насколько я понимаю, что загрузчик GRUB2, смонтирован на /boot. Однако когда каталог /bootнаходится в отдельном разделе sda2, как это может произойти до того, как он /будет смонтирован?

Как /bootв этом случае успешно происходит взаимодействие между BIOS, основной загрузочной записью и GRUB (или файлами )? Неужели данные на /bootсамом деле не подключены к /файловой системе на этом раннем этапе?

Примечание: этот вопрос касается монтирования корневого раздела, но не обсуждает отдельный загрузочный раздел.

ИСИ
источник

Ответы:

18

Вот проблема в вашем понимании:

Насколько я понимаю, загрузчик GRUB2 монтируется в / boot.

GRUB не "установлен" на загрузке. GRUB будет установлен в /boot, и загружается из кода в Master Boot Record. Вот упрощенный обзор современного процесса загрузки, предполагающий распространение GNU / Linux с MBR / BIOS (не GPT / UEFI):

  1. BIOS загружается.
  2. BIOS загружает небольшой фрагмент кода, который находится в основной загрузочной записи.
  3. GRUB не умещается в 440 байт, размер основной загрузочной записи. Следовательно, загруженный код фактически анализирует таблицу разделов, находит /bootраздел (который, я считаю, определяется при установке GRUB в основную загрузочную запись) и анализирует информацию файловой системы. Затем он загружает 2-й этап GRUB. (Это то, где упрощение приходит.)
  4. Этап 2 GRUB загружает все, что ему нужно, включая конфигурацию GRUB, затем представляет меню (или нет, в зависимости от конфигурации пользователя).
  5. Последовательность загрузки выбрана. Это может быть по таймауту, пользователем, выбирающим пункт меню, или загрузкой списка команд.
  6. Последовательность загрузки начинает выполняться. Это может сделать несколько вещей - например, загрузку ядра, загрузку по цепочке в другой загрузчик - но давайте предположим, что последовательность загрузки является стандартной GNU / Linux.
  7. GRUB загружает ядро ​​Linux.
  8. GRUB загружает начальный виртуальный диск .
  9. Первоначальный виртуальный диск монтируется /в /new_root(возможно, криптографически разблокируя его), запускает udev, запускает резюме из свопа и т. Д.
  10. Начальный виртуальный диск использует pivot_rootутилиту, чтобы установить /new_rootв качестве реального /.
  11. initначинается. Разделы монтируются, демоны запускаются, а система загружается.

Обратите внимание, как ядро ​​загружается только на шаге 7. Из-за этого концепция монтирования отсутствует до шага 7 . Вот почему /bootего нужно снова смонтировать на шаге 9, хотя GRUB уже использовал его.

Также может быть полезно взглянуть на раздел GRUB 2 на странице Википедии о GRUB.

strugee
источник
Вы точно сгладили мое замешательство. Это как раз то, что я искал. То есть изначально /bootне относится к каталогу, смонтированному в корневом разделе?
JII
@ jesterII потрясающе! в таком случае, не возражаете ли вы принять этот ответ, нажав на флажок прямо под стрелками голосования?
стружка
7
Код MBR не может проанализировать файловую систему. Он загружает образ ядра grub из неиспользуемых секторов после MBR перед первым разделом, и этот код понимает, как найти и смонтировать раздел / boot, чтобы найти файлы конфигурации grub, дополнительные модули и ваши ядра. Также pivot_root считался грязным хаком и был заменен на тот, run-initкоторый удаляет все файлы в initramfs, а затем загружает в корневую файловую систему.
psusi
Современный процесс загрузки теперь должен быть процессом загрузки Legacy, поскольку он UEFIстановится все более популярным ;-) @strugee
Kiwy
1
@strugee, после обсуждения списка рассылки util-linux мне кажется, что мои воспоминания были немного не в порядке: они перестали разрешать pivot_root для настоящих rootfs, поэтому никто больше не использует его во время загрузки. Systemd использует его при завершении работы, но не для возврата к исходному initrd (который удаляет себя при переходе к реальному корню), а для переключения на только что загруженный. См. Marc.info/?l=util-linux-ng&m=139100788306216&w=2
psusi
6

Вопрос 1

Насколько я понимаю, загрузчик GRUB2 монтируется в / boot. Однако, когда каталог / boot находится на отдельном разделе sda2, как это может произойти до того, как / будет фактически смонтирован?

Я не думаю, что вы понимаете, это прямо здесь. Со страницы Википедии GNU GRUB :

выдержка

Когда компьютер включен, BIOS компьютера находит настроенное основное загрузочное устройство (обычно это жесткий диск компьютера), загружает и выполняет начальную программу начальной загрузки из основной загрузочной записи (MBR). MBR является первым сектором жесткого диска и имеет номер 0 (отсчет секторов начинается с 0). Долгое время размер сектора составлял 512 байт, но с 2009 года доступны жесткие диски с размером сектора 4096 байт, которые называются дисками расширенного формата . По состоянию на октябрь 2013 года такие жесткие диски по-прежнему доступны в 512-байтовых секторах с использованием эмуляции 512e .

В GRUB версии 2 происходит следующее:

выдержка

Загрузка компьютера

Когда питание включено, происходит следующее:

  • Аппаратное обеспечение инициализирует, устанавливает процессор в реальный режим (без виртуальной памяти) и переходит в фиксированное положение 0xFFFF0 (зашито в цепях ЦП)
  • Поэтому выполняется код BIOS, сохраненный в ПЗУ или флэш-памяти, сопоставленной с этим местоположением.
  • Код BIOS просматривает данные конфигурации BIOS, чтобы определить, какое загрузочное устройство. Эти данные конфигурации BIOS обычно можно редактировать, нажимая специальную последовательность клавиш сразу после включения питания, вызывая запуск программы конфигурации BIOS. Среди прочего, здесь обычно можно выбрать загрузочное устройство.
  • Код BIOS загружает MBR загрузочного устройства в RAM. Помните, что MBR составляет всего 512 байт! Загруженные данные - это, конечно, программа и данные, которые grub-install динамически создавала и записывала туда при запуске программы grub-install.
  • Код BIOS переходит на начальный адрес загруженной MBR (т.е. код Grub выполняется впервые с момента включения).
  • Код MBR Grub загружает один сектор, адрес которого встроен в блок MBR. Затем он проходит по парам (address, len) в этом секторе, загружая все эти данные с диска в память (т.е. загружает содержимое файла /boot/grub/core.imgили его «встроенную» копию). Затем код MBR переходит к загруженному коду, то есть «выполняет» программу в core.img.
  • Как описано в разделе «Установка Grub», этот трюк встраивания необработанных адресов блочных дисков позволяет хранить их core.imgв пространстве, которое не находится в разделе и которое вообще никогда не форматировалось как файловая система («встраивание»). И в этом случае, если core.imgизменяется, пока новая версия «встроена» в том же месте, код MBR обновлять не нужно.
  • В качестве альтернативы, возможно, что они core.imgнаходятся внутри реальной файловой системы, а Grub может прочитать core.imgсодержимое файла, не имея драйвера для этой файловой системы. Однако в этом случае, если core.imgон изменен, тогда первому блоку файла может быть присвоен новый адрес на диске; если это происходит, MBR необходимо обновить, чтобы указать на это новое местоположение. Тем не менее, как core.imgобычно обновляется при запуске grub-install, это обычно не проблема.
  • Обратите внимание, что теоретически, если core.imgна устройстве, отличном от MBR, и добавлено новое оборудование, сгенерированная Grub запись MBR может быть не в состоянии правильно загрузить core.imgфайл; идентификатор устройства, на котором core.imgдолжен быть найден первый сектор, встроен в MBR, а не ищется. Однако для этого нет решения; нет способа встроить эквивалент команды поиска Grub в 512-байтовую MBR. Эта проблема маловероятна, хотя; обычно core.imgон встроен в то же устройство, что и MBR. И после core.imgзагрузки он может использовать search.mod для поиска всех дальнейших /boot/grubфайлов, и поэтому неуязвим для аппаратных перестановок.
  • Выполненный core.imgкод теперь инициализирует все модули, которые встроены в него (связаны с core.img); одним из этих модулей будет драйвер файловой системы, способный считывать файловую систему, в которой находится каталог /boot/grub.
  • Он также регистрирует набор встроенных команд: set, unset, ls, insmod.
  • Если «файл конфигурации» был связан с ним core.img, он передается в очень простой встроенный синтаксический анализатор сценариев для обработки. Команды сценариев в файле конфигурации могут вызывать только встроенные или связанные команды. Простые сценарии (например, загрузка типичного настольного компьютера с локального диска) не требуют файла конфигурации; эта возможность используется для таких вещей, как загрузка через pxe, удаленный nfs или когда /boot/grubустройство LVM.
  • Core.imgтеперь загружает файл “/boot/grub/normal.mod”динамически с диска и переходит к его функции ввода. Обратите внимание, что этот шаг требует установки соответствующего драйвера файловой системы (т. Е. Встроенного).

     процесс загрузки

ПРИМЕЧАНИЕ. Когда вы видите типичное меню GRUB2, в котором вы выбираете, какую ОС / ядро ​​загружать, вы ссылаетесь на системный /boot/grubкаталог в этой точке.

                                         ss grub tui

Ссылки

SLM
источник
Кто-то должен исправить эту запись в Википедии, потому что это неправильно. Стадия 1 / 1.5 / 2 применима только к устаревшему grub. Они были полностью уничтожены в переписывании grub2, и вы не найдете ссылки на эти термины в официальной документации grub 2.
psusi
@psusi - спасибо за разъяснения. Я был немного озадачен, когда увидел, что их тоже там упомянули, поскольку я слышал то же самое, что 1 / 1,5 / 2 пропали. Я бы не знал, кого просить отредактировать статьи в Википедии, я не чувствовал бы себя компетентным, чтобы редактировать такой пост. Возможно, следующей лучшей вещью будет уведомление команды GRUB2?
SLM
@psusi - вот ссылка. чтобы этапы ликвидировались в офф. не документы для GRUB2: gnu.org/software/grub/manual/grub.html ... «Файлы изображений (см фото) , которые составляют GRUB были реорганизованы; Стадия 1, Стадия 1,5 и Сценические 2 не более.»
SLM
6

Linux (ядро) не волнует, сколько у вас загрузочных разделов. Загрузка ядра с диска является работой загрузчика (например grub, grub2, lilo) и эти средства также не заботятся о количестве мест ядро может быть расположены. Они заботятся только о конкретном месте.

Например, мой загрузочный раздел - /dev/md1зеркало RAID mdadm, поддерживаемое физическими разделами /dev/sde1и /dev/sdf1. Я могу смонтировать их по отдельности, если захочу, и, таким образом, это технически считается наличием двух загрузочных разделов, хотя они должны содержать одинаковые данные.

Наличие двух разделов для / boot для меня - проблема доступности, но они могут быть разными / boot-разделами. Следующий шаг - откуда загрузчик узнает? Вот как:

menuentry 'Linux 3.10.17 (sde) kernel-3.10.17-g' {
        root=hd0,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3
        initrd /boot/initrd-3.10.17-g
}

menuentry 'Linux 3.10.17 (sdf) kernel-3.10.17-g' {
        root=hd1,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3 
        initrd /boot/initrd-3.10.17-g
}

Это выдержка из grub2конфигурации , и вы заметите , что единственные различия root=hd0,1и root=hd1,1которые устанавливают , какие загрузочный раздел , что ссылки входа.


Теперь, чтобы пройтись через ботинок, вы сможете понять, что здесь происходит.

  • BIOS считывает MBR с загрузочного тома и переходит на загрузчик
  • Загрузчик (например grub2) настроен на то, чтобы знать, какое устройство и раздел содержит ваше ядро. Grub2 напрямую обращается к этому разделу и загружает ваше ядро ​​в память.
  • Затем ваш загрузчик запрыгивает в ядро, а ядро ​​загружает вашу машину.

Загрузчик не заботится о том, сколько у вас загрузочных разделов, он заботится только о том, где они находятся, и вы должны сообщить ему эту информацию.

Ядру не важно, сколько загрузочных разделов у вас есть, потому что оно никогда не должно их видеть (вам нужно иметь его только для добавления новых ядер, например).

Casey
источник