00 Flash bellek temelleri
Flash bellek, blok tabanlı elektriksel olarak silinip yazılabilen kalıcı depolama teknolojisidir; NOR ve NAND iki temel mimariyi temsil eder.
NOR ve NAND karşılaştırması
NOR flash her hücreyi doğrudan adresleyebilir (random access), bu yüzden XIP (execute-in-place) için uygundur; bootloader kodunu çalıştırmak için idealdir. NAND ise page/block organizasyonuyla çok daha yüksek yoğunluk ve düşük birim maliyet sunar; büyük veri depolama için tercih edilir. Ancak NAND, üretimden gelen bad block içerebilir ve yazma sırasında da yeni bad block oluşabilir — bu ECC ve bad block yönetimini zorunlu kılar.
| Özellik | NOR Flash | NAND Flash |
|---|---|---|
| Bus arayüzü | Paralel veya SPI (QSPI) | Paralel (raw) veya SPI (SPI NAND) |
| Erase boyutu | 4–64 KB (sector) | 64–512 KB (block = 64 × page) |
| Okuma hızı | Yüksek; XIP destekli | Daha düşük; sayfalık okuma |
| Yazma hızı | Yavaş (byte-by-byte) | Hızlı (page programlama) |
| Bad block | Yok (pratik olarak) | Var; fabrika + kullanım sürecinde |
| Kapasite | Düşük (16 MB – 1 GB tipik) | Yüksek (256 MB – 64 GB+) |
| Birim maliyet | Yüksek | Düşük |
| Tipik kullanım | Bootloader, küçük firmware | Rootfs, data partition, büyük image |
SLC / MLC / TLC / QLC hücre tipleri
Bir flash hücresinin kaç bit sakladığı; silme döngüsü dayanıklılığını, güvenilirliğini ve maliyetini doğrudan belirler. Endüstriyel ve güvenlik kritik uygulamalarda SLC kesinlikle tercih edilmelidir.
Page / Block / Plane yapısı
NAND organizasyonu hiyerarşik bir yapıdan oluşur. Okuma ve yazma işlemleri page granülüründe, silme ise block granülüründe gerçekleşir — bir block içindeki tek bir page'i silmek için tüm bloğu silmek zorundasınız.
Die → Plane → Block (erase unit) → Page (read/write unit) → Byte
| Katman | Tipik boyut | Operasyon |
|---|---|---|
| Page | 2 KB – 16 KB (data) + OOB alanı | Program (write), Read |
| Block | 64 – 512 pages (= 128 KB – 8 MB) | Erase |
| Plane | Binlerce block | Paralel operasyon (multi-plane) |
| Die / LUN | Birden fazla plane | Bağımsız komut kuyruğu |
Her page'in sonunda OOB (Out-of-Band) alanı bulunur — tipik olarak 64–256 byte. Bu alan ECC paritesi, bad block işaretçisi ve dosya sistemi metadata'sı için kullanılır. Linux MTD sürücüleri OOB'u otomatik yönetir.
Wear leveling neden gerekli
Flash hücrelerinin programlama/silme (P/E) döngüsü sınırlıdır. Aynı blok tekrar tekrar yazılırsa diğerlerinden çok daha hızlı aşınır ve bad block haline gelir. Wear leveling, yazmaları tüm bloklar arasında eşit dağıtarak toplam flash ömrünü maksimize eder. UBI katmanı bu görevi yazılım katmanında üstlenir; eMMC/SD kartlarda ise bu işlev donanım flash controller'ı tarafından gerçekleştirilir.
Raw NAND flash üzerine doğrudan ext2/ext4 gibi block-tabanlı dosya sistemi kurmayın. Bu dosya sistemleri bad block yönetimi ve wear leveling yapmaz; veri bozulmasına ve erken arızaya yol açar. Bunun yerine UBI + UBIFS zincirini kullanın.
Bu bölümde
- NOR: random access, XIP, küçük kapasite, bootloader için ideal
- NAND: yüksek kapasite, düşük maliyet, bad block yönetimi gerektirir
- SLC en dayanıklı (100 K P/E); TLC/QLC tüketici ürünler için
- Silme block granüllü, yazma page granüllü; wear leveling şart
01 Linux MTD subsystem
MTD (Memory Technology Device), Linux'un flash bellek soyutlama katmanıdır — donanım sürücüsü ile üst katman araçları arasında standart bir arayüz sağlar.
/dev/mtd* ve /dev/mtdblock* farkı
MTD subsystem iki farklı cihaz dosyası türü sunar. Bu ikisinin farkını anlamak kritik önemdedir.
flash_erase, nandwrite, nanddump bu arayüzü kullanır.MTD partition listesini görüntüleme
# Kernel tarafından tanınan MTD partition'larını listele
cat /proc/mtd
# dev: size erasesize name
# mtd0: 00080000 00020000 "SPL"
# mtd1: 00060000 00020000 "SPL.backup"
# mtd2: 00140000 00020000 "u-boot"
# mtd3: 00020000 00020000 "u-boot.env"
# mtd4: 00800000 00020000 "kernel"
# mtd5: 0f560000 00020000 "rootfs"
# mtdinfo ile daha ayrıntılı bilgi (mtd-utils paketi)
mtdinfo /dev/mtd0
# Name: SPL
# Type: nand
# Eraseblock size: 131072 bytes, 128.0 KiB
# Amount of eraseblocks: 4 (524288 bytes, 512.0 KiB)
# Minimum input/output unit size: 2048 bytes
# Sub-page size: 512 bytes
# OOB size: 64 bytes
# Character device major/minor: 90:0
# Bad blocks are allowed: true
# Device is writable: true
# Tüm MTD cihazlarını listele
mtdinfo -a
MTD cihaz türleri
| Tür | Açıklama | Örnek donanım |
|---|---|---|
| MTD_NORFLASH | CFI/JEDEC uyumlu NOR flash | Spansion S25FL, Intel StrataFlash |
| MTD_NANDFLASH | Raw NAND; page/block organizasyonlu | Micron MT29F, Samsung K9 |
| MTD_SPI-NOR | SPI arayüzlü NOR (m25p80 sürücüsü) | Winbond W25Q128, Macronix MX25L |
| MTD_SPI-NAND | SPI arayüzlü NAND | Winbond W25N, GigaDevice GD5F |
| MTD_DATAFLASH | Atmel DataFlash (SPI) | AT45DB serisi |
Kernel konfigürasyonu
# MTD altyapısını etkinleştir
CONFIG_MTD=y
CONFIG_MTD_CHAR=y # /dev/mtdN karakter cihazları
CONFIG_MTD_BLOCK=y # /dev/mtdblockN
# NAND flash desteği
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y # yazılım ECC (donanım yoksa)
CONFIG_MTD_NAND_ECC_SW_BCH=y # BCH ECC — daha güçlü
# SPI NOR (m25p80 sürücüsü)
CONFIG_MTD_SPI_NOR=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
# Partition parser'ları
CONFIG_MTD_CMDLINE_PARTS=y # cmdline'dan partition okuma
CONFIG_MTD_OF_PARTS=y # Device Tree'den partition okuma (önerilen)
# UBI desteği
CONFIG_MTD_UBI=y
CONFIG_UBIFS_FS=y
Device Tree'de MTD partition tanımı
/* arch/arm/boot/dts/myboard.dts */
&gpmc {
nand@0 {
compatible = "ti,omap2-nand";
reg = <0 0 4>;
nand-bus-width = <8>;
ti,nand-ecc-opt = "bch8";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "SPL";
reg = <0x0 0x80000>; /* 512 KB */
};
partition@80000 {
label = "u-boot";
reg = <0x80000 0x140000>; /* 1.25 MB */
};
partition@1c0000 {
label = "u-boot.env";
reg = <0x1c0000 0x40000>; /* 256 KB */
};
partition@200000 {
label = "kernel";
reg = <0x200000 0xa00000>; /* 10 MB */
};
partition@c00000 {
label = "rootfs";
reg = <0xc00000 0x0>; /* kalan alan */
};
};
};
MTD partition'larını Device Tree ile tanımlamak (CONFIG_MTD_OF_PARTS) kernel cmdline yöntemine göre çok daha temiz ve board bağımlı konfigürasyonu yerinde tutar. Yeni tasarımlarda DTS yöntemini tercih edin.
Bu bölümde
/dev/mtdNham karakter erişimi;/dev/mtdblockNblok emülasyonu — NAND'da sadece mtdN kullanıncat /proc/mtdvemtdinfo -apartition'ları listeler- Kernel config:
CONFIG_MTD_NAND=y,CONFIG_MTD_UBI=y,CONFIG_UBIFS_FS=y - Partition layout: Device Tree tercih edilmeli
02 NAND flash operasyonları
mtd-utils paketi, NAND flash üzerinde erase, write ve dump işlemleri için komut satırı araçları sağlar; bad block yönetimi bu araçlar tarafından otomatik yapılır.
mtd-utils kurulumu
# Host (Ubuntu/Debian)
sudo apt install mtd-utils
# Cross-compile (Yocto):
# IMAGE_INSTALL:append = " mtd-utils"
# Buildroot: BR2_PACKAGE_MTD=y
Flash erase
# Tüm mtd0'ı sil (offset=0, count=0 → tüm partition)
flash_erase /dev/mtd0 0 0
# Sadece ilk 10 erase block'u sil
# Offset: 0x00000, Block count: 10
flash_erase /dev/mtd0 0 10
# Verbose mod — ilerleme göster
flash_erase --verbose /dev/mtd2 0 0
# JFFS2 clean marker yaz (JFFS2 mount için gerekli)
flash_erase --jffs2 /dev/mtd5 0 0
NAND'a yazma: nandwrite
# Erase ardından image yaz (en yaygın kullanım)
flash_erase /dev/mtd4 0 0
nandwrite -p /dev/mtd4 kernel.bin
# -p: padding — image page sınırına tamamlanır
# Belirli bir offset'e yaz
nandwrite -p -s 0x200000 /dev/mtd4 kernel.bin
# Bad block'ları atla (-c: marklanmış bad block skip)
nandwrite -p -c /dev/mtd4 kernel.bin
# OOB alanıyla birlikte yaz (raw mod — dikkatli kullan)
nandwrite --raw /dev/mtd4 kernel_with_oob.bin
NAND'dan okuma: nanddump
# Tüm partition'ı dosyaya dump et
nanddump /dev/mtd4 -f kernel_dump.bin
# OOB alanı dahil dump
nanddump --oob /dev/mtd4 -f full_dump.bin
# Sadece belirli bir aralık: offset + uzunluk
nanddump -s 0x0 -l 0x100000 /dev/mtd4 -f first_1MB.bin
# Bad block'ları atla (-c flag)
nanddump -c /dev/mtd4 -f dump_skip_bad.bin
# Hexdump ile inceleme (küçük partition için)
nanddump /dev/mtd0 -f /tmp/spl.bin && hexdump -C /tmp/spl.bin | head -40
Bad block yönetimi
# Mevcut bad block'ları listele
nandtest -m /dev/mtd4
# bad eraseblock N at 0x...
# mtdinfo ile bad block sayısı
mtdinfo /dev/mtd4
# Bad blocks: 3
# Bad block tablosunu görüntüle (kernel dmesg)
dmesg | grep -i "bad block"
# [ 1.234567] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xda
# [ 1.234890] nand: Bad block at 0x01fe0000
nandwrite ile kernel veya bootloader yazarken bad block atlama (-c) flag'ini kullanın. Aksi takdirde bad block üzerine yazma girişimi hata döner ve image bozulabilir. UBI kullanıyorsanız bu yönetim otomatik yapılır.
Bu bölümde
flash_erase /dev/mtdN 0 0tüm partition'ı silernandwrite -p /dev/mtdN image.binen yaygın yazma komutunanddump /dev/mtdN -f dump.bintam partition dump-cflag'i bad block'ları otomatik atlar
03 NOR flash operasyonları
NOR flash, bad block yönetimi gerektirmez ve XIP kapasitesine sahiptir; flashcp ile doğrudan programlanabilir.
flashcp ile NOR yazma
# NOR flash'a firmware yaz (-v: verbose, ilerleme göster)
flashcp -v firmware.bin /dev/mtd0
# Flashing... (0% - 10% - ... - 100%)
# Verifying... done.
# flashcp hem erase hem write yapar — önceden flash_erase gerekmez
# SPI NOR üzerinde manuel erase + write
flash_erase /dev/mtd0 0 0
dd if=firmware.bin of=/dev/mtd0 bs=4096
# Sadece belirli bir bölgeyi güncelle (offset ile)
# flash_erase offset'i erase block sınırına hizalamalısın
flash_erase /dev/mtd0 0x10000 4 # 0x10000 offset, 4 blok sil
dd if=patch.bin of=/dev/mtd0 bs=4096 seek=16 # offset=16*4096=0x10000
/dev/mtdblock ile raw erişim (NOR)
# NOR flash'ı read-only mount et (cramfs/squashfs için)
mount -t cramfs /dev/mtdblock2 /mnt/rom -o ro
# squashfs NOR üzerinde
mount -t squashfs /dev/mtdblock2 /mnt/rom -o ro
# FAT üzerinde U-Boot environment değişkenlerini oku
mount -t vfat /dev/mtdblock1 /mnt/env
# Doğrudan okuma (cat ile ham binary)
cat /dev/mtdblock0 > /tmp/nor_backup.bin
CFI probe — donanım tespiti
CFI (Common Flash Interface), NOR flash'ların parametrelerini (boyut, erase block, timing) standart bir sorgu protokolüyle raporlamasını sağlar. Linux CFI sürücüsü boot sırasında bu bilgiyi otomatik okur.
# Boot sırasında CFI probe çıktısı (dmesg)
dmesg | grep -i "cfi\|nor\|flash"
# [ 0.456789] physmap-flash 10000000.flash: physmap platform flash device: [mem 0x10000000-0x10ffffff]
# [ 0.456800] physmap-flash 10000000.flash: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x000089 Chip ID 0x8801
# [ 0.457000] Intel/Sharp Extended Query Table at 0x0031
# [ 0.457100] Using buffer write method
# [ 0.457200] physmap-flash 10000000.flash: CFI conformant device (jedec_probe)
# SPI NOR tespiti (m25p80 / spi-nor sürücüsü)
dmesg | grep -i "spi.*nor\|m25p\|w25q"
# [ 1.234567] m25p80 spi0.0: w25q128 (16384 Kbytes)
# [ 1.234600] 3 fixed-partitions partitions found on MTD device spi0.0
SPI NOR flash için Device Tree'de compatible = "jedec,spi-nor" kullanmak, tek bir sürücüyle tüm JEDEC uyumlu cihazları kapsar. Cihaz kimliği kernel tarafından spi-nor tablosundan otomatik eşleştirilir.
Bu bölümde
flashcp -v firmware.bin /dev/mtd0en güvenli NOR yazma yöntemi/dev/mtdblocksadece NOR'da read-only kullanım için güvenli- CFI probe: kernel boot log'unda flash kapasitesi ve geometri otomatik raporlanır
04 UBI — Unsorted Block Images
UBI, ham NAND flash üzerinde wear leveling, bad block yönetimi ve I/O hata kurtarma sağlayan bir ara katmandır — UBIFS bu katman üzerine oturur.
UBI mimarisi
UBI, MTD katmanı ile dosya sistemi arasına girer. Fiziksel erase block'ları (PEB) ile mantıksal erase block'ları (LEB) arasında esnek bir eşleme tablası tutar; bu sayede wear leveling ve bad block yönetimini şeffaf biçimde gerçekleştirir.
UBIFS / diğer FS → UBI (LEB → PEB eşleme, wear leveling) → MTD driver → NAND donanımı
UBI format ve attach
# Adım 1: NAND partition'ı UBI için hazırla (format)
# Bu komut tüm PEB'leri siler ve EC header yazar
ubiformat /dev/mtd2
# ubiformat: mtd2 (nand), size 268435456 bytes (256.0 MiB),
# 2048 eraseblocks of 131072 bytes (128.0 KiB)
# ubiformat: formatting eraseblock 0 -- 100 % complete
# Verbose + minimum I/O unit belirt
ubiformat -v -s 2048 /dev/mtd2
# Adım 2: UBI volume'ünü kernel'a attach et
ubiattach -m 2
# UBI device number 0, total 2048 LEBs
# /dev/ubi0 oluşur
# Belirli bir UBI device numarası ata
ubiattach -m 2 -d 0 # → /dev/ubi0
ubiattach -m 3 -d 1 # → /dev/ubi1
# Detach etmek için
ubidetach -m 2
UBI volume oluşturma
# rootfs volume oluştur (50 MiB)
ubimkvol /dev/ubi0 -N rootfs -s 50MiB
# /dev/ubi0_0 oluşur
# data volume oluştur (kalan tüm alanı kullan)
ubimkvol /dev/ubi0 -N data -m
# -m: maximum available size
# Volume'leri listele
ubinfo -a
# UBI device 0, total 2048 LEBs (260046848 bytes, 248.0 MiB),
# Volume 0: rootfs, size: 400 LEBs (50 MiB)
# Volume 1: data, size: 1595 LEBs (197.7 MiB)
# Volume boyutunu güncelle (sadece dynamic volume)
ubirsvol /dev/ubi0_0 -s 80MiB
# Volume sil
ubirmvol /dev/ubi0 -N data
UBI image yazmak: ubiupdatevol
# Önceden hazırlanmış UBIFS image'ını volume'e yaz
ubiupdatevol /dev/ubi0_0 rootfs.ubifs
# İlerleme göstererek yaz
ubiupdatevol -s $(stat -c %s rootfs.ubifs) /dev/ubi0_0 rootfs.ubifs
UBI volume türleri: dynamic (okuma/yazma, normal kullanım) ve static (sadece okunur; CRC korumalı; kernel image gibi değişmeyen veriler için). Static volume için ubimkvol --type static kullanın.
Bu bölümde
ubiformat /dev/mtdN→ubiattach -m N→ubimkvoltemel UBI hazırlık akışı- PEB/LEB ayrımı; EC ve VID header'lar wear leveling'in temeli
- Static volume: CRC korumalı, değişmeyen veriler için
ubinfo -atüm volume'leri listeler
05 UBIFS — UBI üzerine dosya sistemi
UBIFS, UBI logical volume üzerine kurulan log-yapılandırmalı bir dosya sistemidir; NAND flash'ın tüm özelliklerine uyum sağlar ve güç kaybında tutarlılık garantisi verir.
UBIFS'in avantajları
UBIFS mount etme
# UBI volume adıyla mount (ubi0:rootfs sözdizimi)
mount -t ubifs ubi0:rootfs /mnt
# Cihaz dosyasıyla mount
mount -t ubifs /dev/ubi0_0 /mnt
# Sıkıştırma seçeneğiyle mount
mount -t ubifs -o compr=lzo ubi0:rootfs /mnt
# /etc/fstab satırı
# ubi0:rootfs / ubifs defaults,noatime 0 0
# Kernel cmdline ile rootfs olarak boot
# root=ubi0:rootfs rootfstype=ubifs ubi.mtd=5
mkfs.ubifs ile image oluşturma
# rootfs dizininden UBIFS image üret
# -r: kaynak dizin
# -m: minimum I/O birimi (page size, örn. 2048)
# -e: LEB boyutu (erase block - 2*page, örn. 131072 - 4096 = 126976 ≈ 0x1f000)
# -c: maksimum LEB sayısı (volume büyüklüğü / LEB boyutu)
mkfs.ubifs \
-r /path/to/rootfs \
-m 2048 \
-e 126976 \
-c 2000 \
-o rootfs.ubifs
# Sıkıştırma belirterek (varsayılan lzo)
mkfs.ubifs -r rootfs/ -m 2048 -e 126976 -c 2000 \
-x lzo -o rootfs.ubifs
# LEB boyutu hesabı:
# erase_block_size = 128 KiB = 131072 bytes
# LEB = erase_block_size - 2 * min_io_size (EC + VID header alanı)
# LEB = 131072 - 2*2048 = 126976 bytes
ubinize ile UBI image üretme
Üretim programlaması için UBIFS image'ını UBI volume metadata'sıyla birleştiren bir .ubi image üretilebilir — bu image tek seferde ubiformat ile flash'a yazılır.
[ubifs-volume]
mode=ubi
image=rootfs.ubifs
vol_id=0
vol_size=50MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
[data-volume]
mode=ubi
vol_id=1
vol_size=100MiB
vol_type=dynamic
vol_name=data
# UBI image üret
# -p: PEB boyutu (erase block), -m: minimum I/O, -s: sub-page (eğer varsa)
ubinize \
-o rootfs.ubi \
-p 128KiB \
-m 2048 \
-s 512 \
ubinize.cfg
# Üretilen .ubi image'ı flash'a yaz (NAND önceden erase edilmemeli — ubiformat yapar)
ubiformat /dev/mtd5 -f rootfs.ubi
vol_flags=autoresize: Son volume, UBI attach sırasında mevcut tüm boş alanı otomatik olarak kaplar. Farklı flash kapasiteli kartlarda tek bir image ile çalışmak için kullanışlıdır.
Bu bölümde
mount -t ubifs ubi0:rootfs /mntveyaroot=ubi0:rootfscmdlinemkfs.ubifs -r rootfs/ -m 2048 -e 126976 -c 2000 -o rootfs.ubifsubinizeile çok-volume UBI image üretimi;ubiformat -f rootfs.ubiile tek adımda yaz- LEB = erase_block_size - 2 × min_io_size
06 Partition layout tasarımı
Flash partition layout, erase block sınırlarına hizalı olmalı, bad block rezervasyonu içermeli ve her partition'ın amacına uygun boyutlandırılmalıdır.
Tipik NAND partition yapısı
| Partition | Boyut | Tür | İçerik |
|---|---|---|---|
| SPL | 512 KB | Raw | Secondary Program Loader; ROM tarafından okunur |
| SPL.backup | 512 KB | Raw | SPL yedek kopyası; güvenilirlik için |
| u-boot | 1.5 MB | Raw | U-Boot binary (u-boot.img) |
| u-boot.env | 256 KB | Raw | U-Boot environment değişkenleri; iki kopya önerilir |
| kernel | 8–16 MB | Raw veya UBI static | zImage/Image + DTB veya FIT image |
| rootfs | 50–256 MB | UBI + UBIFS | Kök dosya sistemi |
| data | kalan | UBI + UBIFS | Uygulama verisi, log, konfigürasyon |
Boyut hesaplama ve hizalama
# Örnek: 256 MB NAND, 128 KB erase block
# Toplam erase block sayısı
TOTAL_BLOCKS=$(( 256 * 1024 * 1024 / (128 * 1024) ))
# TOTAL_BLOCKS = 2048
# Bad block rezervasyonu: ~%2 önerilir
RESERVED_BAD=$(( TOTAL_BLOCKS * 2 / 100 ))
# RESERVED_BAD ≈ 40 block
# Kullanılabilir block sayısı
USABLE=$(( TOTAL_BLOCKS - RESERVED_BAD ))
# USABLE ≈ 2008 block = ~251 MB
# Her partition boyutu erase block katı olmalı
# SPL: 512 KB = 4 erase block
# u-boot: 1536 KB = 12 erase block
# kernel: 10 MB = 80 erase block
# rootfs: 128 MB = 1024 erase block
# data: kalan
Bad block rezervasyonu ve UBI overhead
UBI her PEB için EC ve VID header yazar; bu 2 × min_io_size alanı kullanır. Ayrıca UBI kendi iç yönetimi için birkaç PEB rezerve eder (genellikle 20 PEB). NAND flash standartları ise üretimden gelen bad block'lar için kapasitesi başına %2'ye kadar reserve edilmesini zorunlu kılar. Bunu hesaba katmadan UBI volume boyutu belirlemeyin.
SPL ve U-Boot partition'larını kesinlikle UBI'ye dahil etmeyin. ROM bootrom UBI formatını bilmez; bu partition'lar raw olarak kalmalıdır. Yalnızca Linux'un kullandığı partition'larda (kernel sonrası) UBI uygulayın.
U-Boot environment çift kopya
/* U-Boot environment NAND üzerinde çift kopya */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x1C0000 /* mtd3 başlangıcı */
#define CONFIG_ENV_OFFSET_REDUND 0x1E0000 /* yedek kopya */
#define CONFIG_ENV_SIZE 0x20000 /* 128 KB */
#define CONFIG_ENV_RANGE 0x40000 /* toplam 256 KB = 2 erase block */
Bu bölümde
- Her partition boyutu erase block katı olmalı; hizalanmamış partition sorunlara yol açar
- %2 bad block rezervasyonu ve UBI iç overhead (≈20 PEB) hesaba katılmalı
- SPL ve U-Boot raw partition'da kalmalı; UBI sadece Linux'un kullandığı alanlarda
- U-Boot environment için çift kopya (
CONFIG_ENV_OFFSET_REDUND) önerilir
07 JFFS2 — eski alternatif
JFFS2 (Journalling Flash File System 2), UBI olmadan doğrudan MTD üzerinde çalışan eski bir flash dosya sistemidir; küçük NOR flash sistemlerde hâlâ kullanılabilir.
JFFS2 ne zaman tercih edilir
| Kriter | JFFS2 | UBIFS |
|---|---|---|
| Bağımlılık | Doğrudan MTD; UBI gerekmez | UBI katmanı zorunlu |
| Boyut | Küçük flash (<32 MB) için uygun | Büyük flash için optimize |
| Mount süresi | Yavaş (log scan); büyük flash'ta çok yavaş | Hızlı; log boyutu sınırlı |
| Wear leveling | Temel, log-structured yapıdan gelir | UBI aracılığıyla daha iyi |
| Bad block | Sınırlı destek | UBI tam bad block yönetimi |
| Sıkıştırma | ZLIB, RTIME, LZO | LZO, ZLIB, ZSTD |
| Tercih senaryosu | Küçük NOR, basit sistem, legacy | NAND, büyük rootfs, yeni tasarım |
mkfs.jffs2 ile image oluşturma
# rootfs dizininden JFFS2 image üret
# -r: kaynak dizin, -o: çıktı dosyası
# -e: erase block boyutu (NOR: 64KB, NAND: 128KB tipik)
# -p: image boyutunu erase block katına doldur
mkfs.jffs2 \
-r rootfs/ \
-o rootfs.jffs2 \
-e 0x10000 \
-p 0x2000000 \
--squash # root dışı dosyaları squash et (UID/GID normalize)
# LZO sıkıştırma ile
mkfs.jffs2 -r rootfs/ -o rootfs.jffs2 -e 0x10000 -l
# -l: little-endian (ARM için varsayılan)
# NAND için (128 KB erase block, no-cleanmarker)
mkfs.jffs2 -r rootfs/ -o rootfs.jffs2 -e 0x20000 \
-n # -n: cleanmarker yazma (NAND OOB kullanır, farklı yönetim)
-l
JFFS2 flash'a yazma ve mount
# NOR flash'a yaz
flash_erase --jffs2 /dev/mtd5 0 0 # clean marker yaz
flashcp -v rootfs.jffs2 /dev/mtd5
# NAND flash'a yaz
flash_erase /dev/mtd5 0 0
nandwrite -p /dev/mtd5 rootfs.jffs2
# Mount et
mount -t jffs2 /dev/mtdblock5 /mnt
# Kernel cmdline ile boot
# root=/dev/mtdblock5 rootfstype=jffs2
JFFS2 büyük flash partition'larında mount süresi dakikalar alabilir — başlangıçta tüm log yapısını taraması gerekir. 64 MB üzeri NAND flash için UBIFS kullanın; JFFS2'yi sadece küçük NOR partitionları veya legacy sistemler için tercih edin.
Bu bölümde
- JFFS2 küçük NOR flash veya legacy sistemler için uygun; büyük NAND'da UBIFS kullanın
mkfs.jffs2 -r rootfs/ -e 0x10000 -o rootfs.jffs2- JFFS2 mount süresi flash büyüklüğüyle orantılı olarak uzar
- Yeni tasarımlarda MTD → UBI → UBIFS zincirini tercih edin
08 Pratik: Yocto ile NAND image üretimi
Yocto Build System, UBIFS image üretimini ve ubinize ile UBI paketlenmesini yerleşik değişkenler aracılığıyla destekler.
IMAGE_FSTYPES ile flash image türleri
# UBIFS ve UBI image türlerini etkinleştir
IMAGE_FSTYPES += "ubifs ubi"
# mkfs.ubifs parametreleri
# -m: min I/O, -e: LEB size, -c: max LEB count
MKUBIFS_ARGS = "-m 2048 -e 126976 -c 2000"
# ubinize parametreleri
# -p: PEB size, -m: min I/O, -s: sub-page size
UBINIZE_ARGS = "-p 128KiB -m 2048 -s 512"
# Kullanılan makine (BSP layer'dan gelir)
MACHINE = "myboard"
Machine konfigürasyonunda NAND parametreleri
# NAND parametreleri — mkfs.ubifs ve ubinize için
MKUBIFS_ARGS = "-m 2048 -e 126976 -c 4096"
UBINIZE_ARGS = "-p 128KiB -m 2048 -s 512"
# Image türleri
IMAGE_FSTYPES = "ubifs ubi tar.gz"
# Kernel image türü
KERNEL_IMAGETYPE = "zImage"
# U-Boot yüklenecek binary
UBOOT_MACHINE = "myboard_defconfig"
UBOOT_SUFFIX = "img"
Yocto build ve çıktı dosyaları
# Ortamı hazırla
source oe-init-build-env build/
# Image build et
bitbake core-image-minimal
# Çıktılar:
ls tmp/deploy/images/myboard/
# core-image-minimal-myboard.ubifs — ham UBIFS image
# core-image-minimal-myboard.ubi — UBI paketlenmiş image
# zImage — kernel
# myboard.dtb — device tree blob
# u-boot.img — U-Boot binary
# MLO — SPL (TI AM335x)
Flash layout DTS binding — Yocto ile
# Kernel recipe'ye board DTS dosyasını ekle
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://myboard-nand-partitions.dts \
file://0001-add-myboard-nand-partitions.patch"
# U-Boot üzerinden TFTP ile kernel yükle ve flash et
# (U-Boot shell üzerinde)
# setenv serverip 192.168.1.100
# setenv ipaddr 192.168.1.200
# tftp 0x82000000 zImage
# nand erase.part kernel
# nand write 0x82000000 kernel $filesize
# Target üzerinde (Linux çalışırken) rootfs güncelle
ubiformat /dev/mtd5 -f core-image-minimal-myboard.ubi
ubiattach -m 5
mount -t ubifs ubi0:rootfs /mnt/newroot
Yocto MKUBIFS_ARGS ve UBINIZE_ARGS değerleri, hedef NAND flash'ın geometrisine tam uymalıdır. Yanlış -e (LEB size) veya -p (PEB size) değerleriyle üretilen image mount edilemez. Bu değerleri mtdinfo /dev/mtdN çıktısından alın.
Bu bölümde
IMAGE_FSTYPES += "ubifs ubi"veMKUBIFS_ARGS/UBINIZE_ARGSdeğişkenleri- Machine config'e NAND geometrisini girin;
mtdinfoçıktısından alın - Build çıktısı:
.ubifsham image,.ubiUBI paketlenmiş image ubiformat /dev/mtdN -f image.ubitek adımda hem format hem yaz