embedded-deck
TEKNİK REHBER GÖMÜLÜ LİNUX BUSYBOX 2026

BusyBox
Tek binary, yüzlerce araç.

GNU araçlarını tek bir statik binary'ye sıkıştırın — 2 MB'ın altında tam işlevsel bir Linux rootfs, sıfırdan init'ten network daemon'lara kadar eksiksiz.

00 BusyBox nedir?

BusyBox, "The Swiss Army Knife of Embedded Linux" olarak tanımlanır. GNU coreutils, util-linux, procps ve birçok ağ aracının yerini tek bir küçük binary olarak alır. Gömülü sistemlerde depolama ve RAM kısıtlamalarını aşmak için vazgeçilmez bir araçtır.

Applet kavramı

BusyBox tek bir binary'dir (/bin/busybox). Bu binary'ye farklı isimlerle sembolik link oluşturulduğunda, çağrıldığı isme göre farklı bir araç gibi davranır. argv[0]'a bakarak hangi applet'in çalıştırılacağını belirler.

  /bin/busybox
      │
      ├── /bin/sh     → symlink → busybox (ash shell)
      ├── /bin/ls     → symlink → busybox (ls applet)
      ├── /bin/mount  → symlink → busybox (mount applet)
      ├── /sbin/init  → symlink → busybox (init applet)
      ├── /sbin/mdev  → symlink → busybox (mdev applet)
      └── /usr/sbin/httpd → symlink → busybox (httpd applet)

  Çalışma: argv[0] = "ls" → ls applet çalışır
           argv[0] = "busybox" → busybox ls / applet listesi
    

Boyut optimizasyonu

KonfigürasyonBinary boyutuApplet sayısıNot
Tam (tüm applet'ler)~1.2 MB (stripped)400+glibc dinamik
Tam, static musl~900 KB400+musl-libc, no shared libs
Minimal (seçili)~300-400 KB50-80sadece gerekli applet'ler
UPX sıkıştırmalı~200 KB50-80yavaş başlatma tradeoff
Buildroot defconfig~500 KB~200musl + LTO optimizasyon
NOT

BusyBox, LGPL lisanslıdır. Ticari gömülü ürünlerde kaynak kodu veya yapı konfigürasyonu uyumluluğu için lisans koşullarını dikkatle inceleyin. Alternatif olarak BSD lisanslı ToyBox projesi benzer işlevsellik sunar.

01 Derleme: menuconfig ve cross-compile

BusyBox derlemesi Linux kernel'e benzer bir yapılandırma sistemi kullanır. make menuconfig ile hangi applet'lerin dahil edileceği seçilir, ardından cross-compile ile hedef mimari için derlenir.

Kaynak indirme ve defconfig

wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1

# ARM64 cross-compile için ortam değişkenleri
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

# Varsayılan tam konfigürasyon
make defconfig

# Minimal konfigürasyon başlangıç noktası
make allnoconfig   # hiçbir şey seçili değil, sıfırdan başla

# Grafik konfigürasyon arayüzü
make menuconfig

Kritik menuconfig seçenekleri

Settings → Build static binaryCONFIG_STATIC=y — paylaşımlı kütüphane gerekmez, rootfs'e libc kopyalamak zorunda kalmazsınız
Settings → Build with muslCROSS_COMPILE ile musl toolchain belirtin — glibc'ye göre %30-50 küçük binary
Settings → Strip binariesCONFIG_STRIP=y — debug sembollerini at, boyutu önemli ölçüde küçültür
Settings → LTO (Link Time Optimization)CONFIG_LTO=y — GCC'nin tüm derleme birimi optimizasyonu, %10-20 boyut kazancı
Settings → vi-style line editingash shell'de vi keybinding desteği — kullanılmıyorsa kapayın

ARM64 static musl derleme

# musl cross toolchain:
# https://musl.cc/ adresinden aarch64-linux-musl-cross indirilir
export PATH="$HOME/toolchains/aarch64-linux-musl-cross/bin:$PATH"
export CROSS_COMPILE=aarch64-linux-musl-
export ARCH=arm64

# .config'de static'i aktifleştir
cat >> .config << 'EOF'
CONFIG_STATIC=y
CONFIG_STATIC_LIBGCC=y
EOF

make oldconfig
make -j$(nproc)
make install  # _install/ altına sembolik linklerle kurar

# Boyut kontrolü
ls -lh busybox
file busybox   # ELF 64-bit, statically linked

# strip ile ek küçültme
aarch64-linux-musl-strip --strip-all busybox

UPX ile sıkıştırma

# UPX kurulum:
sudo apt install upx-ucl

# Sıkıştır (--best en yüksek sıkıştırma, yavaş başlatma):
upx --best busybox -o busybox.upx

# Boyut karşılaştırması:
ls -lh busybox busybox.upx
# busybox:     900K
# busybox.upx: 340K

# UPX'li binary şeffaf çalışır — symlink'ler normal çalışır
# Dikkat: Flash'ta depolanan sistemlerde runtime decompression için
# RAM gerektirir — küçük RAM'li sistemlerde dikkatli olun

02 Applet kategorileri

BusyBox applet'leri işlevsel gruplara ayrılmıştır. Minimum rootfs için hangi kategorilerin zorunlu olduğunu bilmek, boyut optimizasyonunda kritik öneme sahiptir.

KategoriÖrneklerZorunluluk
coreutilsls, cp, mv, rm, mkdir, chmod, chown, cat, echo, printfTemel sistem işlemleri için zorunlu
util-linuxmount, umount, fdisk, blkid, swapon, lsblk, dmesgDepolama yönetimi için gerekli
Shellash, hush, shash önerilir — POSIX sh uyumlu, küçük
initinit, halt, reboot, poweroffBusyBox init kullanılıyorsa zorunlu
procpsps, top, free, kill, killall, pidofSüreç yönetimi
Networkingifconfig, ip, ping, wget, nc, nslookupAğ bağlantısı için
DHCPudhcpc, udhcpdIP alımı için udhcpc
Editorsvi, nano (minimal)Bakım için önerilir
mdevmdevStatik /dev yerine dinamik device node yönetimi
klogd/syslogdklogd, syslogdLog yönetimi
gzip/targzip, gunzip, tar, xzArşiv işlemleri
find/grepfind, grep, awk, sedScript'ler için gerekli

03 BusyBox init sistemi

BusyBox init, SysV init'e benzer ama çok daha basit bir init sistemidir. /etc/inittab dosyasından çalıştırılacak süreçleri okur. systemd veya OpenRC'nin aksine son derece küçüktür.

/etc/inittab sözdizimi

# /etc/inittab format:
# id:runlevel:action:process

# Önyükleme: bir kez çalıştır
::sysinit:/etc/init.d/rcS

# Konsol getty — bağlantı kesilince yeniden başlat
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2

# Kullanıcıya Enter'a basmasını sor (geliştirme için):
ttyS0::askfirst:/bin/sh

# Kapatma sinyali gelince
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

Action türleri

sysinitSistem başlangıcında bir kez çalıştır — ilk çalıştırılan, bloklar (tamamlanmasını bekler)
waitBelirtilen runlevel'a girildiğinde bir kez çalıştır, tamamlanmasını bekle
onceBir kez çalıştır, tamamlanmasını bekleme
respawnSüreç ölürse yeniden başlat — getty ve kritik daemon'lar için
askfirstEnter'a basmayı bekle, sonra başlat — geliştirme konsolu için
shutdownKapatma sinyalinde çalıştır
ctrlaltdelCtrl+Alt+Delete basıldığında çalıştır

/etc/init.d/rcS — sysinit scripti

#!/bin/sh
# /etc/init.d/rcS — sistem başlangıç scripti

# Temel dosya sistemlerini mount et
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null || \
    mdev -s  # devtmpfs yoksa mdev ile doldur

mkdir -p /dev/pts
mount -t devpts devpts /dev/pts

# Geçici dosya sistemi
mount -t tmpfs tmpfs /tmp -o size=64m
mount -t tmpfs tmpfs /run -o size=32m

# Saat sınıfını yükle (RTC varsa)
hwclock -s 2>/dev/null

# Hostname ayarla
echo "embedded-device" > /proc/sys/kernel/hostname

# Syslog başlat
syslogd -n -O /var/log/messages &
klogd -n &

# Ağ başlat
ifconfig lo up
ip link set eth0 up
udhcpc -i eth0 -s /etc/udhcpc/default.script -b

echo "Sistem hazır."

04 mdev — udev alternatifi

mdev, BusyBox'ın minimal udev implementasyonudur. Hotplug olaylarına yanıt verir, device node'ları oluşturur ve firmware yükleme yapabilir. udev'in 10MB+ bağımlılığının aksine mdev BusyBox binary'sinin içindedir.

mdev kurulumu

# /etc/init.d/rcS içinde:
echo /sbin/mdev > /proc/sys/kernel/hotplug

# /dev dizinini doldur (başlangıçta statik device'lar için)
mdev -s

# devtmpfs kullanılıyorsa (önerilir):
mount -t devtmpfs devtmpfs /dev
# mdev sadece hotplug için yeterli

/etc/mdev.conf sözdizimi

# /etc/mdev.conf
# Format: regex owner:group permissions [command]

# Tüm cihazları root:root 660 yap (varsayılan)
.* root:root 660

# Block cihazlar
sd[a-z][0-9]?  root:disk 660
mmcblk[0-9]p[0-9] root:disk 660
nvme[0-9]n[0-9]p[0-9] root:disk 660

# Seri port
ttyS[0-9]*  root:dialout 660
ttyUSB[0-9]* root:dialout 660

# Video
video[0-9]* root:video 660

# Input cihazları
mice     root:input 640
mouse[0-9] root:input 640
event[0-9]* root:input 640

# USB cihaz ekleme/çıkarma olayı:
# $MDEV = cihaz adı, $ACTION = add/remove
usb.* root:root 660 *:if [ "$ACTION" = "add" ]; then \
    logger "USB eklendi: $MDEV"; fi

# Firmware yükleme — kernel firmware_class mekanizması
firmware/.* root:root 640 *:/sbin/load_firmware.sh $MDEV

Firmware yükleme scripti

#!/bin/sh
# /sbin/load_firmware.sh — mdev firmware helper

FIRMWARE_DIR="/lib/firmware"
FIRMWARE="$FIRMWARE_DIR/$FIRMWARE"
LOADING="/sys$DEVPATH/loading"
DATA="/sys$DEVPATH/data"

if [ -e "$FIRMWARE" ]; then
    echo 1 > "$LOADING"
    cat "$FIRMWARE" > "$DATA"
    echo 0 > "$LOADING"
    logger "Firmware yüklendi: $FIRMWARE"
else
    echo -1 > "$LOADING"
    logger "Firmware bulunamadı: $FIRMWARE"
fi
NOT

mdev, udev'e göre önemli eksikliklere sahiptir: udev rule parser kadar gelişmiş değildir, D-Bus ile entegrasyonu yoktur ve karmaşık device sıralama kurallarını desteklemez. Basit gömülü sistemler için mdev yeterlidir; Android gibi karmaşık sistemler kendi device manager'larını (ueventd) kullanır.

05 initramfs + BusyBox rootfs

initramfs (initial RAM filesystem), kernel başlangıcında belleğe yüklenen geçici kök dosya sistemidir. BusyBox initramfs, gerçek rootfs mount edilene kadar temel sistemi sağlar veya kendisi kalıcı rootfs olarak kullanılır.

initramfs ile gerçek rootfs arası fark

pivot_rootEski root'u başka noktaya taşır, yeni root'a geçer — initramfs'ten gerçek rootfs'e tam geçiş
switch_rootinitramfs'i RAM'den tamamen siler, yeni rootfs'e geçer — RAM tasarrufu için tercih edilir

Minimal initramfs dizin yapısı

mkdir -p initramfs/{bin,sbin,usr/{bin,sbin},lib,lib64,etc,proc,sys,dev,tmp,mnt,run,var/log}

# BusyBox'ı kopyala ve sembolik linkleri oluştur
cp busybox initramfs/bin/busybox
chmod +x initramfs/bin/busybox

# Sembolik linkleri oluştur (_install dizininden kopyala)
cd busybox-1.36.1
make install INSTALL_PATH=$(pwd)/../initramfs
cd ..

# Gerekli konfigürasyon dosyaları
cat > initramfs/etc/passwd << 'EOF'
root:x:0:0:root:/root:/bin/sh
EOF

cat > initramfs/etc/group << 'EOF'
root:x:0:
EOF

cat > initramfs/etc/inittab << 'EOF'
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty -L ttyS0 115200 vt100
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
EOF

mkdir -p initramfs/etc/init.d
cat > initramfs/etc/init.d/rcS << 'EOF'
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null || mdev -s
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mount -t tmpfs tmpfs /tmp -o size=32m
echo "BusyBox initramfs hazır"
EOF
chmod +x initramfs/etc/init.d/rcS

# cpio arşivi oluştur
cd initramfs
find . | cpio -o -H newc | gzip -9 > ../initramfs.cpio.gz
cd ..
ls -lh initramfs.cpio.gz

switch_root ile gerçek rootfs'e geçiş

#!/bin/sh
# /init — initramfs ana init scripti, gerçek rootfs'e geçiş yapar

mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev

# Kernel command line'dan root cihazını al
ROOT=$(cat /proc/cmdline | tr ' ' '\n' | grep '^root=' | cut -d= -f2)

# udev/mdev ile cihazın hazır olmasını bekle
mdev -s

# Root cihazını mount et
mkdir -p /mnt/root
mount "$ROOT" /mnt/root

# initramfs'i temizle ve gerçek rootfs'e geç
# switch_root: initramfs belleğini serbest bırakır
exec switch_root /mnt/root /sbin/init

06 Buildroot entegrasyonu

Buildroot, BusyBox'ı birinci sınıf paket olarak destekler. BusyBox konfigürasyonu Buildroot'un menuconfig'i üzerinden yönetilir ve özelleştirme dosyası overlay mekanizmasıyla uygulanır.

Buildroot BusyBox konfigürasyonu

# Buildroot menuconfig:
# System configuration → Init system → BusyBox
# System configuration → /dev management → Dynamic using devtmpfs + mdev

# BR2_PACKAGE_BUSYBOX: otomatik seçili
# BR2_PACKAGE_BUSYBOX_CONFIG: özel .config dosyası yolu

# BusyBox'a özgü konfigürasyon için:
make busybox-menuconfig
# Bu komut BusyBox'ın kendi menuconfig'ini açar
# Değişiklikler output/build/busybox-VERSION/.config'e yazılır

# Konfigürasyonu kaydet (proje içinde versiyonlanabilir):
make busybox-update-config
# board/myboard/busybox.config olarak kaydedilir

BR2_ROOTFS_OVERLAY ile özelleştirme

# buildroot/conf/local.conf veya make menuconfig:
# System configuration → Root filesystem overlay directories
# BR2_ROOTFS_OVERLAY = "board/myboard/rootfs_overlay"

# Dizin yapısı:
board/myboard/rootfs_overlay/
├── etc/
│   ├── inittab               # BusyBox inittab
│   ├── passwd                # Özel kullanıcılar
│   ├── network/
│   │   └── interfaces        # Ağ konfigürasyonu
│   └── init.d/
│       ├── S10syslog         # Syslog başlatma
│       ├── S20network        # Ağ başlatma
│       └── S99myapp          # Uygulama başlatma
├── usr/
│   └── bin/
│       └── myapp             # Özel binary
└── lib/
    └── firmware/             # Aygıt yazılımı dosyaları

Buildroot BusyBox build

cd buildroot

# ARM platformu için (örn. Cortex-A9):
make qemu_arm_vexpress_defconfig
make menuconfig
# Target → ARM Cortex-A9
# Toolchain → musl
# System → Init: BusyBox

make -j$(nproc) 2>&1 | tee build.log

# Çıktılar:
# output/images/rootfs.ext2     — ext2 rootfs imajı
# output/images/rootfs.cpio.gz  — cpio initramfs
# output/images/zImage          — kernel
# output/images/vexpress-v2p-ca9.dtb — DTB

07 BusyBox networking

BusyBox, tam teşekküllü ağ araçları ve daemon'ları barındırır. udhcpc DHCP istemcisinden httpd web sunucusuna kadar gömülü ağ uygulamaları için eksiksiz bir set sunar.

Temel ağ araçları

# Ağ arayüzü yapılandırma
ifconfig eth0 192.168.1.100 netmask 255.255.255.0
ifconfig eth0 up
ip addr add 192.168.1.100/24 dev eth0
ip route add default via 192.168.1.1

# DNS
echo "nameserver 8.8.8.8" > /etc/resolv.conf

# Bağlantı testi
ping -c 4 192.168.1.1
ping6 -c 4 fe80::1%eth0

# Port tarama / bağlantı testi (nc = netcat)
nc -vz 192.168.1.1 80      # TCP bağlantı testi
nc -l -p 8080              # Dinleyici başlat
echo "GET / HTTP/1.0" | nc example.com 80  # HTTP isteği

udhcpc DHCP istemcisi

# Basit kullanım:
udhcpc -i eth0

# Script ile (tam konfigürasyon):
udhcpc -i eth0 -s /etc/udhcpc/default.script -b -p /run/udhcpc.pid
#!/bin/sh
# /etc/udhcpc/default.script — udhcpc lease callback

case "$1" in
  deconfig)
    ip addr flush dev $interface
    ip route flush dev $interface
    ;;
  bound|renew)
    ip addr add $ip/$mask dev $interface
    ip route add default via $router dev $interface
    # DNS ayarla
    echo "" > /etc/resolv.conf
    for dns in $dns; do
        echo "nameserver $dns" >> /etc/resolv.conf
    done
    echo "DHCP lease alındı: $ip/$mask gw=$router"
    ;;
  leasefail|nak)
    echo "DHCP başarısız — statik IP dene"
    ip addr add 169.254.1.1/16 dev $interface   # link-local fallback
    ;;
esac

BusyBox httpd web sunucusu

# /www/index.html hazırla
mkdir -p /www
cat > /www/index.html << 'EOF'
<html><body>
<h1>Gömülü Cihaz</h1>
<p>Uptime: <b>$(uptime)</b></p>
</body></html>
EOF

# httpd başlat (port 80, /www dizininden sun):
httpd -p 80 -h /www

# CGI desteği:
mkdir -p /www/cgi-bin
cat > /www/cgi-bin/status.sh << 'EOF'
#!/bin/sh
echo "Content-Type: text/plain"
echo ""
echo "=== CPU ==="
cat /proc/cpuinfo | grep "model name" | head -1
echo "=== Bellek ==="
free -m
echo "=== Disk ==="
df -h
EOF
chmod +x /www/cgi-bin/status.sh

udhcpd DHCP sunucusu

# /etc/udhcpd.conf
start      192.168.2.100
end        192.168.2.200
interface  eth0
max_leases 100
opt subnet 255.255.255.0
opt router 192.168.2.1
opt dns    8.8.8.8 8.8.4.4
opt lease  86400

# Başlatma:
udhcpd /etc/udhcpd.conf

08 Pratik: 2MB minimal rootfs

Bu bölümde BusyBox static binary + Linux kernel + initramfs kombinasyonuyla QEMU'da çalışan ~2MB'lık bir gömülü Linux sistemi oluşturacağız.

Boyut hedefleri

BileşenHedef boyutTeknik
BusyBox (ARM64 musl static)~400 KBstrip + LTO, minimal applet seçimi
Konfigürasyon dosyaları (/etc)~10 KBsadece zorunlular
Dizin yapısı~0 KBsembolik linkler yer kaplamaz
initramfs.cpio.gz (sıkıştırılmış)~500 KBgzip -9
Linux kernel (ARM64, minimal)~1.5 MBtinyconfig + gerekli sürücüler
Toplam~2 MB

Adım adım minimal sistem

#!/bin/bash
# build_minimal.sh — 2MB gömülü Linux sistemi

set -e
WORK=$(pwd)/minimal_system
CROSS=aarch64-linux-musl-

mkdir -p $WORK && cd $WORK

# ─── 1. BusyBox ───────────────────────────────────────
wget -q https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1

make CROSS_COMPILE=$CROSS ARCH=arm64 defconfig

# Zorunlu optimizasyonlar:
scripts/config --enable  CONFIG_STATIC
scripts/config --enable  CONFIG_STATIC_LIBGCC
scripts/config --disable CONFIG_DEBUG_OPTIMIZATIONS
scripts/config --enable  CONFIG_LTO

# Gereksiz applet'leri kapat:
scripts/config --disable CONFIG_FEATURE_VI_REGEX
scripts/config --disable CONFIG_BC
scripts/config --disable CONFIG_DC
scripts/config --disable CONFIG_HUSH
scripts/config --set-str CONFIG_DEFAULT_SHELL ash

make CROSS_COMPILE=$CROSS ARCH=arm64 olddefconfig
make CROSS_COMPILE=$CROSS ARCH=arm64 -j$(nproc)
${CROSS}strip --strip-all busybox

BUSYBOX_SIZE=$(stat -c%s busybox)
echo "BusyBox boyutu: $((BUSYBOX_SIZE / 1024)) KB"

make CROSS_COMPILE=$CROSS ARCH=arm64 install \
     CONFIG_PREFIX=$WORK/rootfs
cd $WORK

# ─── 2. rootfs yapısı ─────────────────────────────────
for d in proc sys dev tmp run mnt var/log; do
    mkdir -p rootfs/$d
done

# inittab
cat > rootfs/etc/inittab << 'EOF'
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty -L ttyAMA0 115200 vt100
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
EOF

mkdir -p rootfs/etc/init.d
cat > rootfs/etc/init.d/rcS << 'EOF'
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null || mdev -s
echo /sbin/mdev > /proc/sys/kernel/hotplug
mount -t tmpfs tmpfs /tmp -o size=16m
ifconfig lo up
echo "Minimal Linux hazir — BusyBox ile calisiyor"
EOF
chmod +x rootfs/etc/init.d/rcS

echo "root::0:0:root:/root:/bin/sh" > rootfs/etc/passwd
echo "root:x:0:" > rootfs/etc/group

# ─── 3. cpio initramfs ────────────────────────────────
cd rootfs
find . | cpio -o -H newc | gzip -9 > ../initramfs.cpio.gz
cd ..
echo "initramfs boyutu: $(du -sh initramfs.cpio.gz | cut -f1)"

# ─── 4. QEMU ile test ─────────────────────────────────
echo "QEMU başlatılıyor..."
qemu-system-aarch64 \
  -machine virt \
  -cpu cortex-a57 \
  -m 128M \
  -kernel /path/to/linux/arch/arm64/boot/Image \
  -initrd initramfs.cpio.gz \
  -append "console=ttyAMA0 rdinit=/sbin/init" \
  -nographic \
  -no-reboot

Minimal kernel konfigürasyonu

# ARM64 için tinyconfig + gömülü gereksinimler
cd linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- tinyconfig

# Zorunlu eklemeler:
scripts/config --enable CONFIG_TTY
scripts/config --enable CONFIG_SERIAL_AMBA_PL011
scripts/config --enable CONFIG_SERIAL_AMBA_PL011_CONSOLE
scripts/config --enable CONFIG_BINFMT_ELF
scripts/config --enable CONFIG_BINFMT_SCRIPT
scripts/config --enable CONFIG_PROC_FS
scripts/config --enable CONFIG_SYSFS
scripts/config --enable CONFIG_TMPFS
scripts/config --enable CONFIG_DEVTMPFS
scripts/config --enable CONFIG_INITRAMFS_SOURCE
scripts/config --set-str CONFIG_INITRAMFS_SOURCE "$(pwd)/../minimal_system/initramfs.cpio.gz"

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
ls -lh arch/arm64/boot/Image
NOT

Kernel binary'sinin içine initramfs gömülürse (CONFIG_INITRAMFS_SOURCE), tek bir Image dosyası yeterli olur — ayrıca initrd parametresi vermek gerekmez. Bu yaklaşım, çok kısıtlı ortamlarda (örn. basit TFTP boot) işi basitleştirir ancak her initramfs değişikliğinde kernel yeniden derlenmek zorundadır.