Linux в одном файле для Macbook

yooo1e0i2u4frjrlhnmtqifmpsy.png

TL; DR Можно уместить полноценный Linux Live дистрибутив в один файл, если вкомпилировать в ядро initramfs с корневой файловой системой. Компьютеры с UEFI умеют загружать такой файл напрямую, без помощи загрузчика типа GRUB. У меня получилось уместить дистрибутив с программами aircrack-ng, reaver и драйверами для карт Wi-Fi в файл размером 20 мегабайт (наверняка можно еще меньше).

Основные преимущества

  • Работает на любых компьютерах с UEFI — один и тот же файл будет работать на PC и Mac.
  • Не требует установки — достаточно скопировать один файл на EFI-раздел диска и указать в переменных NVRAM путь к этому файлу.
  • Не нужно устанавливать загрузчики GRUB, rEFInd — ядро Linux собранное с поддержкой EFI Stub можно грузить напрямую без промежуточного загрузчика.
  • Не нужны USB-флешки — скопированный на раздел EFI дистрибутив остается там навсегда, и его можно будет загрузить в любой момент. Он не занимает места на разделе основной системы, так как раздел EFI не используется в ОС.
  • Не изменяет процесс загрузки — систему можно загрузить один раз, без изменения порядка загрузки в настройках UEFI. Следующая перезагрузка компьютера загрузит обычную операционную систему. Никаких следов Linux в очередности загрузки не останется.
  • Совместимо с шифрованием диска FileVault и т.д. — файл копируется на EFI System Partition, специальный зарезервированный раздел диска. В компьютерах Mac его размер около 200 мегабайт. Он выделен под Boot Camp и обычно не используется

Зачем это нужно?


Для всех случаев, когда нужен нативный Linux без виртуальной машины.
Чтобы использовать PCIe-устройства в Linux, когда их нельзя прокинуть в виртуальную машину. Например, встроенную Wi-Fi-карту для инъекции пакетов. Когда лень устанавливать виртуальную машину и качать большой ISO файл с дистрибутивом. Когда не хочется возиться с USB флешками.
Единожды скопированный файл позволит всегда иметь под рукой дистрибутив Linux, который переживет даже переустановку системы.

Инструкция по установке на Mac


Все команды нужно выполнять из macOS.
Конфигурация загрузки не имеет значения, способ не нарушает работу BootCamp, rEFInd и любых других нестандартных конфигураций. Поддерживаются компьютеры Mac не старше 2009 года (работоспособность на более старых не проверялась, но может и заработать).

  1. Скачать файл OneFileLinux.efi (20 мегабайт)
  2. Смонтировать EFI-раздел в систему.
    mkdir /tmp/efi
    sudo mount -t msdos /tmp/efi /dev/disk_номер_раздела
    

    Узнать номер раздела EFI можно командой diskutil list.
    В моем случае путь будет /dev/disk0s1.
    _yh2j5hz9dqthcegf5sebnmxmui.png
  3. Скопировать OneFileLinux.efi в раздел EFI
    cp ~/Downloads/OneFileLinux.efi /tmp/efi/

  4. Добавить вариант загрузки в NVRAM
    sudo bless --mount /tmp/efi --setBoot --nextonly --file /tmp/OneFileLinux.efi
    

    Опция nextonly означает, что данный вариант загрузки будет выполнен один раз. Следующая перезагрузка восстановит прежние настройки. Поэтому, чтобы вернуться из Linux в macOS, достаточно перезагрузиться еще раз.


В последних версиях macOS, начиная с El Capitan, используется технология System Integrity Protection (SIP), так называемый «без root-вый режим». Эта технология запрещает модификацию системных файлов и переменных даже суперпользователю. SIP включен по умолчанию, поэтому последняя команда bless вернет ошибку. Ее можно выполнить из Recovery Mode. Для это нужно зажать cmd+R при включении компьютера и открыть консоль
Utilities —> Terminal. В консоли выполнить шаги 2 и 4


Теперь каждый раз, когда вам потребуется загрузить OneFileLinux.efi, достаточно выполнить шаги 2 и 4 в консоли Recovery, или из основной системы, если SIP выключен.
Наверное, можно выполнить bless без монтирования раздела, но я не нашел, как это сделать. Тогда было бы достаточно одной команды.

Инструкция для PC


Вариантов загрузки на PC множество. Если ваша материнская плата имеет встроенный UEFI Shell, достаточно в нем указать путь к файлу OneFileLinux.efi, чтобы единожды загрузиться в Linux. Я опишу процесс настройки на моем Thinkpad X220.

  1. Скачать OneFileLinux.efi и положить его на EFI-раздел
  2. Добавить опцию загрузки в NVRAM
    
    efibootmgr --disk /dev/sda --part 2 --create --label "One File Linux" --loader /OneFileLinux.efi

  3. Во время загрузки нажать F12 и выбрать нужный вариант
    wv6ftmykf6wncgtkzx7chiiz-cm.png

Инструкция по сборке из исходников


Исходники проекта github.com/zhovner/OneFileLinux
Дистрибутив собран на чистом ядре 4.16-rc1 с kernel.org и Alpine Linux Mini Root filesystem.
Его можно легко собрать самостоятельно.

Подготовка initramfs


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

Я использовал корневую файловую систему от Alpine Linux. Это минималистичный дистрибутив для встраиваемых систем и контейнеров. У него существует вариант поставки без ядра и предустановленных программ, только корневая файловая система на базе busybox и пакетный менеджер apk.

chroot-имся в alpine linux:

chroot ./alpine-minirootfs /bin/ash

Находясь внутри окружения, можно внести нужные изменения. Добавить пакеты через «apk add», модифицировать сервисы используя openrc.
Вся необходимая информацию есть в wiki wiki.alpinelinux.org

Когда все изменения внесены, нужно упаковать файловую систему в архив cpio.

exit #выйти из chroot
cd alpine-minirootfs
find . | cpio -H newc -o > ../alpineramfs.cpio

Сборка ядра


Полученный архив cpio нужно вкомпилить в ядро. Для этого нужно указать путь к архиву в конфиге ядра.


$ make menuconfig 
General Setup --->
   Initramfs source file

И собрать ядро

make -j4

Скопировать полученный файл

cp ./linux-4.16-rc1/arch/x86/boot/bzImage ./OneFileLinux.efi

Помогите!111

02rlqbfzey9ybq7kaddtdrh3gjs.png


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

Известные проблемы:

  • Отключена загрузка модулей ядра — все драйвера вкомпиливаются в ядро.
    Наверное, правильно сделать их отдельными модулями и положить в initramfs
  • Шрифты на HiDPI-дисплеях — из-за огромного разрешения HiDPI-экранов,
    стандартные шрифты 8×16 выглядят очень мелко. Я вкомпилил шрифт 16×32, который выглядит нормально при большой плотности пикселей, но слишком большой для обычных экранов. По-хорошему, шрифт должен выбираться в зависимости от разрешения экрана.
  • Только один драйвер карты WiFi — сейчас вкомпилен один драйвер для встроенного в макбуки адаптера Broadcom 43602. По-хорошему, нужно собрать все популярные драйвера в виде модулей ядра, а также firmware к ним.
  • Сломан udev/mdev?  — я не знаю, как он работает. Как правильно загружать модули в зависимости от конфигурации железа?
  • Мусор в ядре — в конфигурации ядра много лишних функций, которые можно выбросить. Это уменьшит размер итогового файла.

Приглашаю всех коммитить и создавать issues о проблемах github.com/zhovner/OneFileLinux

© Habrahabr.ru