Собственный загрузочный носитель - это ISO-образ, который можно записать на CD/USB/HDD, загрузить с них устройство и запустить процедуру установки.
ISO-образ должен содержать:
Операционная система состоит из ядра (vmlinuz) и архива с файлами корневого раздела (initrd)
В качестве сборочной платформы для получения этих файлов подойдет устройство с минимальным образом и установленными дополнительными пакетами:
apt install debootstrap cpio zstd
Сборка выполняется в пустом временном каталоге из-под пользователя root, например в /tmp/media
:
rm -rfv /tmp/media; mkdir -pvm 0777 /tmp/media; cd /tmp/media pwd
Указать расположение главного репозитория (версия ОС в котором может отличаться от сборочной платформы):
REPOMAIN="https://download.astralinux.ru/astra/stable/1.8_x86-64/repository-main/"
Выбрать необходимые пакеты, например:
PACKAGES="chrony,console-setup,debootstrap,fdisk,isc-dhcp-client,linux-latest-generic,openssh-server"
Собрать систему в подкаталоге (например, в ./os
) и перейти в него:
rm -rfv os debootstrap --variant=minbase --include $PACKAGES $(basename $(echo $REPOMAIN | sed 's/x86-64.*$/x86-64/')) os $REPOMAIN cd os
«Забрать» файл ядра системы (vmlinuz):
cp -fv boot/vmlinuz* ../vmlinuz chmod -v 0644 ../vmlinuz
Распаковать initrd, созданный debootstrap. Его содержимое пригодится в дальнейшем:
zcat boot/initrd.img* | cpio -idmv --no-absolute-filenames --directory=boot --unconditional
Обеспечить поддержку русского языка (консоль и файловая система FAT):
rm -rfv etc/console-setup/* mv -fv usr/share/consolefonts/CyrSlav-Fixed16.psf.gz etc/console-setup/ cat > etc/default/console-setup << EOF CHARMAP="UTF-8" CODESET="CyrSlav" FONTFACE="Fixed" FONTSIZE="8x16" EOF find usr/lib/modules/*/kernel/fs/nls/*1251* -exec mv -fv {} boot/{} \;
Удалить из образа все «ненужное» (трюк):
find . -mindepth 1 -maxdepth 1 -type d \ ! -name 'boot' \ ! -name 'etc' \ ! -name 'usr' \ -exec rm -rfv {} \; find etc -mindepth 1 -maxdepth 1 -type d \ ! -name 'alternatives' \ ! -name 'astra' \ ! -name 'chrony' \ ! -name 'console-setup' \ ! -name 'default' \ ! -name 'dhcp' \ ! -name 'ld.so.conf.d' \ ! -name 'modprobe.d' \ ! -name 'pam.d' \ ! -name 'security' \ ! -name 'ssh' \ ! -name 'udev' \ -exec rm -rfv {} \; find usr -mindepth 1 -maxdepth 1 \ ! -name 'bin' \ ! -name 'lib' \ ! -name 'lib64' \ ! -name 'sbin' \ ! -name 'share' \ -exec rm -rfv {} \; find usr/lib -mindepth 1 -maxdepth 1 -type d \ ! -name 'console-setup' \ ! -name 'init' \ ! -name 'lsb' \ ! -name 'modprobe.d' \ ! -name 'openssh' \ ! -name 'systemd' \ ! -name 'terminfo' \ ! -name 'udev' \ ! -name 'x86_64-linux-gnu' \ -exec rm -rfv {} \; find usr/lib/systemd -mindepth 1 -maxdepth 1 -type d \ ! -name 'network' \ -exec rm -rfv {} \; find usr/lib/x86_64-linux-gnu -mindepth 1 -maxdepth 1 -type d \ ! -name 'security' \ -exec rm -rfv {} \; find usr/share -mindepth 1 -maxdepth 1 \ ! -name 'debootstrap' \ -exec rm -rfv {} \;
Воспользоваться содержимым распакованного ранее initrd и получить минимальный набор модулей/драйверов:
mv -fv boot/usr/lib/modules usr/lib/
Удалить /boot
и «поломанные ссылки»:
rm -rfv boot find . -xtype l -delete
Указать имя хоста и создать скрипты перезагрузки и выключения:
echo "localhost" > etc/hostname echo "echo 1 > /proc/sys/kernel/sysrq" > usr/bin/reboot echo "echo b > /proc/sysrq-trigger" >> usr/bin/reboot echo "echo 1 > /proc/sys/kernel/sysrq" > usr/bin/poweroff echo "echo o > /proc/sysrq-trigger" >> usr/bin/poweroff chmod a+x -v usr/bin/reboot usr/bin/poweroff
Выйти из подкаталога с файлами операционной системы:
cd ..
В результате текущий каталог /tmp/media
будет содержать:
/tmp/media/os/* - подкаталог с файлами операционной системы (которые нужно будет упаковать в архив "initrd") /tmp/media/vmlinuz - ядро Linux
После загрузки ядра операционной системы первым запускаемым модулем, как правило, является /init
Минимальный пример, инициализирующий систему и стартующий командную оболочку (bash):
#!/bin/bash # # Disabling console flood # dmesg --console-off # # Creating VFS # mkdir -p /dev /proc /run /sys /tmp /var/lib/dhcp /var/lock mount -t devtmpfs udev /dev mount -t proc proc /proc mount -t tmpfs tmpfs /run mount -t sysfs sysfs /sys ln -sfn /proc/self/fd /dev/fd ln -sfn /proc/self/fd/0 /dev/stdin ln -sfn /proc/self/fd/1 /dev/stdout ln -sfn /proc/self/fd/2 /dev/stderr mkdir /dev/pts mount -t devpts devpts /dev/pts /lib/systemd/systemd-udevd --daemon --resolve-names=never udevadm trigger --action=add udevadm settle depmod # # Enabling Russian language support # setupcon # # Shell script execution # /usr/bin/bash # # Reboot # read -t 5 -p "Перезагрузка..." reboot
Разместить этот скрипт в корне подкаталога с файлами будущего initrd и установить ему атрибут «исполняемый/executable»:
chmod a+x -v /tmp/media/os/init
Упаковать содержимое подкаталога с файлами операционной системы и получить результирующий initrd:
cd /tmp/media/os find . | cpio -o -H newc -v | zstd -19 > ../initrd cd ..
В итоге:
# du -h /tmp/media/{vmlinuz,initrd} 15M /tmp/media/vmlinuz 60M /tmp/media/initrd
Проверить «работоспособность» этих файлов, загрузив с них виртуальную машину (через прямую загрузку ядра)
Если носитель предполагается использовать для инсталляции минимальной версии ОС, то достаточно сформировать репозиторий из установленных пакетов.
Загрузить все пакеты текущей (минимальной) системы:
cd /tmp/media for p in $(apt list --installed | cut -d / -f 1 -s); do apt download $p; done
В /tmp/media/repo
создать репозиторий и наполнить его загруженными пакетами:
apt install reprepro mkdir -pv repo/conf cat > repo/conf/distributions << EOF Origin: Debian Codename: 1.8_x86-64 Suite: stable Version: 1.8 Architectures: amd64 Components: main non-free EOF reprepro -b repo export reprepro -b repo includedeb 1.8_x86-64 ./*.deb rm -rfv *.deb repo/{conf,db}
Подготовить структуру подкаталогов содержимого ISO-образа и сформировать гибридные загрузочные конфигурации:
cd /tmp/media mkdir -pv iso/EFI/BOOT cat > iso/EFI/BOOT/grub.cfg << EOF set timeout=0 menuentry "setup" { linux /isolinux/vmlinuz initrd /isolinux/initrd } EOF mkdir -pv iso/isolinux cat > iso/isolinux/isolinux.cfg << EOF DEFAULT setup LABEL setup KERNEL /isolinux/vmlinuz APPEND initrd=/isolinux/initrd EOF mv -fv vmlinuz initrd iso/isolinux/
Добыть некоторые SYSLINUX-файлы (потребуется расширенный репозиторий):
apt download grub-efi-amd64-bin isolinux syslinux-common for p in *.deb; do dpkg -x $p .; rm -fv $p; done for f in grubx64.efi isohdpfx.bin isolinux.bin ldlinux.c32; do find usr -name $f -exec mv -fv {} iso/isolinux \;; done rm -rfv usr
Сформировать ESP-раздел:
apt install dosfstools dd if=/dev/zero of=iso/isolinux/esp.img bs=5M count=1 mkfs.fat -F 12 iso/isolinux/esp.img mount -v iso/isolinux/esp.img /mnt mkdir -pv /mnt/EFI/BOOT mv -fv iso/isolinux/grubx64.efi /mnt/EFI/BOOT/BOOTX64.EFI umount -Rv /mnt
При необходимости, переместить созданный ранее репозиторий в подкаталог ISO-образа:
mv -fv repo iso
И, наконец, получить итоговый /tmp/media/setup.iso
:
apt install xorriso mv -fv iso/isolinux/isohdpfx.bin . xorriso \ -as mkisofs \ -V "Setup CD/DVD/USB" \ -o ./setup.iso \ -isohybrid-mbr ./isohdpfx.bin \ -c isolinux/boot.cat \ -b isolinux/isolinux.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -eltorito-alt-boot \ -e isolinux/esp.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ iso
# du -h /tmp/media/setup.iso 256M /tmp/media/setup.iso
Запись на USB-накопитель:
lsblk umount /dev/... dd if=setup.iso of=/dev/... sync
Настройка сети после загрузки:
# автоматически (DHCP) dhclient -1 -v -w # вручную ls /sys/class/net ip a add ...
Запуск SSH-сервера:
passwd echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/99-PermitRootLogin.conf mkdir -pv /run/sshd sed -i '/parsec/d' /etc/pam.d/sshd /sbin/sshd
Доступ к репозиторию на носителе, а не в сети (для debootstrap):
mkdir -pv /setup lsblk mount /dev/... /setup A=file:///setup/repo