Надеюсь вам ещё не надоел этот танцующий пупс
Надеюсь, вам ещё не надоел этот танцующий пупс

Или ещё один способ показать своё превосходство над "average Windows fan".

Дружим современный мем со старым и почти забытым инструментом.

Предыстория

Если девушки после сложного этапа в жизни делают причёску каре, то программные инженеры переустанавливают операционную систему на домашнем ПК.

Сложного этапа в жизни не случилось, но систему в очередной раз переустановить захотелось. И так как в качестве системы я выбрал Arch Linux, то решил настроить его максимально "по фэншую". Стандартный логотип Gigabyte при загрузке системы моим понятиям "фэншуя" не отвечал, поэтому я занялся поиском решения и наткнулся на Plymouth.

Что такое Plymouth и с чем его едят?

Согласно ArchWiki:

Plymouth — это проект Fedora и один из официальных проектов freedesktop.org, реализующий графический экран загрузки системы без бегущих надписей (логов) на экране

Plymouth добавляет в вашу систему 2 бинарных файла:

  1. /sbin/plymouthd - "backend" Plymouth, пишет логи, показывает заставку;

  2. /bin/plymouth - "frontend" Plymouth, через него можно вызывать различные действия plymouthd;

и позволяет изменять графический экран загрузки системы с помощью механизма "тем".

Тема Plymouth - это директория в /usr/share/plymouth/themes/, которая содержит следующие файлы:

  1. .plymouth (обязательный) - главный файл темы, через него plymouth понимает, как называется тема, где хранится файл .script (если есть) и директория с изображениями.

  2. .script - здесь описывается вся логика работы темы (если она есть) на специальном языке [8].

  3. .grub - дополнительный скрипт загрузчика.

  4. Вспомогательные файлы, обычно изображения в формате .png

То есть с помощью темы Plymouth можно установить любую картинку/анимацию на процесс загрузки. Звучит как ровно то, что нам нужно, погнали устанавливать!

Устанавливаем!

Процесс установки покажу только для Arch + GRUB2 + GDM/GNOME. Установка на другие дистрибутивы и конфигурации будет аналогичной, либо он вообще будет доступен "из коробки" (например, Ubuntu).

  1. Устанавливаем пакет

    yay -S plymouth-git
    Почему AUR-версия?

    Вы можете попробовать использовать версию из официальных репозиториев (pacman -S plymouth), однако с ней у меня не получилось заставить тему запускаться во время загрузки.

  2. Настраиваем параметры загрузки:

    1. Добавляем параметр splash в параметры ядра для отображения графического экрана загрузки

    2. Добавляем параметр quiet для тихой загрузки

    /boot/grub/grub.cfg
    ...
    menuentry "Arch Linux" {
      ...
      linux ... quiet splash
      ...
    }
    ...

  3. Добавляем хук plymouth в initramfs

    /etc/mkinitcpio.conf
    ...
    HOOKS = (... plymouth ...)
    ...

  4. Собираем образ initramfs и перезагружаем систему

    # Запускать с правами root
    mkinitcpio -P && reboot
  5. ???

  6. PROFIT!

Если бы всё было так просто... (a.k.a Troubleshooting)

Обычно установка Plymouth проходит гладко, но при возникновении проблем могу посоветовать следующие действия:

  1. Включить отладочные логи Plymouth

    /boot/grub/grub.cfg
    ...
    menuentry "Arch Linux" {
      ...
      linux ... quiet splash plymouth:debug
      ...
    }
    ...

    После перезагрузки логи появятся в файле /var/log/plymouth-debug.log (обновляется после каждого перезапуска)

  2. Внимательно прочитать секции Tips&Tricks и Troubleshooting на ArchWiki

  3. Проверить, что вы корректно настроили проприетарные драйвера NVIDIA

  4. Замедляем загрузку, чтобы анимация успела отрисоваться

    Действие, которое помогло мне запустить свою кастомную тему (о ней будет дальше).
    Если доступен systemd во время запуска Plymouth (как я понял, достаточно в /etc/mkinitcpio.conf заменить хук udev на systemd), то можно сделать сервис, который придержит загрузку системы на n секунд, чтобы анимация успела отрисоваться.

    /etc/systemd/system/plymouth-wait-for-animation.service
    [Unit]
    Description=Waits for Plymouth animation to finish
    Before=plymouth-quit.service display-manager.service
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/sleep animation_duration_in_secs
    
    [Install]
    WantedBy=plymouth-start.service
    

    Не забудьте включить сервис: systemctl enable plymouth-wait-for-animation.service

Customization Time!

Фух, самая сложная часть выполнена, теперь можно приступать к творческому процессу.

Мне пришла в голову идея добавить в процесс загрузки танцующего малыша енота (да, я фанат енотов) из популярного в этих ваших тиках токах мема.

Итак, начинаем начинать! (Исходный код)

  1. Создаём директорию нашей новой темы и её основные файлы

    # Запускать с правами root
    mkdir /usr/share/plymouth/themes/pedro-raccoon
    cd /usr/share/plymouth/themes/pedro-raccoon
    touch pedro-raccoon.plymouth pedro-raccoon.script
  2. Описываем pedro-raccoon.plymouth

    pedro-raccoon.plymouth
    [Plymouth Theme]
    Name=Pedro Raccoon Plymouth
    Description=Pedro Raccoon Meme Plymouth
    ModuleName=script
    
    [script]
    ImageDir=/usr/share/plymouth/themes/pedro-raccoon
    ScriptFile=/usr/share/plymouth/themes/pedro-raccoon/pedro-raccoon.script
    

    [Plymouth Theme] - Секция, в которой описывается метаинформация темы
    ModuleName - Не нашёл какие ещё могут быть варианты ModuleName, но обычно все ставят script
    [script] - Секция, в которой описывается метаинформация для работы скрипта Plymouth
    ImageDir - Корневая директория с изображениями (почему-то все используют корневую директорию, не уверен, что Plymouth умеет нормально работать с вложенными директориями)

  3. Подготовим раскадровку анимации нашего енота

    В качестве базового изображения подойдёт .gif или видео-файл, я использовал .gif отсюда. Делаем раскадровку, например, через ffmpeg:

    ffmpeg -i pedro-raccoon.gif animation-%d.png

    Полученные картинки необходимо поместить в корневую директорию изображений (по пути, указанному в ImageDir)

  4. Пишем скрипт:

    pedro-raccoon.script
    // Получаем настройки экрана
    screen.w = Window.GetWidth();
    screen.h = Window.GetHeight();
    screen.half.w = screen.w / 2;
    screen.half.h = screen.h / 2;
    
    // Подгружаем изображения для анимации
    images_count = 198;
    
    for (i = 0; i < images_count; ++i) {
        images[i] = Image("animation-" + (i + 1) + ".png");
    }
    
    // Plymouth рисует изображения, обёрнутые в объект Sprite
    // Готовим его и помещаем в центр экрана
    cur_sprite = Sprite();
    cur_sprite.SetX(screen.half.w - images[0].GetWidth() / 2);
    cur_sprite.SetY(screen.half.h - images[0].GetHeight() / 2);
    
    // Timestamp процесса отрисовки анимации 
    ts = 0;
    
    // Объявляем функцию для обновления экрана
    // Она будет вызываться до 50 раз в секунду
    fun update() {
        // Оборачиваем подгруженные изображения в Sprite
        // Цикл реализуем с помощью операции mod
        // Обратите внимания на костыль для замедления анимации (ts / 1.6)
        // Он нужен для того, чтобы наш енот танцевал не так быстро (значение подобрано эмпирически)
        cur_sprite.SetImage(images[Math.Int(ts / 1.6) % images_count]);
    
        ts++;   
    }
    
    Plymouth.SetRefreshFunction(update);
    

  5. Проверяем, что всё работает

    # Запускать с правами root
    plymouth-set-default-theme -l
    
    bgrt
    details
    fade-in
    glow
    pedro-raccoon # <- Созданная нами тема
    script
    solar
    spinfinity
    spinner
    text
    tribar
    
    # Запускать с правами root
    plymouth-set-default-theme -R pedro-raccoon

    Важно после установки темы пересобирать образ initramfs (флаг -R делает это автоматически)

    Теперь запустим отладку Plymouth в текущем tty:

    # Запускать с правами root
    plymouthd --debug --debug-file=/tmp/plymouth-debug-out ; plymouth --show-splash ; for ((I=0;I<10;I++)); do sleep 1 ; plymouth --update=event$I ; done ; plymouth --quit

    После запуска этой команды, вы должны увидеть установленную тему Plymouth. Если что-то пошло не так, то это можно увидеть либо в консоли, либо в файле /tmp/plymouth-debug-out

  6. Перезагружаем систему и наблюдаем красоту

Заметки по Plymouth Script

  1. Язык во многом похож на C и JS.

  2. Поддерживает картинки (как минимум .png), но не поддерживает .gif, видео, звуки.

  3. Низкая популярность не добавляет удобства к использованию, однако язык достаточно простой.

  4. Язык достаточно мощный для того, чтобы, например, написать на нём тетрис.

  5. Обратите внимания на костыли для анимации (замедляем анимацию)

Заключение

С распространением быстрых SSD-накопителей процесс загрузки системы на большинстве устройств занимает несколько секунд, что сильно снижает актуальность Plymouth. Несмотря на это я все равно решил пожертвовать парой секунд загрузки для того, чтобы сделать свою систему чуть более дружелюбной и чуть менее скучной.

К сожалению, я не смог вместить в эту статью всех тех "прелестей", с которыми мне пришлось столкнуться, пока я настраивал Plymouth и разрабатывал эту тему, но бОльшая часть из них была связана с моей неполнотой знаний о Plymouth и об Arch Linux в целом.

В общем, я доволен получившимся результатом, и надеюсь, что данная статья привлечёт внимание к Plymouth, вдохновит кого-то на создание интересных тем и вариантов использования этого инструмента и ему подобных.

Источники и ссылки

  1. Статья про Plymouth на ArchWiki

  2. Гайд по установке проприетарных драйверов NVIDIA на Arch Linux

  3. Гайд по созданию своих тем Plymouth (Часть 1)

  4. Гайд по созданию своих тем Plymouth (Часть 2)

  5. Гайд по созданию своих тем Plymouth (Часть 3)

  6. Гайд по созданию своих тем Plymouth (Часть 4)

  7. Тетрис на Plymouth

  8. Введение в язык скриптов Plymouth

  9. Исходный код Pedro Raccoon Plymouth

  10. Pedro Raccoon Plymouth на pling

UPD: По просьбам в комментариях - видосы с результатом!

Сам процесс загрузки системы (на меня и пыльный монитор не смотрите). Противный монитор немножко всё портит своими информационными сообщениями о разрешении, пока не нашёл, можно ли это выключить.

Обратите внимание на то, что анимация проигрывается не сначала. Могу сделать вывод, что Plymouth некоторое время тупит и рендерит анимацию без показа на экран.

Ну и ниже демка через прямой запуск plymouthd && plymouth --splash-screen

Комментарии (47)


  1. Lainhard
    23.04.2024 15:14
    +22

    Где видос с загрузочным енотом?! Это очень важно!


    1. MagisterAlexandr
      23.04.2024 15:14

      Не заслужили.

      Поставить Linux, накатить скрипты — тогда и будет видос.


    1. r1412s
      23.04.2024 15:14
      +1

      Так вот жэ


    1. awesomechekushka Автор
      23.04.2024 15:14
      +1

      Видосы добавил) Согласен, с моей стороны было кощунством их не приложить


  1. Nurked
    23.04.2024 15:14
    +6

    Дмитрий, действительно видос надо.

    Спасибо за статью. К сожалению, не знаю, нафига это надо. Линь на SSD загружается за пол-секунды. Верее, Plymoth показывается только с пол-секунды, потом что-то другое. Надо будет как-то замедлять загрузку системы, чтобы насладиться.


    1. AWRDev
      23.04.2024 15:14
      +1

      Сказали про замедление системы ради наслаждения загрузкой, а я вспомнил про такую "проблему" с играми, например, серии GTA, где теперь 2-3 картинки успеваешь увидеть, а в 3Dшных вообще одна только успевает промелькнуть.

      В общем, эти две мысли объединились и теперь я хочу загрузку ОС в стиле этих игр, ну чтобы там Сатья Наделла, Тим Кук ну и т.д. на соответствующем фоне))


    1. awesomechekushka Автор
      23.04.2024 15:14

      Рад, что статья понравилась.
      В секции Troubleshooting как раз указал, как можно замедлить систему + на ArchWiki про это тоже есть.
      Пробуйте и наслаждайтесь)


  1. Johan_Palych
    23.04.2024 15:14
    +1

    C Plymouth нормально не переключишься на другое ядро или ОС
    Всегда на Debian(Ubuntu) делаю так:

    sudo cp /etc/default/grub /etc/default/grub.bak
    ---
    sudo cat <<EOF | sudo tee /etc/default/grub
    GRUB_DEFAULT=0
    GRUB_TIMEOUT=5
    GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
    GRUB_DISABLE_SUBMENU=y
    GRUB_CMDLINE_LINUX_DEFAULT=""
    GRUB_CMDLINE_LINUX=""
    GRUB_DISABLE_OS_PROBER=false
    EOF
    ---
    sudo update-grub


    1. NickDoom
      23.04.2024 15:14

      О, а у меня проблема с внешним видео на ноуте (воткнуто вместо вайфая при помощи китайского переходника с мини-экспресса на экспресс).

      Биос отлично видит, внешний дисплей стартует вместо родного бучного, Грубиян никаких возражений не выказывает, но в тот момент, когда чисто текстовый лог должен смениться «текстом в графическом режиме», всё виснет вглухую.

      Уж не Плимутрок ли пытается кукарекнуть в этот момент? Или Инитрд не может нормально передать полномочия?

      Кто сталкивался и не начать ли мне тоже с вышеописанного?


      1. Johan_Palych
        23.04.2024 15:14
        +1

        Стартануть без внешней видео и посмотреть логи:
        sudo journalctl --list-boots
        для примера:
        sudo journalctl -p 3..1 -xe --since "Sun 2024-03-31 15:58:27"


  1. JohnDoe_71Rus
    23.04.2024 15:14
    +1

    эти логотипы производителей в uefi забавная штука. Может быть знатоки подскажут.

    Была установлена лубунта 22.04 и при загрузке плимут показывал голубенький фон и кружок с птичкой. Беда случилась при замене монитора. Подключил новый кабелем dp и попал на проблему 20 контакта. Хорошо, железо не спалил, но при включении компа получал восстановление биоса из резервной копии. Проблему с кабелем dp решил, но после этого система стала показывать при загрузке лого гигабайта на черном фоне, и под ним крутится кружок лого лубунты. Пропал красивый голубой фон. Как вернуть фон обратно?

    Больше никакого изменения железа не было, и система на тот момент не обновлялась. Или подскажите какой фразой у гугла правильно спросить.


    1. Panzer_Ex
      23.04.2024 15:14
      +1

      Могу ошибаться, но похоже что bios свалился MBR вместо UEFI. В разделе Загрузка биоса что у Вас?


      1. JohnDoe_71Rus
        23.04.2024 15:14
        +1

        В разделе Загрузка биоса что у Вас

        Сейчас не скажу, я в другом городе. но система устанавливалась в режиме uefi, с созданием uefi раздела на диске. и все продолжает нормально функционировать. разве в случае MBR была бы загрузка с uefi ?


        1. Panzer_Ex
          23.04.2024 15:14
          +3

          Да, MBR не находит и загрузка переходит на UEFI. Это заметно по большей длительности процесса. Опять же, могут быть нюансы в зависимости от биоса.

          Почему знаю, у меня старый ноут Леново, после глюка батареи случился сброс биоса на настройки по умолчанию. Тоже наблюдал лого Леново и значок Убунты на загрузке.


  1. Panzer_Ex
    23.04.2024 15:14
    +4

    Вспомнились старые добрые времена, когда народ boot.bmp на Win9x менял. На черепа, веселые роджеры и прочее. Благо тогда наблюдать их на экране загрузки приходилось долго :)


    1. vesper-bot
      23.04.2024 15:14
      +2

      *logo.sys


      1. Panzer_Ex
        23.04.2024 15:14

        Точно! И понимал он только bmp формат, почему и запомнилось. :)


        1. AKudinov
          23.04.2024 15:14

          Там ещё и пиксели были не квадратные, а вытянутые по горизонтали.


          1. UranusExplorer
            23.04.2024 15:14
            +1

            Да, при его отображении на видеоадаптере выставлялось редкое VGA-разрешение 320x400. Зачем именно такое - точно не знаю, но насколько я помню, оно по "таймингам" совпадает со стандартным текстовым режимом 720x400, возможно сделали так, чтобы переключении туда-сюда аналоговые мониторы не "щелкали" выполняя пересинхронизацию. С ним же совпадает и более привычное 640x400, не знаю, почему не взяли его, может память экономили.


        1. DaemonGloom
          23.04.2024 15:14
          +2

          Boot.bmp вам запомнился, скорее, из Windows XP. Там он назывался именно так.


  1. nronnie
    23.04.2024 15:14
    +1

    но систему в очередной раз переустановить захотелось

    Я думал только виндовс надо регулярно переустанавливать, не?


    1. feelamee
      23.04.2024 15:14
      +5

      виндовс надо

      а линукс хочется)


      1. NibiruanChild
        23.04.2024 15:14
        +1

        Уже лет 10 как не занимался перестановкой винды, при том что в семье 2ноута и компьютер + подопечные 2 компьютера родителей + компьютер и ноут у брата. И между версиями обновлял с 10 на 11, и откатывал с 11 на 10 без переустановки, и мать любит по сомнительным ссылочкам от дяди миллионера из Африки перейти, и в целом сценарии использования на всех компьютерах разные. Прошло то время, когда Винду надо было переустанавливать раз в год просто в качестве профилактики.

        Уверен, что любую ось можно убить до состояния когда только переустановка поможет. У меня 14 лет опыта с Линукс в качестве основной системы и за это время было много случаев, когда переустановить было быстрее чем проблемы после обновления решать.


    1. Titsubishi
      23.04.2024 15:14

      Нет везких причин переустанавливать Linux. Разве что поиграться с установочными конфигурациями или другие ОС попробовать для себя. В линуксе, по-моему, отлично реализована очистка от мусора в системе.


      1. sdore
        23.04.2024 15:14

        Т.е. не реализована никак? Он попросту не копится.