Содержание
Установка ОС с собственного загрузочного носителя
Собственный загрузочный носитель - это ISO-образ, который можно записать на CD/USB/HDD, загрузить с них устройство и запустить процедуру установки.
ISO-образ должен содержать:
- специальный вариант операционной системы, который способен загрузить устройство и обеспечить работоспособность процедуры установки
- локальный репозиторий или возможность сетевого доступа к необходимым для установки пакетам (netinstall)
Операционная система (vmlinuz, initrd)
Операционная система состоит из ядра (vmlinuz) и архива с файлами корневого раздела (initrd)
В качестве сборочной платформы для получения этих файлов подойдет устройство с минимальным образом и установленными дополнительными пакетами:
apt install debootstrap cpio zstd
Сборка выполняется в пустом временном каталоге из-под пользователя root, например в /tmp/media
:
rm -rfv /tmp/media; mkdir -pvm 0777 /tmp/media; cd /tmp/media pwd
vmlinuz
Указать расположение главного репозитория (версия ОС в котором может отличаться от сборочной платформы):
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 (подготовка)
Распаковать 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
После загрузки ядра операционной системы первым запускаемым модулем, как правило, является /init
Минимальный пример, инициализирующий систему и стартующий командную оболочку (bash):
- init
#!/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 (упаковка)
Упаковать содержимое подкаталога с файлами операционной системы и получить результирующий 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-образа
Подготовить структуру подкаталогов содержимого 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
Использование 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