Передача управления другому загрузчику по MBR ID в Syslinux.

Преамбула

Раз уж в прошлой заметке зашла речь про chainloading, т.е. передачу управления другому загрузчику из Syslinux, был разобран стандартный способ указания загрузчика в виде записи hdX Y, и определен минус этого способа, то можно рассказать и про устранение этого минуса.

Согласно спецификации, управление другому загрузчику можно передать не только указав номер диска и раздела, но и в следующем формате:

mbr:<id> [<partition>]

где:
<id> - уникальный MBR ID
<partition> - номер раздела жесткого диска

Схема нумерации разделов жесткого диска

Эта схема, конечно, для предыдущего случая, но разделы (а не диски), в обоих случаях нумеруются одинаково. А вот вместо hd0 (hd1, hd2…) будет mbr:<id>.

Пример конфига

Вот часть измененного конфига syslinux.cfg, где chainloading используется для загрузки Windows со второго раздела на первом жестком диске, только теперь жесткий диск определяется не по номеру, а по MBR ID:

LABEL windows
   menu label Microsoft Windows 7
   kernel modules/chain.c32
   append mbr:0x31c5dff2 2

Получение номера раздела, MBR ID и формирование записи конфигурации для загрузчика Syslinux

Сделал весь процесс в отдельной функции get_slid(), куда первым параметром передается имя устройства (с номером раздела или без), например, /dev/sda2.

1. Получим имя устройства без пути:

T_BN=`basename $1`

2. Получим номер раздела, удалив из начала имени все латинские буквы:

T_VOLNUM=`echo "$T_BN" | sed 's/^[a-z]*//'`

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

T_DSKNAM=`echo "$1"|sed 's/[0-9]\+$//'`

4. Проверим, не получилась ли пустая строка (может случиться, если в первый параметр что-то не то положили):

if [ -z "$T_DSKNAM" ]; then
    return 1 #error
fi

5. Получаем идентификатор MBR, способ указан в руководстве по chain.c32 [1]:

T_MBRID=`hexdump -s 440 -n 4 -e '"0x%08x\n"' "$T_DSKNAM"`

т.е. hexdump читает из MBR устройства 4 байта идентификатора, и выдает их в виде строки требуемого формата.

6. Формируем строку для конфигурации Syslinux:

SL_ID="mbr:$T_MBRID $T_VOLNUM"

7. Пример вызова функции:

if [ -z "$1" ]; then
    echo "Use "`basename $0` "<device>"
    exit
fi

get_slid "$1"

if [ "$?" -ne 0 ];then
    echo "Error!"
else
    echo "$1: $SL_ID"
fi

Скрипт целиком

На PasteBin
На GitHub

Источники

1. Comboot/chain.c32
2. Syslinux (Русский)

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *