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

OverlayFS & SquashFS
Üretim Rootfs Tasarımı.

Read-only SquashFS tabanlı rootfs üzerine OverlayFS katmanı kurarak fabrika sıfırlama, flash ömrü uzatma ve atom güncelleme desteği sağlayan üretim kalitesi gömülü Linux dosya sistemi mimarisi.

00 Neden read-only rootfs?

Güç kaybı, medya bozulması ve olası güvenlik açıklarına karşı en etkili savunma, kök dosya sistemini salt okunur (read-only) olarak bağlamaktır.

Üretim cihazlarında karşılaşılan sorunlar

Saha koşullarında çalışan gömülü cihazların karşılaştığı en yaygın arıza senaryosu güç kesilmesidir. NAND flash veya eMMC üzerinde anlık güç kesilmesi, bağlı bir ext4 veya JFFS2 dosya sisteminde yarım kalmış yazma işlemlerinin yarattığı tutarsız bloklar nedeniyle sistemin bir daha açılmamasına yol açar. Bu durumda saha teknisyeninin cihazı geri getirmesi ya da fabrikaya iade maliyeti çıkar.

Rootfs'i read-only tutmanın ikinci büyük faydası flash ömrüdür. NAND flash hücrelerinin sınırlı sayıda yazma/silme döngüsü vardır; rootfs read-only olduğunda bu hücreler ömür boyunca hiç yıpranmaz. Tüm runtime yazmaları tmpfs veya ayrı bir data bölümüne yönlenir.

Sağladığı üretim gereksinimleri

Güç kesilmesi dayanıklılığıSquashFS salt okunur — yarım yazma olmaz, fsck gerekmez, sistem her zaman tutarlı önyüklenir
Fabrika sıfırlamaKullanıcı verisi yalnızca upperdir'de; silmek = fabrika durumuna dönmek
GüvenlikSaldırgan rootfs'e yazamaz — zararlı yazılım kalıcı olamaz, read-only remount koruması
Flash ömrüRootfs bölümüne sıfır yazma — wear leveling yükü yalnızca data bölümünde
Atomik güncellemeA/B bölüm düzeninde yeni squashfs imajı yazar, pointer değiştir — rollback trivial
NOT

Read-only rootfs yaklaşımı Android'in system partition tasarımıyla aynı prensipleri paylaşır. Android 10'dan itibaren /system ve /vendor bölümleri SquashFS üzerinde salt okunur bağlanır; çalışma zamanı değişiklikleri overlay veya tmpfs katmanına yazılır.

Mimari karar ağacı

Cihazda flash ömrü kritik mi?
        |
       EVET
        |
   ro-rootfs kullan
        |
   +----+-----+
   |          |
tmpfs upper  ext4/f2fs data bölümü
(reboot'ta   (persist edilmesi
 sıfırlanır)  gereken veriler)
    

01 SquashFS oluşturma

SquashFS; sıkıştırılmış, salt okunur, yüksek sıkıştırma oranlı bir Linux dosya sistemidir. Rootfs imajı bir kez oluşturulur, hiçbir zaman değiştirilmez.

mksquashfs temel kullanımı

# Bir dizinden squashfs imajı oluştur
mksquashfs rootfs_dir/ rootfs.squashfs \
    -comp zstd \
    -Xcompression-level 15 \
    -noappend \
    -no-progress \
    -e proc sys dev run tmp

# Oluşturulan imajı incele
unsquashfs -s rootfs.squashfs
# Çıktı: block_size 131072, inodes 1234, ...

# İmajı geçici olarak bağla (loop device)
mkdir -p /mnt/squash
mount -t squashfs -o loop rootfs.squashfs /mnt/squash

Sıkıştırma algoritması seçimi

AlgoritmaSıkıştırma HızıAçma HızıOranKullanım Senaryosu
lz4Çok hızlıEn hızlıDüşükRAM kısıtlı, hızlı boot
lzoHızlıHızlıOrtaDengeli gömülü sistemler
zstdOrtaHızlıİyiModern önerilen seçim
gzipYavaşOrtaİyiEski sistemler, uyumluluk
xzÇok yavaşYavaşEn iyiDepolama kritik, NOR flash

Blok boyutu ve performans

SquashFS varsayılan blok boyutu 128 KB'dir. Küçük blok boyutu (4 KB, 8 KB) rastgele erişim performansını artırır ancak sıkıştırma oranını düşürür. Büyük blok boyutu (256 KB, 1 MB) daha iyi sıkıştırma sağlar ancak tek bir küçük dosyaya erişmek için daha fazla veri sıkıştırması çözülür.

# Blok boyutu karşılaştırma
mksquashfs rootfs/ out-4k.squashfs   -comp zstd -b 4096
mksquashfs rootfs/ out-128k.squashfs -comp zstd -b 131072
mksquashfs rootfs/ out-1m.squashfs   -comp zstd -b 1048576

ls -lh out-*.squashfs
# out-4k.squashfs:   45M
# out-128k.squashfs: 32M
# out-1m.squashfs:   29M
İPUCU

Gömülü sistemlerde zstd -Xcompression-level 3 ile hızlı build ve iyi oran dengesi kurulur. Nihai üretim imajı için seviye 15-19 kullanarak maksimum küçültme elde edilir; build süresi uzasa da bu işlem CI'da yapılır.

02 OverlayFS mimarisi

OverlayFS, Linux çekirdeğine 3.18 sürümünde dahil olan ve birden fazla dizini tek bir birleşik görünüme bindiren katmanlı bir dosya sistemidir.

Temel kavramlar

lowerdirSalt okunur alt katman — squashfs veya herhangi bir ro dosya sistemi. Değiştirilemez
upperdirYazılabilir üst katman — tmpfs veya ext4. Tüm yazma işlemleri buraya gider
workdirOverlayFS'in iç kullanımı için boş çalışma dizini — upperdir ile aynı dosya sistemi üzerinde olmalı
mergedKullanıcıya sunulan birleşik görünüm — upper + lower'ın üst üste bindirilmiş hali
┌─────────────────────────────┐
│        merged (görünen)     │  ← kullanıcı bu katmanı görür
│  /etc/passwd  /bin/bash     │
│  /etc/hosts   /usr/lib/...  │
└─────────┬───────────────────┘
          │ overlay birleştirme
    ┌─────┴─────┐
    │           │
┌───▼───┐   ┌──▼────┐
│ upper │   │ lower │
│(tmpfs)│   │(sqsh) │
│/etc/  │   │/etc/  │
│ hosts │   │ hosts │← upper'da varsa o gösterilir
│       │   │passwd │← sadece lower'da varsa lower gösterilir
└───────┘   └───────┘
    

Kernel mount komutu

mount -t overlay overlay \
    -o lowerdir=/mnt/lower,\
       upperdir=/mnt/upper,\
       workdir=/mnt/work \
    /mnt/merged

Whiteout ve opaque

Bir dosya lower katmanda var olup upper katmanda silindiğinde, OverlayFS upper'a o dosyanın adında bir whiteout dosyası (karakter cihazı 0:0) oluşturur. Bir dizin lower'dan gelen dizinin yerine tamamen yenisiyle değiştirildiğinde ise upper'a opaque xattr (trusted.overlay.opaque=y) yazılır.

# Whiteout dosyasını incele
ls -la /mnt/upper/etc/
# c---------. 1 root root 0, 0 silinen_dosya  ← whiteout

# Opaque dizin xattr'ı
getfattr -n trusted.overlay.opaque /mnt/upper/etc/replaced_dir/
# trusted.overlay.opaque="y"

03 Katmanlı rootfs tasarımı

Üretim kalitesi bir ro-rootfs tasarımında squashfs alt katman, tmpfs veya kalıcı bölüm üst katman olarak birleştirilir.

Senaryo 1: tmpfs upper (volatile)

Reboot sonrası tüm değişiklikler kaybolur. Kiosk, endüstriyel kontrol, güvenlik kamerası gibi cihazlar için idealdir.

#!/bin/sh
# /etc/init.d/overlay-mount veya initramfs init

SQUASHFS=/dev/mmcblk0p2
LOWER=/mnt/lower
UPPER=/mnt/upper
WORK=/mnt/work
MERGED=/

# squashfs'i bağla
mkdir -p $LOWER
mount -t squashfs -o ro $SQUASHFS $LOWER

# tmpfs upper/work hazırla
mount -t tmpfs tmpfs /mnt/rw
mkdir -p /mnt/rw/upper /mnt/rw/work

# overlay bağla
mount -t overlay overlay \
    -o lowerdir=$LOWER,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work \
    $MERGED

Senaryo 2: ext4 upper (persistent)

Değişiklikler yeniden başlatma sonrası korunur. Yapılandırma dosyaları, log, veritabanı gibi kalıcı veriler için gereklidir. Factory reset, ext4 bölümünü formatlamak kadar basittir.

DATA_PART=/dev/mmcblk0p3
DATA_MNT=/mnt/data

# Veri bölümünü bağla
mount -t ext4 -o noatime,nodiratime $DATA_PART $DATA_MNT

# upper ve work dizinleri veri bölümü altında
UPPER=$DATA_MNT/overlay/upper
WORK=$DATA_MNT/overlay/work
mkdir -p $UPPER $WORK

mount -t overlay overlay \
    -o lowerdir=$LOWER,upperdir=$UPPER,workdir=$WORK \
    /
DİKKAT

workdir ve upperdir kesinlikle aynı dosya sistemi üzerinde olmalıdır. Farklı bölümlere yerleştirilirse mount: invalid argument hatasıyla karşılaşılır. Her ikisi de aynı ext4 veya tmpfs bölümü altındaki alt dizinler olmalıdır.

Çoklu lowerdir (birden fazla katman)

OverlayFS, Linux 4.0'dan itibaren birden fazla salt okunur alt katmanı destekler. Bu özellik OTA güncellemelerinde delta katmanı eklemek için kullanılır:

# lower1 = base rootfs, lower2 = uygulama katmanı
mount -t overlay overlay \
    -o lowerdir=/mnt/app:/mnt/base,\
       upperdir=/mnt/rw/upper,\
       workdir=/mnt/rw/work \
    /mnt/merged
# Öncelik: /mnt/app > /mnt/base (soldan sağa)

04 Factory reset implementasyonu

Factory reset, upperdir'in tüm içeriğini silmek ve cihazı yeniden başlatmaktan ibarettir. Donanım reset butonu veya yazılım tetikleyicisiyle entegre edilir.

systemd reset service

# /usr/lib/systemd/system/factory-reset.service
[Unit]
Description=Factory Reset Service
After=umount.target
DefaultDependencies=no
Before=shutdown.target reboot.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/do-factory-reset.sh
StandardOutput=journal

[Install]
WantedBy=multi-user.target
#!/bin/bash
# /usr/sbin/do-factory-reset.sh
set -e

DATA_PART=/dev/mmcblk0p3
DATA_MNT=/mnt/data_reset

echo "Factory reset başlatılıyor..."

# Geçici bağlama noktası
mkdir -p $DATA_MNT
mount -t ext4 $DATA_PART $DATA_MNT

# Overlay dizinini sil
rm -rf $DATA_MNT/overlay/upper
rm -rf $DATA_MNT/overlay/work

# Temiz dizinleri yeniden oluştur
mkdir -p $DATA_MNT/overlay/upper $DATA_MNT/overlay/work

umount $DATA_MNT
echo "Factory reset tamamlandı. Yeniden başlatılıyor..."

# Yeniden başlat
systemctl reboot

Donanım reset butonu (GPIO)

#!/bin/bash
# /usr/sbin/reset-button-monitor.sh
# GPIO 17 = reset butonu (active-low)

GPIO_NUM=17
HOLD_SECONDS=5

echo $GPIO_NUM > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio${GPIO_NUM}/direction

while true; do
    STATE=$(cat /sys/class/gpio/gpio${GPIO_NUM}/value)
    if [ "$STATE" = "0" ]; then
        # Buton basılı — sayaç başlat
        COUNT=0
        while [ "$STATE" = "0" ] && [ $COUNT -lt $HOLD_SECONDS ]; do
            sleep 1
            COUNT=$((COUNT + 1))
            STATE=$(cat /sys/class/gpio/gpio${GPIO_NUM}/value)
        done
        if [ $COUNT -ge $HOLD_SECONDS ]; then
            systemctl start factory-reset.service
        fi
    fi
    sleep 0.2
done
NOT

Üretim sistemlerinde GPIO izleme için gpiod (libgpiod) kullanımı önerilir. Eski sysfs GPIO arayüzü çekirdek 5.x'te deprecated sayılmaktadır. gpioget ve gpiomon araçları daha güvenilir edge detection sağlar.

05 OverlayFS + Buildroot

Buildroot ile squashfs + overlay rootfs imajı oluşturmak için birkaç yapılandırma değişikliği ve board özelleştirme scripti yeterlidir.

Buildroot menuconfig ayarları

# make menuconfig ile aşağıdaki seçenekleri etkinleştir:

# Filesystem Images:
BR2_TARGET_ROOTFS_SQUASHFS=y
BR2_TARGET_ROOTFS_SQUASHFS_LZMA=n
BR2_TARGET_ROOTFS_SQUASHFS_LZ4=n
BR2_TARGET_ROOTFS_SQUASHFS_ZSTD=y

# Overlay filesystem support (package):
BR2_PACKAGE_UTIL_LINUX=y          # mount komutu için
BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y

Kernel konfigürasyonu

# Linux kernel .config içinde gerekli seçenekler:
CONFIG_OVERLAY_FS=y               # ya da =m (modül olarak)
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_SQUASHFS_XZ=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y

post-build.sh ile init script ekleme

#!/bin/bash
# board/myboard/post-build.sh
# Buildroot bu scripti rootfs finalize'dan önce çalıştırır

TARGET_DIR=$1

# Overlay mount init scriptini kopyala
install -m 755 board/myboard/overlay/etc/init.d/S01overlay \
    $TARGET_DIR/etc/init.d/S01overlay

# Readonly fstab oluştur
cat > $TARGET_DIR/etc/fstab << 'EOF'
/dev/mmcblk0p2  /mnt/lower  squashfs  ro,noatime           0 0
tmpfs           /mnt/rw     tmpfs     size=64m,mode=755    0 0
overlay         /           overlay   lowerdir=/mnt/lower,upperdir=/mnt/rw/upper,workdir=/mnt/rw/work  0 0
EOF

Buildroot imaj düzeni

BölümİçerikDosya SistemiErişim
mmcblk0p1Bootloader (U-Boot), DTB, kernelFAT32/rawR/W (boot)
mmcblk0p2rootfs.squashfsSquashFSRead-only
mmcblk0p3overlay upper/work + user dataext4R/W

06 OverlayFS + Yocto

Yocto, overlayfs-etc.bbclass ve IMAGE_FSTYPES mekanizmalarıyla squashfs + overlay kurulumunu resmi olarak destekler.

local.conf / image recipe ayarları

# conf/local.conf veya image recipe'si içinde:
IMAGE_FSTYPES += "squashfs"
IMAGE_FSTYPES:append = " squashfs-zst"

# squashfs sıkıştırma seçenekleri
EXTRA_IMAGECMD:squashfs = "-comp zstd -Xcompression-level 15 -b 131072"

overlayfs-etc.bbclass kullanımı

# image recipe'sine inherit et:
# recipes-core/images/my-image.bb
inherit overlayfs-etc

# /etc dizinini overlay ile yönet:
OVERLAYFS_ETC_MOUNT_POINT = "/data"
OVERLAYFS_ETC_DEVICE       = "/dev/mmcblk0p3"
OVERLAYFS_ETC_FSTYPE        = "ext4"
OVERLAYFS_ETC_MOUNT_OPTIONS = "defaults,noatime"

Bu bbclass, /etc dizinini alt katman ve /data/overlay-etc üst katman olarak otomatik olarak yönetir. Systemd mount unit'leri ve mount-overlay.service dosyaları otomatik üretilir.

Kalıcılık (persistency) stratejisi

# recipes-core/images/my-image.bb
# Hangi dizinlerin kalıcı olduğunu belirt:
OVERLAYFS_MOUNT_POINT[data] = "/data"
OVERLAYFS_WRITABLE_PATHS[data] = " \
    /etc/network/interfaces \
    /var/lib/dhcp \
    /home \
"
NOT

Yocto Kirkstone (4.0) ve sonrasında overlayfs.bbclass geliştirilmiş ve OVERLAYFS_QA_SKIP değişkeni ile lint kontrolleri atlanabilir hale getirilmiştir. Dunfell (3.1) kullanıyorsanız bbclass'ı meta-layer'ınıza elle kopyalamanız gerekebilir.

07 Persistent partition stratejisi

Kalıcı veri bölümü tasarımı, hangi dizinlerin reboot'a karşı dayanıklı olması gerektiğine dair bilinçli kararlar gerektirir.

Dizin kategorileri

DizinİçerikStratejiNeden
/etcSistem yapılandırmasıOverlay upperFabrika reset'te sıfırlanabilmeli
/var/logSistem loglarıtmpfs veya ayrı bölümFlash yıpranmasını önle
/var/libUygulama durumuBind mount — data bölümüReboot'ta korunmalı
/homeKullanıcı verileriBind mount — data bölümüReboot'ta korunmalı
/tmpGeçici dosyalartmpfsRAM'da, flash'a yazma yok
/runRuntime PID, sockettmpfs (otomatik)systemd tarafından yönetilir

fstab ile bind mount kurulumu

# /etc/fstab — persistent bölüm bind mount'ları
/dev/mmcblk0p3  /data          ext4    defaults,noatime  0 2

# data bölümü altındaki dizinleri bind mount et
/data/var/lib   /var/lib       none    bind              0 0
/data/home      /home          none    bind              0 0

# Log'ları tmpfs'e yönlendir (flash ömrü)
tmpfs           /var/log       tmpfs   size=32m,nosuid,nodev  0 0
tmpfs           /tmp           tmpfs   size=64m,nosuid,nodev  0 0

İlk açılışta data bölümü init

#!/bin/sh
# /etc/init.d/S02data-init

DATA=/data
DIRS="var/lib var/lib/dhcp home"

# İlk boot: dizinleri oluştur
for dir in $DIRS; do
    if [ ! -d "$DATA/$dir" ]; then
        mkdir -p "$DATA/$dir"
        # Squashfs'teki varsayılan içeriği kopyala
        if [ -d "/mnt/lower/$dir" ]; then
            cp -a "/mnt/lower/$dir/." "$DATA/$dir/"
        fi
    fi
done

08 Pratik: Raspberry Pi'da ro-rootfs + overlay + factory reset

Raspberry Pi 4 üzerinde squashfs tabanlı read-only rootfs, tmpfs overlay ve GPIO reset butonu ile eksiksiz bir uygulama.

Adım 1: Mevcut rootfs'ten squashfs oluşturma

# Pi üzerinde veya SD kart PC'ye takılıyken:
# /proc /sys /dev /run /tmp dışarıda bırak
mksquashfs /mnt/pi_root rootfs.squashfs \
    -comp zstd \
    -Xcompression-level 10 \
    -noappend \
    -e proc -e sys -e dev -e run -e tmp \
    -e mnt -e media

# SD karta yaz (mmcblk0p2 = rootfs bölümü)
dd if=rootfs.squashfs of=/dev/mmcblk0p2 bs=4M status=progress

Adım 2: initramfs ile overlay kurulumu

#!/bin/sh
# /etc/initramfs-tools/scripts/overlay (Raspberry Pi OS)
# veya /init (özel initramfs)

prereqs() { echo ""; }
case $1 in prereqs) prereqs; exit 0 ;; esac

. /scripts/functions

LOWER=/mnt/lower
RW=/mnt/rw

# squashfs bölümünü bağla
mkdir -p $LOWER
mount -t squashfs -o ro ${ROOT} $LOWER

# tmpfs üst katmanı hazırla
mount -t tmpfs -o size=128m tmpfs $RW
mkdir -p $RW/upper $RW/work

# overlay'i gerçek rootfs'e bağla
mount -t overlay overlay \
    -o lowerdir=$LOWER,upperdir=$RW/upper,workdir=$RW/work \
    ${rootmnt}

# Çalışma anı pseudo-fs bağlama noktaları oluştur
mkdir -p ${rootmnt}/mnt/lower ${rootmnt}/mnt/rw
mount --move $LOWER ${rootmnt}/mnt/lower
mount --move $RW    ${rootmnt}/mnt/rw

Adım 3: cmdline.txt güncellemesi

# /boot/cmdline.txt
console=serial0,115200 console=tty1 \
root=/dev/mmcblk0p2 rootfstype=squashfs \
ro quiet init=/sbin/overlay-init

Adım 4: Factory reset servisi kurulumu

cat > /etc/systemd/system/factory-reset.service << 'EOF'
[Unit]
Description=Factory Reset — tüm overlay değişikliklerini sil
DefaultDependencies=no
After=umount.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'rm -rf /mnt/rw/upper/* /mnt/rw/upper/.[^.]*'
ExecStartPost=/bin/systemctl reboot
EOF

systemctl daemon-reload

Adım 5: Doğrulama

# Rootfs'in read-only bağlandığını doğrula
mount | grep " / "
# overlay on / type overlay (rw,lowerdir=/mnt/lower,upperdir=...)

# Değişiklik yap ve reboot sonrası kaybolduğunu gör
echo "test" > /tmp/kalici_mi
cat /tmp/kalici_mi  # "test" gösterir
reboot
cat /tmp/kalici_mi  # Dosya yok — overlay temizlendi

# squashfs boyutu ve içeriği
df -h /mnt/lower
ls /mnt/lower/etc/
ÖZET

Read-only squashfs + OverlayFS kombinasyonu, gömülü Linux üretim cihazlarında güç kesilmesi dayanıklılığı, fabrika sıfırlama ve flash ömrü optimizasyonu için olgunlaşmış bir standarttır. Buildroot ve Yocto her ikisi de bu mimariyi birinci sınıf olarak destekler.