User Tools

Site Tools


debian:linux-chroot-mini-ubuntu

Construire un mini-ubuntu basé sur debootstrap et busybox

L'utilisation de l'outil debootstrap + busybox pour créer un système aussi petit présente les avantages suivants:

  • Le petit ubuntu généré par debootstrap facilite l'installation d'outils supplémentaires à l'aide d'apt
  • Peut copier directement le module de pilote sur une petite image
  • Les scripts personnalisés sont très simples et faciles

L'ensemble du petit système représente environ 100 M sans installer de logiciel supplémentaire ni de modules de noyau, et peut être ajouté à busybox et réduit à 40-50 M (y compris la bibliothèque de base complète). Après avoir installé python3 (full python3), on peut le réduire à environ 110 M.

Initramfs est un système de fichiers complet d'un système Linux (supprime le noyau, supprime les logiciels inutilisés), puis le développe en mémoire et exécute le programme (/init/sbin/init).

Création du système de base

Debootstrap

Utiliser debootstrap pour générer un système minibase ubuntu contenant l’ensemble du système de fichiers de base et l’outil apt (sans noyau):

sudo debootstrap --variant=minbase trusty mini \
    http://mirrors.aliyun.com/ubuntu/

On peut utiliser n'importe quel autre miroir.

utiliser chroot en liaison avec dpkg pour afficher les logiciels installés:

sudo chroot mini dpkg -l

ou

sudo chroot mini/bin/bash

Afin de permettre son démarrage en tant qu'initramfs du noyau, il faut placer un fichier init dans le répertoire racine, écrire le processus de démarrage dans le fichier init (montage du système de fichiers, exécuter /sbin/init, etc.). Ce qui suit est copié à partir d'une partie de /usr/share/initramfs-tools/init, car elle ne monte pas la partition racine sur le disque dur, ce qui réduit considérablement le code.

cat << EOF | sudo tee mini/init
#!/bin/sh

[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mkdir -p /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc
# Certaines choses ne fonctionnent pas correctement sans /etc/mtab.
ln -sf /proc/mounts /etc/mtab

grep -q '\<quiet\>' /proc/cmdline || echo "Loading, please wait..."

# Cela ne devient /dev que sur le système de fichiers réel si les scripts de udev
# sont utilisés; ce qu'ils seront, mais il est utile de préciser
if ! mount -t devtmpfs -o mode=0755 udev /dev; then
        echo "W: devtmpfs not available, falling back to tmpfs for /dev"
        mount -t tmpfs -o mode=0755 udev /dev
        [ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
        [ -e /dev/null ] || mknod /dev/null c 1 3
fi
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
mount -t tmpfs -o "noexec,nosuid,size=10%,mode=0755" tmpfs /run
mkdir /run/initramfs
# lien symbolique de compatibilité pour les emplacements pre-oneiric
ln -s /run/initramfs /dev/.initramfs

# Set modprobe env
export MODPROBE_OPTIONS="-qb"

# mdadm a besoin que le nom d’hôte soit défini, ceci avant que les règles udev soient appelées!
if [ -f "/etc/hostname" ]; then
        /bin/hostname -b -F /etc/hostname 2>&1 1>/dev/null
fi

exec /sbin/init
EOF

Sudo chmod + x mini/init

Récupération du Noyau

Lorsque GRUB charge le noyau et initramfs, le noyau étend initramfs en mémoire, puis exécute init dans son répertoire racine, qui est le script ci-dessus. Le script ci-dessus effectuera le travail de montage, préparera la structure de répertoires, puis exécutera /sbin/init pour convertir le processus d'initialisation d'ubuntu (system-v init, upstart, systemd, créer automatiquement des fichiers de périphérique avec udev, etc.).

Modifier la configuration de lancement d'ubuntu pour une connexion automatique :

for i in $(find mini/etc/init -type f -name "tty*"); do
    sed -e "s|/sbin/getty -8|/sbin/getty --autologin root -8|" -i $i
done

Le module du noyau et le pilote matériel ne sont pas inclus dans la minibase. Il faut cpier le module à partir du noyau ou de la machine. Par exemple, télécharger une image linux via apt-get et extraire le module du noyau.

sudo apt-get download linux-image-$(uname -r)
sudo rm -rf linux-image-$(uname -r)
sudo dpkg -x $(find . -type f -name "linux-image-$(uname -r)*.deb" | head -n 1) linux-image-$(uname -r)
sudo cp -af linux-image-$(uname -r)/lib mini/

Puis générer les dépendances de modules :

sudo chroot mini depmod

Nettoyer :

sudo chroot mini apt-get clean

Réduction du système

Le petit système généré ci-dessus est fondamentalement disponible, mais pour continuer à réduire la taille nécessaire pour une exécution sur une machine avec moins de mémoire, on peut encore continuer à couper. L'étape la plus importante consiste à utiliser busybox pour gérer la plus grande partie du travail. Busybox comprend même le chargement et l’échange à chaud pilotés par l’appareil

Installation de Busybox

sudo chroot mini apt-get -y --no-install-recommends install \
    busybox-static

Définir les variables apps et extra_apps pour contenir les commandes prises en charge par busybox, et définir les fonctions pour remplacer les commandes d'origine par busybox :

applets=$(mini/bin/busybox --list)
apps=
for i in $applets; do
    apps="$apps $(sudo chroot mini which $i)"
done
extra_apps=
for i in $applets; do
    if ! sudo chroot mini which $i > /dev/null; then
        extra_apps="$extra_apps /bin/$i "
    fi
done

function fix_missing() {
    for i in $apps $extra_apps; do
        if ! test -f mini/$i; then
            sudo ln -sf /bin/busybox mini/$i
        fi
    done
}

Nettoyage

Nettoyer les paquets pouvant être supprimés directement:

sudo chroot mini apt-get -y --force-yes purge adduser busybox-initramfs \
    cpio ifupdown initramfs-tools initscripts initramfs-tools-bin \
    iproute2 locales mountall makedev plymouth procps upstart libprocps3 \
    libcgmanager0 libusb-1.0-0 usbutils libdbus-1-3 libnih-dbus1 libdrm2 \
    libjson-c2 libjson0 kmod libkmod2 module-init-tools file libmagic1 \
    libnih1 libplymouth2 pciutils libudev1 udev
fix_missing

Forcer la suppression des paquets indésirables:

sudo chroot mini /bin/sh -c 'echo "Yes, do as I say!" |\
    apt-get -y --force-yes purge diffutils findutils hostname'
fix_missing

sudo chroot mini /bin/sh -c 'echo "Yes, do as I say!" |\
    apt-get -y --force-yes purge -y --force-yes login libmount1 mount\
        grep gzip sed mount'
fix_missing

sudo chroot mini /bin/sh -c 'echo "Yes, do as I say!" |\
    apt-get -y --force-yes purge -y --force-yes sysvinit-utils lsb-base\
        e2fsprogs e2fslibs bsdutils libblkid1 libuuid1 passwd tzdata insserv'
fix_missing

sudo chroot mini /bin/sh -c 'echo "Yes, do as I say!" |\
    apt-get -y --force-yes purge ncurses-base ncurses-bin'
sudo chroot mini /bin/sh -c 'echo "Yes, do as I say!" |\
    apt-get purge coreutils'
fix_missing

On peut continuer à nettoyer en supprimant des bibliothèques inutiles.

Nettoyer le cache d'apt ::

sudo chroot mini apt-get clean
sudo rm -rf mini/usr/share/locale/*
sudo rm -rf mini/usr/share/man/*
sudo rm -rf mini/usr/share/doc/*
sudo rm -rf mini/var/log/*
sudo rm -rf mini/var/lib/apt/lists/*
sudo rm -rf mini/var/cache/*
sudo rm -rf mini/etc/rc*

Configuration de l'init

Comme udev, system-v init, upstart, etc. ont été supprimés au cours du processus de nettoyage, un nouveau script init prenant en charge busybox est requis. Sous Ubuntu, l’udev original lui-même prend en charge le chargement initial du pilote et du périphérique, mais mdev n’est appellé que lorsqu’il est hotplug il faut inspecter le répertoire /sys/devices pour charger le module de pilote:

cat > mini/init << EOF
#!/bin/sh
mount -t proc -o nodev,noexec,nosuid proc /proc
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
ln -sf /proc/mounts /etc/mtab
mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
[ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
[ -e /dev/null ] || mknod /dev/null c 1 3
mkdir -p /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts
mount -t tmpfs -o "noexec,nosuid,size=10%,mode=0755" tmpfs /run
echo "Loading modules..."
# hotplug with mdev
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s
# coldplug: load devices supporting modules
find /sys/devices -name modalias | xargs -r cat | xargs -r modprobe -qa
# extra modules
[ -f /etc/modules ] && cat /etc/modules | grep -v "^[[:blank:]]#" |\
    xargs -r modprobe -qa
exec /sbin/init
EOF

chmod +x mini/init

Créer des liens sympoblyque pour utiliser l'init de busybox

ln -sf /bin/busybox mini/bin/sh
ln -sf /bin/busybox mini/sbin/init

L'init de busybox nécessite un fichier inittab pour décrire le processus d'initialisation:

cat > mini/etc/inittab << EOF
::sysinit:/etc/init.d/rcS
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
tty1::respawn:/bin/sh
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
EOF

touch mini/etc/init.d/rcS
chmod +x mini/etc/init.d/rcS

Encore une fois, recharger le module du noyau:

sudo apt-get download linux-image-$(uname -r)
sudo rm -rf linux-image-$(uname -r)
sudo dpkg -x $(find . -type f -name "linux-image-$(uname -r)*.deb" | head -n 1) linux-image-$(uname -r)
sudo cp -af linux-image-$(uname -r)/lib mini/
sudo chroot mini depmod

A la fin de cette étape, la taille du répertoire est d'environ 80 M (y compris le module du noyau), mais vous peut faire mieux.

Réduction en profondeur

Utiliser du -hs * mini pour voir tout le répertoire. On peut voir que l’espace le plus occupé est le répertoire des modules du noyau, qui représente près de la moitié de l’espace.

Ce qui suit est l'empreinte du module du noyau (mini/lib/modules/4.4.0-31-generic) ::

2.6M    arch
1.4M    crypto
11M     drivers
8.1M    fs
1.8M    lib
12M     net
832K    sound
508K    ubuntu
20K     virt

Net inclut ceph, netfilter, openvswitch, atm, x2, appletalk, etc., peuvent être supprimés.

Importanat: revérifier les dépendances après la suppression:

Chroot mini depmod

Le répertoire mini/usr/lib est également très volumineux: certaines bibliothèques peuvent être supprimées, par exemple, il existe de nombreuses bibliothèques de code dans mini/usr/lib/x86_64-linux-gnu/gconv. Libdb-5.3.so est également très volumineux, peut être supprimé sans utiliser man, etc.

À ce stade, on ne peut pas utiliser apt-get pour supprimer des éléments, utiliser au maximum dpkg, et le forcer à le nettoyer. Il n’y a pas de problèmes techniques à ce stade, et avec suffisamment de soin et de patience, on peut obtenir un système suffisamment petit.

Il existe d'autres moyens de personnaliser linux, tels que LFS http://linuxfromscratch.org/, buildroot https://buildroot.org/ et ainsi de suite.

Pour sauvegarder ce petit Linux sur le disque dur, c'est aussi très simple. Copier l'intégralité de la mini-copie sur une partition séparée, charger la partition où se trouve le répertoire racine, puis basculer vers /sbin/init dans le script init via switch_root:

# Une fois le module chargé ...
Monter/dev/sda3/mnt
Mkdir -p/mnt/mnt
Exec switch_root/mnt/sbin/init

Een raison de la commutation de la partition racine, des répertoires tels que /proc /sys /dev /tmp nécessitent un traitement supplémentaire: mount -o move to mnt ou définir des points de montage dans le fichier mini/fstab .

Etapes finales

Empaqueter et copier dans le répertoire de démarrage

(cd mini; sudo find . | sudo cpio -o -H newc | sudo gzip -9 > ../initramfs-mini.gz)
sudo cp -f initramfs-mini.gz /boot

Redémarrer, appuyer sur c dans le répertoire grub pour entrer cmdline:

linux /vmlinux-<xxxxx>
initrd /initramfs-mini.gz
boot

Démarrage

Redémarrer l'ordinateur, appuyer sur c dans l'écran d'ammorce grub pour entrer dans cmdline et utiliser la commande suivante pour démarrer (compléter avec tab):

Linux/vmlinux- <xxxxx>
Initrd /initramfs-mini.gz

Après l’amorçage, le noyau extraira initramfs-mini.gz et entrera rapidement à l’invite de commande ubuntu. Ce Linux de base peut exécuter des opérations courantes, à l'exception d'outils tels que ping (qui peuvent être installés via apt-get), qui sont exécutés directement en mémoire, ce qui est identique à l'habitude (tous les fichiers étant chargés en mémoire, ). La vitesse de la commande devrait être un peu plus rapide).

debian/linux-chroot-mini-ubuntu.txt · Last modified: 2025/02/19 10:59 by 127.0.0.1