rootfs tar что это
Образ rootfs
Содержание
Что такое rootfs
rootfs, то есть root file system, корневая файловая система — это архив с минималистичной системой, грубо говоря, это как если бы вы открыли файловый менеджер в корне своего Linux и запаковали всё найденное в архив, только здесь предустановлено минимально необходимое количество пакетов.
Для чего нужен rootfs
Где скачать rootfs Росы
Раз в день автоматически выполняются сборки rootfs архитектур x86_64 и i586 на платформах rosa2016.1 и rosa2014.1.
Найти и скачать самые свежие сборки можно здесь.
Образы rootfs-min — это минималистичный образ (ввиду того, что некоторые пакеты в репозитории сейчас тянут лишние зависимости, в rootfs также есть лишние пакеты, например, grub2). Образы rootfs-std — это более расширенный набор пакетов, добавлены пакеты, необходимые для сборки других пакетов (rpm-build, git-core и др.).
Порядок скачивания последней сборки rootfs
Как собрать rootfs самому
Нужно взять скрипты сборки и запустить mkimage-urpmi.sh.
Патчи и пулл-реквесты для улучшения скриптов сборки принимаются на Github.
Пример использования rootfs
Разберем на примере ежедневной сборки №25111. Контейнер назовем «rosa1».
В команде wget выше
Пример использования на BTRFS для быстрого клонирования контейнеров
/var/lib/machines должно быть внутри раздела BTRFS.
В итоге у нас есть 3 одинаковых контейнера: /var/lib/machines/rosa1, /var/lib/machines/rosa2, /var/lib/machines/rosa3. Поскольку они одинаковые, место на диске занимается 1 раз, а не 3. После запуска каждого из контейнеров рекомендую менять hostname, чтобы было удобно их различать.
Запуск 32-битного контейнера на 64-битном хосте
Без доп. параметров всё запустится, но, например, uname и lscpu будут выдавать x86_64, в результате чего утилиты типа rpm будут думать, что они работают на 64-битной Ос, а не 32-битной.
Zynq 7000. Собираем Linux и RootFS при помощи Buildroot
Рекомендуемые источники для более глубокого изучения
Перед началом повествования хотелось бы отдельно отметить источники информации, которые помогли мне при подготовке этого материала:
Книга Криса Симмондса Встраиваемые системы на основе Linux.
Стрим ребят из команды FPGA-Systems.ru по сборке Linux: https://www.youtube.com/watch?v=339hpNuRZDo
Что такое Buildroot и зачем он нужен?
Чтобы решить эту проблему профессионалы придумали нечто такое, что позволило бы автоматизировать всю процедуру сборки, настройки всего необходимого! Звучит заманчиво, не правда ли?
В результате реализации этой идеи на свет появился Buildroot! Это система автоматизированной сборки на основе GNU Make и Kconfig.
Основная идея автоматизированной сборки состоит в том, что эта система должна уметь собрать из полученного исходного кода с репозиториев всё необходимо для работы, набор для кросс-компиляции, всех инструментов, начальный загрузчик, ядро ОС, откомпилированный файл device-tree и корневую файловую систему.
Самое удобное и полезное в этой ситуации то, что всё необходимое собирается из исходного кода. В этом случае у нас есть уверенность, что мы можем пересобрать код в любое время и без лишнего гемороя с внешними зависимостями. Также мы можем быть уверенными в том, что используется самые последние версии программ со всеми патчами и исправлениями.
Общая последовательность шагов которые выполняются при работе с системами сборки мне видится таковой:
Конфигурирование. В этом шаге выполняется настройка всего того, что будет в последствии собрано: от загрузчика до программ которые будут скомпилированы и включены в корневую файловую систему. Самый трудоемкий и объемный шаг, который в последствии облегчается тем, что наработки можно сохранять в файлы конфигурации и детальная настройка нужна только один раз. В дальнейшем можно переиспользовать уже готовую конфигурацию.
Скачивание исходных кодов и сохранение всего того, что было выбрано на этапе конфигурации. Также докачиваются зависимости и всё необходимое для успешной сборки.
Сборка и компиляция исходных кодов. Занимает достаточно много времени, длительность зависит от объема выбранных программ и того, насколько сложную систему вы хотите собрать.
Создание корневой файловой системы и конечная компоновка.
Создание финальных образов с возможностью выбора их форматов, пригодных для загрузки на устройстве.
В дополнение к этому, есть еще ряд плюшек которые предоставляются системой сборки:
Можно добавлять свои программы и пакеты.
Есть возможность выбора различных профилей файловой системы, с оптимизацией по размеру. с поддержкой разных опций влияющих на размер образа.
Очень удобно использовать при создании автономного SDK и распространения его среди других разработчиков.
Возможность создавать обновления, которые можно применить к уже установленным системам.
Наличие удобного интерфейса для взаимодействия с пользователем.
Наверняка, пытливый пользователь может спросить “А ведь есть же PetaLinux который базируется на Yocto. Зачем нужен buildroot?”. И я немного разобравшись в вопросе смело могу заявить, что это абсолютно две разные системы которые подходят к решению задачи сборки довольно таки разных по сложности и преследуют совершенно разные цели.
Возможно когда-нибудь в будущем я попробую разобраться и с Yocto, но точно не в этой статье. Едем дальше…
Переходим от разговоров к делу!
Перейдем к установке
Как обычно все начинается с клонирования репозитория на локальный компьютер. Привожу пример получения последней версии на момент написания статьи:
После клонирования репозиториев необходимо установить все требуемые зависимости:
Конфигурирование
Давайте посмотрим, что находится рабочем каталоге buildroot:
Всё, что будет скомпилировано будет положено в папку output, либо в папку указанную в параметрах компиляции с ключом O= , в которой появятся два основных каталога:
Создадим файл, запуская который у нас будет открываться меню конфигурации:
Запишем в него следующее:
Теперь можно начинать конфигурацию и подготовить конфигурацию, которую после будем использовать для работы с нашей платой.
Первым пунктом заходим в меню Target options и выбираем архитектуру ARM (little endian) и выбираем вариант архитектуры Cortex-A9, что собственно соответствует тому, что мы имеем на плате. Устанавливаем также опции связанные с Hard Floating Point. После проведения правильной конфигурации окно примет следующий вид:
Переходим обратно в главное меню и заходим в меню Build options. Для ускорения процедуры сборки можно поставить опцию Number of jobs to run simultaneously в соответствии с количеством ядер CPU. Остальные опции оставляем по умолчанию.
Переходим к настройке Toolchain.
В нашем случае мы воспользуемся toolchain встроенным в Buildroot. Оставляем без изменений пункт Toolchain type.
Меняем используемую C library на glibc.
В пункте Kernel Headers выбираем Custom Git Repository и в меню URL of custom repository указываем путь, к cклонированному в прошлом занятии, ядру Linux. Либо клонируем репозиторий в папку /home:
После в поле Custom repository version необходимо указать хэш текущего указателя на master-ветку в репозитории:
Смотрим версию ядра, склонированную в репозитории linux-xlnx:
Будет выведено окно настройки конфигурации ядра для последующего компилирования и в заголовке будет указана версия:
Выбираем версию ядра 5.10.х в опции Custom kernel headers series.
Устанавливаем опцию Install glibc utilities.
Выбираем версию компилятора gcc. В моем случае это gcc 9.x. Установим его в поле GCC compiler Version.
Установим поддержку C++ в поле Enable C++ support.
Далее выбираем опции Enable compiler link-time-optimization support.
Ставим поддержку мультипроцессорного режима работы программ с использованием OpenMP в поле Enable compiler OpenMP support.
Настроим параметры ядра для последующей компиляции следующим образом.
Таким же образом указываем Custom Git repository с указанием пути до репозитория и хэша.
Указываем что корневой файл конфигурации будем использовать из in-tree источника: Kernel configuration (Using an in-tree defconfig file).
Файл defconfig указываем тот, что использовали по умолчанию при компиляции ядра в прошлом уроке: записываем в поле Defconfig name xiinx_zynq без постфикса “_defconfig”.
Выбираем опцию Kernel binary format и ставим uImage и тип компрессии gzip
Устанавливаем адрес загрузки Load address в 0x8000.
Остальные опции в этом меню остаются по умолчанию. Выглядит меню настройки следующим образом:
Переходим в меню Target options. В этом меню мы можем выбрать весь набор необходимых программ которые будут включены в состав будущего образа.
Переходим в меню Filesystem images. Выбираем интересующие нас образы, я выбираю только cpio и метод сжатия lzma.
В меню Host Utilites ставим опции:
host dosfstools
host genimage
host mtools
Все настройки завершены, записываем их путем нажатия клавиши F6 сохраняем файл с именем .config.
На этом мы можем считать, что предварительная настройка Linux закончена. Можно запускать компиляцию. Для этого я сделал скрипт br-build и записал в него следующее:
После этого необходимо присвоить ему права на исполнение и запустить:
После окончания компиляции в папке images/ появятся необходимые образы:
После этого можно попробовать загрузить то, что у нас получилось. Копируем на загрузочную microSD файлы uImage и uramdisk.image.gz и файл devicetree.dtb который у нас был сделан в прошлом занятии.
Проверим, что получилось
Запускаем плату и попадаем в меню U-Boot. В этом меню вводим команды:
В целом основная задача выполнена и достигнутое можно считать хорошей заготовкой для дальнейшей кастомизации используемого образа Linux. Можно пробовать добавлять свои скрипты и проводить более углубленное изучение buildroot, например, осуществить сборку Device Tree через buildroot.
Write/rootfs
Содержание
Введение [ править ]
Данная страница посвящена описанию способов установки архивов корневых файловых систем (rootfs) на физические носители (flash-накопители).
Установка rootfs на SD-карту с помощью alt-rootfs-installer [ править ]
Порядок действий для установки на SD-карту:
В списке нужно найти название загрузчика (u-boot), предназначенного для вашего устройства, и указать его в качестве цели (—target= ). Список разбит по производителям SOC и архитектурам (armh, aarch64 и т.д.). Особняком стоят загрузчики для Raspberry Pi. rpi2 предназначен для записи armh rootfs для Raspberry Pi 2 и 3. rpi3 для записи aarch64 rootfs на Raspberry Pi 3.
Примеры создания загрузочных SD-карт [ править ]
Jetson Nano [ править ]
Команда для установки alt-p9-cinnamon-tegra-20190721-aarch64.tar.xz на SD-карту /dev/mmcblk0 с драйверами для Nvidia Jetson Nano будет выглядеть так:
После чего вам будет предложено скачать архив с драйверами:
Вы должны ввести yes и нажать Enter. После чего начнётся загрузка архива. Это может занять продолжительное время. После успешной загрузки архива на ваш компьютер, у вас будет запрошено подтверждение на запись SD-карты с информацией.
Вы также должны написать yes и нажать Enter. По завершении записи должно быть
ЭЛВИС Салют ЭЛ24ПМ2 (mcom02) [ править ]
Для установки на процессорный модуль ЭЛВИС Салют ЭЛ24ПМ2 потребуются специальные сборки с ядром mcom02. В названии rootfs должно присутствовать mcom02. Установка осуществляется командой:
Также можно установить вручную, выполнив следующие команды от root:
Или же можно воспользоваться графической утилитой вроде gparted. На microSD-карте необходимо создать таблицу разделов msdos, один раздел, отформатировать его в файловую систему ext4fs, файловой системе присвоить метку ROOT. После чего примонтировать созданный раздел и распаковать архив rootfs на него.
Raspberry Pi 4 [ править ]
Нужен alt-rootfs-installer версии 0.4.5-alt1 или новее.
Команда для установки alt-education-9.2-rpi4-20210524-aarch64.tar.xz на SD-карту /dev/mmcblk0 с загрузчиком для Raspberri Pi 3 и Raspberry Pi 4 будет выглядеть так:
Raspberry Pi 3 [ править ]
Команда для установки regular-mate-20190228-aarch64.tar.xz на SD-карту /dev/mmcblk0 с загрузчиком для Raspberri Pi 3 будет выглядеть так:
Команда для установки regular-mate-20190228-armh.tar.xz на SD-карту /dev/mmcblk0 с загрузчиком для Raspberri Pi 3 будет выглядеть так:
Raspberry Pi 2 [ править ]
Команда для установки regular-mate-20190228-armh.tar.xz на SD-карту /dev/mmcblk0 с загрузчиком для Raspberri Pi 2 будет выглядеть так:
Orange Pi Prime [ править ]
Команда для установки regular-mate-20190228-aarch64.tar.xz на SD-карту /dev/mmcblk0 с загрузчиком для Orange Pi Prime будет выглядеть так:
Замена загрузчика [ править ]
Одну и ту же micro-SD карту можно легко использовать на другом устройстве, лишь заменив загрузчик (это касается только загрузчиков для одного и того же типа SOC):
Запись дополнительного загрузчика [ править ]
Существует возможность иметь одновременно загрузчик для Raspberry Pi и ещё одного компьютера (только на базе SOC Allwinner), так как Raspberry Pi размещает свой загрузчик на первом разделе с файловой системой FAT.
Для этого необходимо при установке rootfs в качестве target указать rpi2 для armh или rpi3 для aarch64:
После чего установить второй загрузчик:
Создание образа img из архива rootfs [ править ]
Пример: создание образа regular-lxqt-20190213-aarch64.img из архива rootfs regular-lxqt-20190213-aarch64.tar.xz для Raspberry Pi 3:
Будет создан образ с минимальным запасом свободного места достаточного для загрузки, но не полноценной работы. Если планируется создать образ для работы в qemu, то можно явно указать желаемый размер в MiB:
Пример: создание образа regular-lxqt-20190213-aarch64.img из архива rootfs regular-lxqt-20190213-aarch64.tar.xz для Raspberry Pi 3 размером 8000 MiB:
Запись образа img на SD-карту [ править ]
Можно воспользоваться удобной утилитой с графическим интерфейсом rpi-imager[1] (сайт), которая существует под самые распространенные платформы. Ссылка на сообщение в рассылке
В любом Linux можно записать командой:
Пример: запись образа regular-lxqt-20190213-aarch64.img.xz на /dev/mmcblkX для компьютера Orange Pi Prime:
Пример: запись образа slinux-rpi4-9.0-aarch64.img.xz на /dev/sdb для компьютера Raspberry Pi 4:
И наконец, если у вас Windows, то записать, предварительно разархивировав, можно программой HDD Raw Copy Tool.
Расширить корневой раздел на всё свободное место [ править ]
Создание образа Ubuntu для ARM «from scratch»
Когда разработка только начинается часто еще непонятно какие именно пакеты пойдут в целевую rootfs.
Иными словами хвататься за LFS, buildroot или yocto (или еще что-то) еще рано, а начинать уже нужно. Для богатых (у меня на пилотных образцах 4GB eMMC) есть выход раздать разработчикам дистрибутив, который позволит оперативно доставить что-то чего не хватает в данный момент, а затем мы всегда можем собрать списки пакетов и сформировать список для целевой rootfs.
Данная статья не несет в себе новизны и представляет из себя простую copy-paste инструкцию.
Цель статьи сборка Ubuntu rootfs для ARM борды (в моем случае на базе Colibri imx7d).
Сборка образа
Собираем целевой rootfs для тиражирования.
Распаковываем Ubuntu Base
Релиз выбираем сами исходя из необходимости и собственных предпочтений. Здесь я привел 20.
Проверка поддержки BINFMT в ядре
Если у вас распространенный дистрибутив, то поддержка BINFMT_MISC есть и все настроено, если нет — то я уверен, что вы знаете как включить поддержку BINFMT в ядре.
Убедитесь, что BINFMT_MISC включено в ядре:
Теперь надо проверить настройки:
Зарегистрировать вручную можно с помощью, например, вот этой инструкции.
Настройка qemu static arm
Теперь нам понадобится экземпляр qemu собранный статически.
Chroot
Любуемся на полученный результат:
Ради интереса замерим размер до и после установки минимального (для меня) набора пакетов:
Установим интересующие нас пакеты:
Заголовочные файлы ядра, модули, это отдельный разговор. Загрузчик, ядро, модули, device tree через Ubuntu мы конечно же не поставим. Они придут к нам извне или сами соберем или нам их выдаст производитель борды, в любом случае это за гранью данной инструкции.
До какой-то степени расхождение версий допустимо, но лучше взять их со сборки ядра.
Смотрим, что получилось и получилось немало:
Не забудьте задать пароль.
Пакуем образ
Дополнительно можем поставить etckeeper с настройкой autopush
Ну допустим раздали мы нашу сборку, работа пошла, как лучше собрать потом различные версии нашей системы.
На помощь нам может прийти etckeeper.
Настроим autopush
Можем конечно заранее же создать ветки на устройстве (допустим сделать скрипт или службу, которая отработает при первом запуске).
А можем поступить хитрее.
Ленивый путь
Пусть у нас будет какой-то уникальный идентификатор, допустим серийный номер процессора (ну или MAC — серьезные компании покупают диапазон):
Тогда мы можем использовать его для имени ветки в которую будем пушить:
Создадим простой скрипт:
И всё — через некоторое время можем посмотреть изменения и сформировать список пакетов для целевой прошивки.
Бездисковая загрузка по сети и жизнь после нее
История
Теория
По сути, для того, чтобы система загрузилась ей необходимо 3 компонента — ядро, начальное окружение initramfs и корневой каталог, в котором система будет работать.
Практика
Все действия проводятся на машине с ubuntu precise.
Для начала настроим PXE. Мануалов на эту тему уйма, поэтому я расскажу только самую суть.
Ставим ваш любимый dhcp сервер, например isc-dhcp-server, который будет раздавать машинкам ip адреса и указывать путь к файлу pxelinux.0, который будет отдавать tftp сервер (tftp-hpa или же atftp).
Пример конфига dhcp сервера. В примере pxe-сервер находится по адресу 10.0.0.1.
Запускаем tftp сервер (в ubuntu он имеет init-скрипт, но вполне вероятно, что вам придется запускать его и через inetd/xinetd).
Проверяем работоспособность. Кладем файл в каталог /var/lib/tftpboot и пробуем стянуть его tftp клиентом.
В принципе неважно, где вы возьмете файл pxelinux.0, так как он является просто начальным загрузчиком, в который мы передаем то, что надо грузить дальше.
Вы можете сделать красивую менюшку в загрузчике, но сейчас нам это не нужно, поэтому мой pxelinux.cfg/default выглядит так
rootfs
Образ rootfs собираем через debootstrap, чрутимся в него и ставим необходимые программы. Настраиваем сеть, hostname, фаервол и прочее, чем больше сделаем настроек, тем больше будет образ. Главное не забудьте сменить пароль на рута.
С нашим минимальным набором система получилась весом 200Мб.
Initramfs
В этом примере мы будем забирать образ корневой фс с веб-сервера, расположенного на нашем сервере сетевой загрузки, то есть на 10.0.0.1. Решение было таким просто потому, что в нашем initramfs была утилита wget. Чтобы не тянуть большой объем данных по сети, мы решили сжать образ. Это можно было бы сделать и обычным tar, но можно попробовать squashfs, тем более, что обычно в initramfs tar не встроен, с другой стороны, ничего не мешает его туда добавить.
Squashfs
Squashfs — это сжимающая файловая система, которая включена в ядро с версии 2.6.29. С ее помощью можно заархивировать каталог, примонтировать на loop устройство и читать с него, для записи же необходимо провести процедуру добавления файлов в архив. Так как при обращении к squashfs, вы читаете из архива, то это дает дополнительную нагрузку на cpu.
Далее надо научить init из initramfs забирать образ корня и помещать его в оперативную память.
init в initramfs — это скрипт на sh, который производит разбор опций из cmdline, монтирует фс, делает switch_root и запускает гланый init-процесс системы.
Воспользуемся этим и допишем свои опции для cmdline. Напишем скрипт ram, который будет вызываться при значении опции boot=ram.
Через параметр rooturl можно указывать откуда качать образ корневой фс. Для работы со squashfs необходимо подгрузить ее модуль в ядро. Указываем в /etc/initramfs-tools/initramfs.conf BOOT=ram и пересобираем initramfs
Включаем машинку, на которой будем тестировать, и смотрим на происходящее. После успешной загрузки мы получили бездисковую систему, которая занимает в памяти около 300Мб, при этом мы может писать в нее, но после ребута, система вернется в свое первоначальное состояние.
В это примере, мы использовали squashfs просто для сжатия образа, но почему бы нам не попробовать примонтировать корневой раздел в squashfs и не посмотреть, что получится? Меняем наш скрипт, в функции do_rammount() оставляем только монтирование squashfs.
Пересобираем initramfs, запускаем, смотрим. Система загружается в режиме ro, но зато занимает в памяти всего около 180Мб.
В каких-то случаях монтирование в режиме ro это хорошо, но нас это не устраивает, но и просто так тратить оперативную память нам тоже не хочется. Выход же был найден при помощи Aufs.
Aufs
Aufs позволяет делать каскадно-объединённое монтирование файловых систем — одну в режиме только на чтение, а вторую в rw. Работает она в режиме copy-on-write, то есть все изменения записываются на rw систему и после этого чтение производится с нее же.
Опять переписываем наш скрипт.
В фукнцию mountroot() добавляем
А фукнцию do_rammount() приводим к следующему виду:
Пересобираем initramfs, запускаем, смотрим. Система занимает в памяти 181Мб, при этом мы можем менять ее, писать, читать. Все изменения хранятся отдельно в /mnt/rw, а сама система хранится в /mnt/ro.
В результате мы получили систему, которая грузится по сети, занимает небольшой объем в памяти, при этом после каждой перезагрузки пропадают все изменения (поэтому надо заранее собирать все нужные продукты жизнедеятельности системы в надежное место).
Все вышеперечисленные способы имеют право на жизнь. Надеюсь, что эта информация вам пригодится, а мне же будет интересно почитать/послушать ваши комментарии.
Спасибо за внимание.