Сломалась загрузка Arch Linux

2012-06-10

После последнего обновления сломалась загрузка Arch Linux на моём ноутбуке. Грузится ядро, но не находится корневая ФС. Arch Linux ломается у меня уже второй раз за год, это много.

У меня необычная конфигурация накопителей: ФС находится на флэш-карте SDHC, подключённой через карточитатель. Доступ к ней осуществляется через USB внутри ноута. Несколько слов о том, как Linux грузится в таких ситуациях.

  1. В настройках BIOS указывается накопитель, с которого компьютер начинает грузиться. Загрузчик считывается из его MBR и ему передаётся управление. BIOS современных ноутбуков умеют работать с накопителями по протоколу USB mass-storage.

  2. В MBR находится загрузчик GRUB, который средствами BIOS зачитывает файл ядра с ФС указанного раздела диска. Каким-то образом GRUB умеет понимать несколько разных файловых систем (как минимум, ext2, ext3 и ext4).

  3. В современных Linux ядра включают в себя не так много модулей. Модули подгружаются по мере необходимости при распознавании оборудования, например, через систему udev. Поэтому после загрузки ядра происходит подключение небольшого диска в RAM, содержащего начальные файлы и программы userspace, использующиеся для инициализации корневой ФС и передачи управления процессу init. Начальное ядро в Arch Linux не содержит даже модулей работы с USB и накопителями mass-storage.

  4. Начальная ФС в RAM генерируется для конкретной машины с различным набором опций в зависимости от оборудования программой mkinitcpio. Опции описаны в конфиге /etc/mkinitcpio.conf. Распознавание устройств USB и загрузка модулей ядра для поддержки USB добавляется следующими опциями:

    HOOKS='base udev usb'
    

Видимо, при обновлении слетел этот конфиг. Например, на его место перезаписался новый, и был сгенерирован образ initramfs, не содержащий поддержки USB. В пользу этой версии говорит то, что ядро грузится, инициализируется initramfs, загружается udev, однако устройство /dev/sdb1, представляющее мою корневую ФС на диске USB mass-storage в виде карточки SDHC, не находится.

Возможные варианты решения проблемы:

  • Установить на флэшку ядро с поддержкой USB, загрузить с неё корневую ФС, поправить конфиг и перегенерировать initramfs для поддержки USB

    Получить загрузочную флэшку с Arch Linux легко: достаточно скачать и записать образ диска с сайта. Но эта ядро флэшки может не уметь поддерживать USB и может содержать несовместимый с моим генератор mkinitcpio.

  • Переставить Arch Linux

    Точно поможет решить проблему, но займёт много времени. К тому же версионируемые конфиги /etc находятся на том самом диске, который придётся отформатировать, а зачитать их с другого компа я не могу, поскольку нет карточитателя SDHC.

  • Перейти на Mac OS

    Неплохой вариант, учитывая необходимую при этом замену ноутбука на более мощный и более подходящий для моих задач.

Для начала я решил попробовать пойти по первому варианту. Во-первых, он может подтвердить правильность моих предположений, ведь я подключу из-под другого ядра свою корневую ФС и смогу посмотреть на конфиг /etc/mkinitcpio.conf. Во-вторых, он самый простой, и если всё получится, то я потрачу меньше всего времени.

Мои предположения подтвердились. Действительно, оказался затёртым мой конфиг /etc/mkinitcpio.conf. Надо было исправить его и перегенерировать образ. Генератор mkinitcpio с загрузочной флэшки не подходил, потому что там более старое ядро и окружение, что приводило к разным ошибкам при генерации. В mkinitcpio можно указать, откуда брать версию ядра и каталог с его модулями, но это не помогло справиться со всеми ошибками.

Я решил сделать chroot-окружение на своём корневом диске и использовать mkinitcpio оттуда. После нескольких попыток запуска и разбирательств с неподключёнными системными виртуальными ФС я узнал об опции mount -o bind для подключения уже подключённой ФС на другую точку подключения и жизнь наладилась:

$ mount -o bind /proc /mnt/flash-root/proc
$ mount -o bind /dev /mnt/flash-root/dev
$ mount -o bind /sys /mnt/flash-root/sys

Затем оставалось лишь сгенериовать initramfs, указав версию ядра, отличную от запущенной в данный момент:

$ chroot /mnt/flash-root
$ mkinitcpio -k 3.3.8-1-ARCH -g /boot/initramfs-linux.img

Эта история с очередной поломкой Arch Linux ещё немного приблизила меня к переходу на Mac OS.