Скриптинг GRUB 2: преобразование имени устройства в нотации GRUB в имя устройства Linux

Вопрос или проблема

Я пытаюсь использовать метки разделов (или UUID, что не имеет значения), чтобы выбрать корневой раздел без использования initrd/initramfs.

С initramfs это довольно просто: root=LABEL=... или root=/dev/disk/by-label/... в аргументах ядра выполняет задачу. Однако без initramfs это невозможно: нотация LABEL= декодируется скриптом initramfs, а символические ссылки /dev/disk/by-label/... создаются udev, работающим из initramfs. Только нотация root=/dev/sdXY понимается самим ядром.

Тем не менее, GRUB поддерживает скрипты в стиле командной оболочки, и я думаю, что это может быть реализовано в виде скрипта GRUB 2, который будет генерировать строку root=/dev/sdXY из метки устройства или UUID.

В частности, команда search --label <label> --set ROOTDEV установит переменную ROOTDEV со строкой вроде hd0,gpt5, которая указывает на раздел с заданной меткой. Если я правильно понимаю (пожалуйста, исправьте меня, если я ошибаюсь), порядок устройств в GRUB и ядре одинаковый, так что hd0 это /dev/sda, hd1 это /dev/sdb и так далее.

Так что вот вопрос: есть ли способ, изнутри скрипта GRUB 2, преобразовать hd0,gpt5 в /dev/sda5? Именно часть hd0 в sda – остальное легко сделать с помощью регулярных выражений.

Когда Grub2 находится на USB-накопителе (на этом USB-накопителе не установлена Linux, поэтому grub.cfg должен быть создан и отредактирован вручную), литерал раздела данных меняется в зависимости от количества подключенных внутренних и внешних устройств, а также от того, загружается ли оборудование в режимах UEFI или BIOS.

В некоторых строках мне нужно иметь параметр в форме /dev/sd$#, не в стиле GRUB, он должен указывать на такие данные раздела (литерал не всегда одинаковый, это сильно зависит от компьютера, с которого я загружаю такой USB).

С помощью команды поиска GRUB я могу получить литерал, но в стиле GRUB.

Я не знаю, как использовать регулярные выражения внутри файла grub.cfg, чтобы заменить hd# на sd$, а также чтобы заменить ‘,msdos#’ или ‘,gpt#’ на #.

Возможно, ссылка на регулярные выражения в grub.cfg будет полезной.

Ответ или решение

Для решения задачи конвертации имен устройств в обозначение GRUB и обратно, необходимо учитывать две главные детали: правильное использование команд GRUB и возможность манипуляции строками в GRUB 2. Таким образом, мы можем создать скрипт, который будет выполнять вашу задачу.

Как вы правильно отметили, вы можете использовать команду search для нахождения устройства по метке. Пример команды:

search --label <your_label> --set ROOTDEV

После выполнения этой команды переменная ROOTDEV будет содержать значение в формате hdX,gptY или hdX,msdosY, в зависимости от типа разметки.

Шаг 2: Конвертация GRUB обозначения в Linux обозначение

Теперь, чтобы преобразовать строку вида hd0,gpt5 в строку /dev/sda5, нам нужно будет выделить определенные части строки. В GRUB нет поддержки регулярных выражений в том виде, как это реализовано в некоторых других языках программирования, но мы можем воспользоваться простыми строковыми операциями.

Шаг 3: Пример скрипта

Ниже приведен пример скрипта, который поможет вам преобразовать hdX в sdX, а также удалить ,gpt# или ,msdos#:

# Поиск устройства по метке
search --label <your_label> --set ROOTDEV

# Получаем строку из переменной ROOTDEV
set GRUB_DEV=${ROOTDEV}

# Разделение строки на устройство и номер
set DEVICE_PART=${GRUB_DEV%%,*}  # Получаем hd0
set PARTITION=${GRUB_DEV##*,}     # Получаем gpt5

# Конвертация hdX в sdX
set DEVICE_NUM=${DEVICE_PART#hd}  # Убираем hd
set DEVICE_NAME=s${DEVICE_NUM}      # Подставляем s

# Формирование окончательного имени устройства
set FINAL_DEVICE=${DEVICE_NAME}${PARTITION}
echo "Linux device name: /dev/${FINAL_DEVICE}"

Объяснение кода

  1. Нахождение устройства: Сначала мы ищем устройство по метке и сохраняем его в переменной ROOTDEV.
  2. Разделение переменной: Используем простые операции для получения имени устройства и номера раздела.
  3. Конвертация: Изменяем hdX на sdX, при этом принимаем во внимание различия в обозначениях.
  4. Формирование имени: Собираем полное имя устройства, добавляя номер раздела.

Примечания

  • Обратите внимание, что порядок устройств в GRUB и в Linux должен совпадать. Обычно hd0 соответствует /dev/sda, hd1 — это /dev/sdb и так далее.
  • В зависимости от конфигурации вашего оборудования и порядка загрузки может потребоваться дополнительная настройка, чтобы гарантировать правильность работы скрипта.

Заключение

Используя предложенный подход, вы сможете динамически генерировать имена устройств в нужном формате. Это решение позволяет вам обойти ограничение, связанное с отсутствием инициализации RAM-диска и использовать метки или UUID для загрузки нужной системы. Убедитесь, что вы тестируете конфигурацию на разных устройствах, чтобы гарантировать ее стабильность и правильность.

Оцените материал
Добавить комментарий

Капча загружается...