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



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

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


    • Работает на любых компьютерах с 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-раздел в систему.

      diskutil mount disk_номер_раздела 
      

      Узнать номер раздела EFI можно командой diskutil list.


      В моем случае команда будет выглядеть так:
      diskutil mount disk0s1 
      

    3. Скопировать OneFileLinux.efi в раздел EFI

      cp ~/Downloads/OneFileLinux.efi /Volumes/EFI/

    4. Добавить вариант загрузки в NVRAM

      bless --mount /Volumes/EFI --setBoot --nextonly --file /Volumes/EFI/OneFileLinux.efi
      

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

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

    Теперь каждый раз, когда вам потребуется загрузить 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 и выбрать нужный вариант



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


    Исходники проекта 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.

    Сборка


    Запустить скрипт сборки. Он соберет модули ядра, поместит их в initramfs, и соберет ядро.
    
    ./build.sh
    


    Помогите!!111



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

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

    • Отключена загрузка модулей ядра — все драйвера вкомпиливаются в ядро.
      Наверное, правильно сделать их отдельными модулями и положить в initramfs

      Исправлено
    • Шрифты на HiDPI-дисплеях — из-за огромного разрешения HiDPI-экранов,
      стандартные шрифты 8x16 выглядят очень мелко. Я вкомпилил шрифт 16x32, который выглядит нормально при большой плотности пикселей, но слишком большой для обычных экранов. По-хорошему, шрифт должен выбираться в зависимости от разрешения экрана.

      Исправлено. Теперь автоматически выбирается большой шрифт для HiDPI экранов. Также размер шрифта можно изменить в любой момент командой fontsize.
    • Только один драйвер карты WiFi — сейчас вкомпилен один драйвер для встроенного в макбуки адаптера Broadcom 43602. По-хорошему, нужно собрать все популярные драйвера в виде модулей ядра, а также firmware к ним.
      Исправлено. Добавлена поддержка многих популярных WiFi адаптеров.
    • Сломан udev/mdev? — я не знаю, как он работает. Как правильно загружать модули в зависимости от конфигурации железа?
      Исправлено
    • Мусор — сейчас вместе с ядром устанавливается большое количество устаревших драйверов. В несжатом виде модули ядра весят более 100 мегабайт. Большую часть из них можно исключить.

    Приглашаю всех коммитить и создавать issues о проблемах github.com/zhovner/OneFileLinux.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 47
    • +1
      Разве адаптер Broadcom 43602 поддерживает инъекции пакетов и режим мониторинга? Насколько я знаю, драйвер brcmfmac не поддерживает ни то, ни другое.
      • 0
        К сожалению да, не умеет. Инъекции и мониторинг поддерживали карты в старых макбуках 2009-2010 года, которые 802.11n. Примечательно, что виноват драйвер brcmfmac, потому что сама карта поддерживает мониторный режим, он работает в macOS через встроенную утилиту Wireless Diagnostics.app.
        • 0
          Как минимум мониторинг поддерживается даже из самой МакОси стандартными утилитами, в этот момент значок вайфай меняется на глаз. Вроде бы из под линя можно и инъекции производить.
      • 0
        Подписался на репо, будем следить
        • 0
          На моем macbook 2012 года шрифт огромный. Читать затруднительно.
          • 0
            Да, есть такая проблема, она описана в конце. Дело в том, что на ретина экрана, шрифт настолько мелкий, что его не удается прочесть. Поэтому пришлось жестко задать этот огромный шрифт. По-хорошему, нужно выбирать шрифт автоматически в зависимости от разрешения экрана, но я не умею так делать.
            • 0
              По-хорошему, — если не можете автоматизировать какой-то процесс, то дайте возможность сделать выбор пользователю.

              Вшивание шрифта в ядро собственно и сделано для того, чтобы ничего не выбирать. Ни автоматически, ни в ручную. Но если уж сильно приспичит, то это можно сделать через передачу параметров ядру. Обычно это делается на этапе выбора ядра в любимом загрузчике.
              • 0
                Обычно это делается на этапе выбора ядра в любимом загрузчике

                Смысл моего подхода в том, что загрузчик не используется. Параметры ядра можно передать через UEFI переменную.

                если не можете автоматизировать какой-то процесс, то дайте возможность сделать выбор пользователю


                На сколько мне известно, шрифт можно выбрать после загрузки init. Так делается в популярных дистрибутивах. Но я этот вопрос еще не изучал.
                • 0
                  Нет, шрифт можно задать в /linuxrc, о чём я уже писал. Равно как и раскладку клавиатуры, кодовую страницу и т.п. А уже по окончанию всего этого безобразия передать управление /sbin/init. у себя в RTK GNU/Linux я так и делал, чтобы писать сообщения процесса инициализации на языке, отличном от английского, пока ядро там свои дела проворачивает. Но это было 10 лет назад.

                  В общем, в BOOTDISK-HOWTO всё написано.
            • 0
              Зачем прогибаться под SIP, если его можно отключить так:csrutil disable в Recovery mode?
              • +3
                Да, так можно сделать, но я считаю, что это полезная функция. У нормального пользователя нет никаких причин отключать ее.
                • 0
                  Потому что потом ваш мак прогнут под себя другие. После отключения SIP он становится существенно более уязвимым.
              • 0
                Очень удобно
                • 0
                  Всем добрый вечер, возникает ошибка:
                  mount_msdos: /dev/disk0s1: not a directory
                  при вводе sudo mount -t msdos /tmp/efi /dev/disk0s1

                  Вывод diskutil:
                  /dev/disk0 (internal):
                  #: TYPE NAME SIZE IDENTIFIER
                  0: GUID_partition_scheme 251.0 GB disk0
                  1: EFI EFI 314.6 MB disk0s1
                  2: Apple_CoreStorage Macintosh HD 250.0 GB disk0s2
                  3: Apple_Boot Recovery HD 650.0 MB disk0s3

                  /dev/disk1 (internal, virtual):
                  #: TYPE NAME SIZE IDENTIFIER
                  0: Apple_HFS Macintosh HD +249.7 GB disk1
                  Logical Volume on disk0s2
                  E84C5091-EE4E-4EC6-8497-AE8799151BB7
                  Unlocked Encrypted
                  • 0
                    Прошу прощения, перепутал местами параметры.

                    Правильно так:
                    sudo mount -t msdos /dev/disk0s1 /tmp/efi
                    
                    • 0

                      zhovner, с планшетами не дружит?

                      • 0
                        Если у вас на планшете 32-битный UEFI, то, вероятно, придется использовать 32-битное ядро.
                        Если у вас включен Secure Boot, то выключите его.
                    • +1
                      Все проще — mkdir и sudo не нужны:
                      diskutil mount disk0s1
                      

                      • 0
                        О, класс, спасибо. Может вы знаете как bless без монтирования выполнить?
                        • 0
                          Попробовать поиграть с
                          bless --device
                  • 0
                    Добрый вечер, вылетает вот такая ошибка на последнем шаге:

                    ~ » sudo bless --mount /tmp/efi --setBoot --nextonly --file /tmp/OneFileLinux.efi
                    Can't statfs /tmp/OneFileLinux.efi
                    • +1
                      У вас неправильный путь. Посмотрите как вы монтировали EFI раздел. Файл должен быть в /tmp/efi/OneFileLinux.efi
                    • +1
                      ты сделал то что я планировал начать делать целый год)))
                      огромное спасибо, может для кого-то это и «нинужно» а вот у меня есть несколько реальных применений такому проекту…
                      • 0
                        linuxrc вам в корень.
                        • –2
                          "Работает на любых компьютерах с UEFI — один и тот же файл будет работать на PC и Mac.
                          Не нужно устанавливать загрузчики GRUB, rEFInd — ядро Linux собранное с поддержкой EFI Stub можно грузить напрямую без промежуточного загрузчика.
                          Не нужны USB-флешки — скопированный на раздел EFI дистрибутив остается там навсегда, и его можно будет загрузить в любой момент. Он не занимает места на разделе основной системы, так как раздел EFI не используется в ОС."

                          Исходя только из этого — это отличная новость для вирусописателей.
                          Теперь ждем новые волны «неубиваемых» вирусов!
                          Более того печальней всех маководам, которые раньше смеялись над виндузятниками.
                          Дохихикались.
                          • 0
                            Для решения это проблемы как раз придуман secure boot, который уже есть и в Mac, правда пока только в iMac pro. Впрочем, Mac долгое время был подвержен уязвимости Thunderstrike, позволяющий прошить вредонос в саму прошивку на материнской плате, так что даже файлов на диске не было бы.

                            Сценарий который вы описали крайне маловероятен. Если у вас включен SIP (проверить можно командой csrutil status) то никакая программа, даже вы сами, не сможете модифицировать nvram для загрузки вредоносного файла из операционной системы.

                            Если предположить, что атакующий имеет физический доступ к компьютеру, тогда достаточно установить пароль на EFI, который будет запрашивать при любой попытке изменить очередность загрузки. То есть при попытке зайди в recover mode нажатием cmd+r.

                            Рекомендую всем установить пароль на прошивку:

                            1. При загрузке зажать cmd+R.

                            2. Зайти в меню Утилиты --> пароль прошивки

                          • 0
                            Может стоит использовать какое-нибудь LTS-ядро (4.14/4.4)?
                            Под >4.15 — нет стабильно работающего 8814au.

                            P. S.: Могу потестировать билд с драйверами для iwlwifi, ath9k, ath9k_htc, rt2800usb и упомянутого 8814au.
                            • 0
                              Вероятно, вы правы. Я не раздумывал долго и взял последнее в списке на kernel.org.
                              Я вот только не знаю как перенести .config с одной версии ядра на другое. Там ведь отличаются опции и их названия.

                              Сейчас решаю проблему с неработающей SPI клавиатурой на новых макбуках 2015-2017 года github.com/cb22/macbook12-spi-driver

                              • 0
                                Да ладно. А я-то дурак один и тот же конфиг годами использую…

                                Нормально всё будет, я сто раз так делал. При downgrade, те опции, которых нет в 4.14.x будут проигнорированы.
                                • +3
                                  Для переноса .config достаточно его скопировать и выполнить make oldconfig. Всё возможное перенесётся, про разницу будут заданы вопросы.
                              • 0
                                Виртуалка с Kali + внешний адаптер на деле оказывается более удобным.
                                • 0
                                  Да, согласен. Но в нужный момент этого адаптера не оказывается под рукой. Образ kali весит 2GB, еще нужно украсть Vmware Fusion, потому что Virtualbox имеет проблемы с пробрасыванием USB устройств. Я как раз пытался найти более элегантное решение. Жаль только, что встроенная wifi карта в macbook 2015 не умеет ни мониторинг под линуксом, ни инъекции.
                                  • 0
                                    Parallels еще можно «купить» как вариант ) а еще, есть HyperKit от Apple (возможно там проброс будет ок )
                                    • 0
                                      HyperKit от Apple

                                      Ухты, никогда об этом не слышал. Спасибо.
                                      • 0
                                        соврал похоже, не от эпл, но там нативный для osx виртуализации движок юзается как я понял.
                                        • 0
                                          тоже не совсем, там через докер и Hypervisor.framework. компонента докера docker.com
                                    • 0
                                      Что за проблемы? Я лично давно с похожим не сталкивался…
                                  • 0
                                    Приветствую. На команду «sudo bless --mount /Volumes/EFI --setBoot --nextonly --file /Volumes/EFI/OneFileLinux.efi» терминал ругался. Без sudo всё прошло успешно.
                                    Но у меня крайне дилетантский вопрос. Крузится Alpha и спрашивает «onefilelinux login». Я погуглил. Ввёл root. А дальше вроде как нужно вводить setup-alpha. Но команда не работает. Что не так делаю?
                                    Заранее благодарю за ответ.
                                    • 0
                                      Без sudo всё прошло успешно.

                                      Речь про recovery режим? Тогда все правильно, там не нужно вводить sudo, потому что она и так запущена от пользователя root.

                                      спрашивает «onefilelinux login». Я погуглил. Ввёл root. А дальше вроде как нужно вводить setup-alpha.

                                      После того как вы ввели root, вас пускает в консоль. Это конец. Дальше вы либо делаете что вам нужно, либо вводите reboot и перезагружаетесь обратно в macOS.

                                      Графического интерфейса нет. Возможно, мы добавим его позже, но я не уверен.
                                    • 0
                                      Скрипт запилил для macOS, пользуйтесь, оптимизируйте:
                                      gist.github.com/aquigni/5097f40413f53da5a75bc29309cc0059

                                      #!/bin/sh
                                      cd ~/Downloads/
                                      
                                      ### Checking if Homebrew is installed:
                                      command -v brew >/dev/null 2>&1 || {
                                      	echo >&2 "Installing Homebrew:"
                                      	/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
                                      }
                                      
                                      ### Getting wget:
                                      brew install wget
                                      
                                      ### Getting latest OneFileLinux.efi release via GitHub API:
                                      curl -s https://api.github.com/repos/zhovner/OneFileLinux/releases/latest |
                                      	grep "browser_download_url.*efi" |
                                      	cut -d : -f 2,3 |
                                      	tr -d \" |
                                      	wget -i -
                                      
                                      ### Find first macOS disk (containing Recovery HD by default) and mounting its EFI partition:
                                      diskutil mount $(diskutil info "Recovery HD" |
                                      	grep "Part of Whole" |
                                      	grep -Eo '.{5}$')s1
                                      
                                      ### Or just mount default EFI partition:
                                      # diskutil mount disk0s1
                                      
                                      ### Check if SIP is enabled:
                                      if csrutil status | grep "NVRAM Protections: disabled"; then
                                      	echo "NVRAM isn't protected, continuing:"
                                      	mkdir -p /Volumes/EFI/EFI/OneFileLinux
                                      	cp -v OneFileLinux.efi /Volumes/EFI/EFI/OneFileLinux/boot.efi
                                      	sudo bless --mount /Volumes/EFI/EFI/OneFileLinux --setBoot --nextonly --file /Volumes/EFI/EFI/OneFileLinux/boot.efi --verbose
                                      else
                                      	echo "System Integrity Protection is enabled, disabling only available in Recovery OS." >&2
                                      	exit 1
                                      fi
                                      
                                      
                                      • 0
                                        Интересно, получится ли запилить полноценный Linux-дистро таким образом? :)
                                        • 0
                                          Скорее да, при условии, что влезет в ~200 Мб EFI раздела.
                                        • 0
                                          Чорд. Винда под EFI раздел только 100 метров выделяет.
                                          • 0
                                            Последняя версия onefilelinux весит 27 мегабайт, должно хватить места.
                                            • 0
                                              Можно создать разметку GPT на флешке, отформатировать раздел в FAT32 и добавить флаг ESP.
                                              Если onefilelinux будет находится в файле по адресу /EFI/BOOT/BOOTX64.EFI и Secure Boot будет отключен — должно запустится при выборе флешки в качестве загрузочного устройства. Не уверен, что такой способ поможет запуску на Mac.

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

                                            Самое читаемое