00 Buildroot nedir ve neden
Buildroot, tek bir make çağrısıyla cross-toolchain, Linux kernel, rootfs ve boot image'ı üretebilen Makefile tabanlı bir embedded Linux build sistemidir.
Buildroot ne yapar
Buildroot, GNU Make üzerine inşa edilmiş bir cross-compile orkestrasyon sistemidir. Toolchain seçimi, Linux kernel konfigürasyonu, rootfs içeriği ve bootloader entegrasyonunu tek bir menuconfig arayüzünden yönetir. Komple bir embedded Linux sistemi üretmek için yazılması gereken binlerce satır Makefile yerine, birkaç konfigürasyon seçeneği yeterlidir.
make menuconfig → .config → make -j$(nproc) → output/images/ (kernel + DTB + rootfs + image)
Yocto ile karşılaştırma
| Özellik | Buildroot | Yocto Project |
|---|---|---|
| Öğrenme eğrisi | Düz — Makefile, menuconfig bilmek yeterli | Dik — BitBake DSL, layer sistemi, recipe kavramı |
| İlk build süresi | 20–40 dakika | 1–2 saat (sstate-cache yoksa) |
| Incremental build | Sınırlı — toolchain değişirse full rebuild | Güçlü sstate-cache — yalnızca değişen task |
| Paket sayısı | ~2 000 paket | 5 000+ recipe |
| Çoklu board desteği | defconfig bazlı, basit | BSP layer + MACHINE değişkeni — güçlü |
| SDK üretimi | make sdk — temel düzeyde | Yerleşik, güçlü, eSDK dahil |
| Yapılandırma dosyası | .config — düz metin | local.conf + bblayers.conf |
| Ticari destek | Sınırlı, topluluk odaklı | Wind River, Mentor/Siemens, Timesys |
Ne zaman Buildroot tercih edilir
Desteklenen mimariler
| Mimari | Örnek hedefler | C library desteği |
|---|---|---|
| ARM (32-bit) | Cortex-A8/A9/A53, Cortex-M (MMU'suz) | glibc, musl, uClibc-ng |
| ARM64 (AArch64) | Cortex-A55/A72/A76, Raspberry Pi 4/5 | glibc, musl |
| MIPS | MIPS32, MIPS64, OpenWrt router SoC'ları | glibc, musl, uClibc-ng |
| RISC-V | rv32, rv64 — SiFive, StarFive, T-Head | glibc, musl |
| x86 / x86-64 | Intel Atom, AMD Embedded, QEMU | glibc, musl |
| PowerPC | e500, e5500 — NXP QorIQ SoC'ları | glibc, musl, uClibc-ng |
Buildroot dizin yapısı
| Dizin | İçerik |
|---|---|
board/ | Board-specific dosyalar: post-build script, overlay, kernel config, patches |
configs/ | Hazır defconfig'ler — make list-defconfigs ile listelenir |
dl/ | İndirilen kaynak tarball'ları — build'ler arası paylaşılabilir |
output/ | Build çıktıları: images/, host/, target/, build/, staging/ |
package/ | ~2000 paket tarifi — her paketin Config.in ve .mk dosyası burada |
toolchain/ | Internal toolchain build kuralları ve external toolchain wrapper'ları |
Bu bölümde
- Buildroot = GNU Make + menuconfig — tek komutla toolchain + kernel + rootfs + image
- İlk build 20–40 dakika; Yocto 1–2 saat — hızlı prototip için ideal
- ARM, ARM64, MIPS, RISC-V, x86, PowerPC mimarileri; glibc/musl/uClibc-ng seçeneği
- ~2000 paket, 220+ hazır defconfig, sade öğrenme eğrisi
01 İlk build: QEMU ARM
Buildroot'un klonlanmasından QEMU'da ilk boot'a kadar tüm adımlar — donanım gerekmeden çalışan bir ARM sistemi.
Ön gereksinimler
sudo apt-get install -y \
build-essential gcc g++ make unzip \
python3 file wget cpio rsync \
bc libncurses-dev libssl-dev \
qemu-system-arm
# Versiyon kontrolü
gcc --version # gcc 11+ önerilir
make --version # GNU Make 4.0+
python3 --version # Python 3.6+
Buildroot indirme
# Git ile belirli bir LTS sürümünü klonla
git clone https://git.buildroot.net/buildroot -b 2024.02.x buildroot
cd buildroot
# Alternatifl: tarball indirme
wget https://buildroot.org/downloads/buildroot-2024.02.tar.gz
tar xf buildroot-2024.02.tar.gz
# Hazır ARM QEMU konfigürasyonunu yükle
make qemu_arm_versatile_defconfig
# .config içeriğini doğrula
grep -E '^BR2_(ARCH|TOOLCHAIN_BUILDROOT_LIBC)=' .config
# BR2_ARCH="arm"
# BR2_TOOLCHAIN_BUILDROOT_LIBC="uclibc"
make menuconfig — temel gezinme
make menuconfig
# Navigasyon kısayolları:
# ↑↓ : seçenek gezinme
# ← → : alt menü Enter / Esc
# Space : toggle seçenek (y/n/m)
# / : arama (BR2_ değişken adı veya başlık)
# ? : seçenek hakkında yardım
# Esc Esc : bir üst menüye çıkış
# S (Save) : konfigürasyonu kaydet
Build ve çıktı analizi
# Tüm CPU çekirdeklerini kullan
make -j$(nproc) 2>&1 | tee build.log
# Build aşamaları (log'da görüntülenir):
# [1/5] Toolchain build (gcc 13 → arm-buildroot-linux-uclibcgnueabi-gcc)
# [2/5] Kernel headers
# [3/5] Target packages (busybox, dropbear, ...)
# [4/5] Linux kernel
# [5/5] Rootfs image
# Çıktıları incele
ls -lh output/images/
# rootfs.ext2 — ext2 formatında rootfs (~16 MB)
# zImage — ARM Linux kernel
# versatile-pb.dtb — ARM Versatile Platform Baseboard DTB
# start-qemu.sh — hazır QEMU başlatma scripti
QEMU ile boot
# Hazır script varsa kullan
./output/images/start-qemu.sh
# Manuel başlatma (eşdeğer komut)
qemu-system-arm \
-M versatilepb \
-kernel output/images/zImage \
-dtb output/images/versatile-pb.dtb \
-drive "file=output/images/rootfs.ext2,if=scsi,format=raw" \
-append "rootwait root=/dev/sda console=ttyAMA0,115200" \
-serial stdio \
-net nic,model=smc91c111 -net user \
-nographic
# Login: root (şifre yok — varsayılan)
# QEMU'dan çık: Ctrl+A, ardından X
İlk build sırasında Buildroot, toolchain dahil her şeyi sıfırdan derler — bu 20–40 dakika sürebilir. Sonraki build'lerde BR2_CCACHE=y etkinleştirilmişse aynı build yalnızca 2–5 dakika alır. Toolchain veya libc değiştirilmedikçe make clean gerekmez.
Bu bölümde
make qemu_arm_versatile_defconfig: 220+ hazır konfigürasyondan biri — ARM başlangıç noktasımake -j$(nproc): ilk build ~30 dakika; çıktılaroutput/images/altındaoutput/images/: zImage + versatile-pb.dtb + rootfs.ext2 + start-qemu.shqemu-system-arm -M versatilepb: gerçek donanım olmadan tam ARM Linux boot
02 menuconfig anatomy
menuconfig'in 8 ana kategorisi — Target options, Toolchain, Build options, System configuration, Kernel, Packages, Filesystem images, Bootloaders.
Target options
# Target Architecture seçenekleri
# BR2_arm=y → ARM 32-bit
# BR2_aarch64=y → ARM 64-bit (AArch64)
# BR2_riscv=y → RISC-V
# BR2_x86_64=y → x86-64
# ARM ABI seçimi (arm için)
# BR2_ARM_EABI=y → soft-float ABI
# BR2_ARM_EABIHF=y → hard-float ABI (Cortex-A için önerilir)
# CPU variant (performans optimizasyonu)
# BR2_cortex_a9=y → Cortex-A9 (-mcpu=cortex-a9)
# BR2_cortex_a53=y → Cortex-A53
# BR2_cortex_a72=y → Cortex-A72 (Raspberry Pi 4)
Toolchain kategorisi
| Seçenek | Açıklama | Ne zaman |
|---|---|---|
| Buildroot toolchain | gcc/binutils kaynak derlemesi | Tam kontrol, custom libc gerektiğinde |
| External toolchain | Linaro, ARM GNU, vendor binary toolchain | gcc derleme istemiyorsan, hızlı build için |
| glibc | GNU C Library — tam POSIX uyumu | Üretim sistemleri, geniş uygulama uyumluluğu |
| musl | Hafif C library (~600 KB) | Embedded, güvenlik odaklı, küçük rootfs |
| uClibc-ng | MMU'suz sistemler için | Cortex-M (MPU), bazı MIPS SoC'ları |
Build options
# Derleyici optimizasyonu
# BR2_OPTIMIZE_2=y → -O2 (varsayılan)
# BR2_OPTIMIZE_S=y → -Os (boyut öncelikli)
# BR2_OPTIMIZE_3=y → -O3 (performans öncelikli)
# Binary'leri strip et (debug sembollerini kaldır)
# BR2_STRIP_strip=y → rootfs boyutunu ~%30 düşürür
# Hata ayıklama sembolleri (strip ile çakışır)
# BR2_ENABLE_DEBUG=y → -g flag eklenir; strip devre dışı kalır
# ccache — compiler cache (tekrar build'leri hızlandırır)
# BR2_CCACHE=y
# BR2_CCACHE_DIR="/home/user/.buildroot-ccache"
System configuration
# Sistem hostname
BR2_TARGET_GENERIC_HOSTNAME="embedded"
# /etc/issue banner
BR2_TARGET_GENERIC_ISSUE="Welcome to Embedded Linux"
# Timezone
BR2_TARGET_TZ_INFO=y
BR2_TARGET_LOCALTIME="Europe/Istanbul"
# Init sistemi seçimi
# BR2_INIT_BUSYBOX=y → BusyBox init (sysvinit benzeri, hafif)
# BR2_INIT_SYSTEMD=y → systemd (daha büyük, geniş özellik)
# BR2_INIT_SYSV=y → sysvinit (klasik /etc/init.d)
# Root şifre (SHA256 hash)
BR2_TARGET_GENERIC_PASSWD_METHOD_SHA256=y
BR2_TARGET_GENERIC_ROOT_PASSWD="mypassword"
# Getty (seri konsol login)
BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200=y
Kernel ve Filesystem images
# Kernel versiyonu
# BR2_LINUX_KERNEL_LATEST_VERSION=y → en yeni stable
# BR2_LINUX_KERNEL_CUSTOM_VERSION=y → belirli sürüm
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.6.21"
# Kernel defconfig
BR2_LINUX_KERNEL_DEFCONFIG="versatile"
# ya da board dizinindeki özel config
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/myboard/linux.config"
# Rootfs formatları (birden fazla seçilebilir)
# BR2_TARGET_ROOTFS_EXT2=y → ext2 (SD kart, eMMC)
# BR2_TARGET_ROOTFS_SQUASHFS=y → squashfs read-only (NOR flash)
# BR2_TARGET_ROOTFS_CPIO=y → initramfs (RAM boot)
# BR2_TARGET_ROOTFS_TAR=y → tarball (NFS root, Docker)
Toolchain veya C library değiştirildiğinde tüm build geçersiz olur. make clean komutuyla output/ dizinini temizleyin ve yeniden build edin. Yalnızca paket veya kernel konfigürasyonu değiştiyse make clean gerekmez — Buildroot etkilenen paketleri otomatik yeniden derler.
Bu bölümde
- Target options: mimari + ABI + CPU variant — cross-compiler flag'lerini belirler
- Toolchain: internal (gcc kaynak) vs external (Linaro binary) + libc seçimi
- System configuration: hostname, init sistemi, timezone, root şifre
- Filesystem images: ext2/ext4, squashfs, cpio, tar — birden fazla aynı anda seçilebilir
03 Package ekleme
Buildroot'un ~2000 paketini menuconfig'den seçmek veya .config'te BR2_PACKAGE_XXX=y ile etkinleştirmek yeterlidir.
Package seçim yöntemleri
# Yöntem 1: menuconfig ile interaktif seçim
make menuconfig
# → Target packages → Networking applications → [*] openssh
# → Target packages → Networking applications → [*] dropbear
# → Target packages → Interpreter languages → [*] python3
# → Target packages → System tools → [*] htop
# Yöntem 2: .config'i doğrudan düzenle
echo 'BR2_PACKAGE_OPENSSH=y' >> .config
echo 'BR2_PACKAGE_DROPBEAR=y' >> .config
make olddefconfig # bağımlılıkları çöz
# Yöntem 3: paket arama
make menuconfig
# '/' tuşuna basın → 'libcurl' yazın → sonucu bulun
Örnek: libcurl, openssh, python3 + modüller
# libcurl — HTTP/HTTPS client library
BR2_PACKAGE_LIBCURL=y
BR2_PACKAGE_LIBCURL_OPENSSL=y # HTTPS için SSL backend
# OpenSSH — tam SSH server + client
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_OPENSSH_SERVER=y
BR2_PACKAGE_OPENSSH_CLIENT=y
# Python3 + minimal pip modülleri
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_PIP=y
BR2_PACKAGE_PYTHON_REQUESTS=y
BR2_PACKAGE_PYTHON_PAHO_MQTT=y
# Mosquitto MQTT broker
BR2_PACKAGE_MOSQUITTO=y
BR2_PACKAGE_MOSQUITTO_BROKER=y
Tek paket rebuild komutları
# Örnek: mosquitto paketini yeniden build et
make mosquitto-dirclean
make mosquitto
# Host tool'u rebuild et (cross-compile araçları)
make host-dtc-rebuild # device tree compiler
# Paket bağımlılıklarını görselleştir
make mosquitto-graph-depends
dot -Tsvg output/graphs/graph-depends.dot -o mosquitto-deps.svg
Host package: BR2_PACKAGE_HOST_XXX
# Host package: build host üzerinde çalışır (cross-compile araçları)
# Target package: rootfs'e dahil edilir
# Örnek: genimage — SD kart image üretimi (host'ta çalışır)
BR2_PACKAGE_HOST_GENIMAGE=y
# device tree compiler — host'ta dtc binary
BR2_PACKAGE_HOST_DTC=y
# mtools — FAT image manipülasyonu (host)
BR2_PACKAGE_HOST_MTOOLS=y
# Host binary konumu
ls output/host/bin/
# arm-buildroot-linux-gnueabihf-gcc
# dtc
# genimage
# mtools
Package bağımlılıkları Config.in içinde select ve depends on direktifleriyle tanımlanır. select ile işaretlenen bağımlılıklar otomatik seçilir; depends on ise ilgili seçenek etkinleştirilmeden paketin seçilmesini engeller. menuconfig'de gri görünen paketler genellikle karşılanmamış bir depends on koşuluna sahiptir — ? tuşuyla detay görüntüleyin.
Bu bölümde
BR2_PACKAGE_XXX=ysatırı .config'e eklenmesi veya menuconfig seçimi yeterli- libcurl + openssl, openssh, python3 + paho-mqtt, mosquitto broker ekleme örnekleri
make <pkg>-dirclean && make <pkg>: tek paket temiz rebuild- Host package: build host'ta çalışan araçlar — genimage, dtc, mtools
04 Custom package yazmak
Kendi uygulamanızı Buildroot'a entegre etmek iki dosya gerektirir: Config.in (menuconfig girişi) ve .mk (build kuralları).
Package dizin yapısı
mkdir -p package/my-app
# Gerekli dosyalar:
# package/my-app/Config.in → menuconfig girişi
# package/my-app/my-app.mk → build kuralları
# Ana Config.in'e kaynak ekle (bir kerelik)
grep -n 'endmenu' package/Config.in | tail -1
# Uygun endmenu'dan önce source satırı ekle:
# source "package/my-app/Config.in"
Config.in — Kconfig snippet
config BR2_PACKAGE_MY_APP
bool "my-app"
depends on BR2_USE_MMU # MMU gerektiriyor
depends on BR2_TOOLCHAIN_HAS_THREADS
select BR2_PACKAGE_LIBCURL # otomatik seç
select BR2_PACKAGE_OPENSSL
help
Minimal IoT daemon — HTTP REST API + MQTT publish.
https://github.com/myorg/my-app
my-app.mk — generic-package
################################################################################
# my-app — IoT daemon (generic package)
################################################################################
MY_APP_VERSION = 1.3.0
MY_APP_SITE = https://github.com/myorg/my-app/archive/refs/tags
MY_APP_SOURCE = v$(MY_APP_VERSION).tar.gz
MY_APP_DEPENDENCIES = libcurl openssl
MY_APP_LICENSE = MIT
MY_APP_LICENSE_FILES = LICENSE
define MY_APP_BUILD_CMDS
$(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
-C $(@D)
endef
define MY_APP_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/my-app \
$(TARGET_DIR)/usr/bin/my-app
$(INSTALL) -D -m 0644 $(@D)/config/default.conf \
$(TARGET_DIR)/etc/my-app/my-app.conf
endef
$(eval $(call generic-package))
cmake-package örneği
MY_APP_VERSION = 2.0.0
MY_APP_SITE = https://github.com/myorg/my-app/archive/v$(MY_APP_VERSION).tar.gz
MY_APP_LICENSE = Apache-2.0
# CMake konfigürasyon seçenekleri (-DXXX=YYY)
MY_APP_CONF_OPTS = \
-DBUILD_TESTS=OFF \
-DBUILD_DOCS=OFF \
-DENABLE_MQTT=ON \
-DENABLE_TLS=ON
# cmake configure + ninja build + install otomatik çalışır
$(eval $(call cmake-package))
Local source override ile geliştirme
# Tarball indirmek yerine yerel kaynak dizini kullan
# Geliştirme aşamasında her değişiklikte hız kazandırır
# local.mk dosyasına ekle (Buildroot kök dizinine):
echo 'MY_APP_OVERRIDE_SRCDIR = /home/user/src/my-app' >> local.mk
# Build et (tarball indirilmez, yerel dizin kullanılır)
make my-app-rebuild
# Kaynak değişikliği → direkt rebuild (indirme yok)
make my-app-rebuild # ~5-10 saniye
# Override'ı kaldır (release build için)
sed -i '/MY_APP_OVERRIDE/d' local.mk
Gerçek örnek: basit C daemon
/* hello-daemon: syslog'a mesaj yazan minimal daemon */
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
#include <signal.h>
static volatile int running = 1;
void sig_handler(int sig) { running = 0; }
int main(void) {
openlog("hello-daemon", LOG_PID, LOG_DAEMON);
signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler);
syslog(LOG_INFO, "started");
while (running) {
syslog(LOG_INFO, "heartbeat");
sleep(10);
}
syslog(LOG_INFO, "stopped");
closelog();
return 0;
}
generic-package, autotools-package, cmake-package makrolarının farkı: generic-package'ta BUILD_CMDS ve INSTALL_TARGET_CMDS adımlarını kendiniz yazarsınız. autotools-package ise ./configure --host=TARGET + make + make install adımlarını otomatik yönetir. cmake-package de benzer şekilde cmake -DCMAKE_TOOLCHAIN_FILE=... + ninja + ninja install sırasını çalıştırır. Özel ek argümanlar için sırasıyla PKGNAME_CONF_OPTS veya PKGNAME_CONF_OPTS değişkeni kullanılır.
Bu bölümde
Config.in: menuconfig girişi —BR2_PACKAGE_MY_APP, depends on, select, helpmy-app.mk: MY_APP_VERSION, MY_APP_SITE, BUILD_CMDS, INSTALL_TARGET_CMDScmake-package: CMake projeler için — CONF_OPTS ile -D argümanlarıMY_APP_OVERRIDE_SRCDIR: local.mk'ya ekle → tarball indirilmeden yerel kaynak kullan
05 Board support (custom hardware)
board/ dizini board-specific her şeyi merkezi tutar: kernel config, post-build script, overlay, U-Boot config ve genimage için partition şablonu.
board/ dizin yapısı
| Dosya / Dizin | Amaç |
|---|---|
board/myvendor/myboard/ | Board'a özel tüm dosyalar |
board/myvendor/myboard/linux.config | Kernel defconfig — make linux-update-defconfig ile güncellenir |
board/myvendor/myboard/uboot.config | U-Boot defconfig |
board/myvendor/myboard/patches/linux/ | Kernel kaynak yamalar (.patch dosyaları) |
board/myvendor/myboard/rootfs-overlay/ | Rootfs overlay dizini — target'a doğrudan kopyalanır |
board/myvendor/myboard/post-build.sh | Rootfs hazırlandıktan sonra çalışır — dinamik değişiklikler |
board/myvendor/myboard/post-image.sh | Image oluşturulduktan sonra — genimage, U-Boot + kernel birleştirme |
board/myvendor/myboard/genimage.cfg | SD kart partition tablosu şablonu |
configs/myboard_defconfig | Tam board konfigürasyonu — make savedefconfig ile üretilir |
linux.config — kernel defconfig override
# .config'te board'a özel linux.config belirt
# BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
# BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/myvendor/myboard/linux.config"
# Kernel menuconfig ile değişiklik yap
make linux-menuconfig
# Değişiklikleri board dizinine kaydet
make linux-update-defconfig
# → board/myvendor/myboard/linux.config güncellenir
# Kernel yamalarını uygulama
# board/myvendor/myboard/patches/linux/ dizinindeki .patch dosyaları
# Buildroot otomatik uygular: BR2_GLOBAL_PATCH_DIR kullanılarak
BR2_GLOBAL_PATCH_DIR="board/myvendor/myboard/patches"
post-build.sh — rootfs modifikasyonu
#!/bin/bash
# Buildroot: post-build.sh çağrılır sonra image üretilir
# Argüman: $1 = TARGET_DIR (output/target/)
set -e
TARGET_DIR="$1"
# Hostname ayarla
echo "myboard-v2" > "${TARGET_DIR}/etc/hostname"
# Build bilgisini rootfs'e göm
cat > "${TARGET_DIR}/etc/build-info" <<EOF
BUILD_DATE=$(date +%Y-%m-%dT%H:%M:%S)
BUILD_HOST=$(hostname)
GIT_HASH=$(git -C "${BR2_EXTERNAL_MYPROJECT_PATH}" rev-parse --short HEAD 2>/dev/null || echo unknown)
BUILDROOT_VERSION=$(git -C "$(dirname "$0")/../../../" describe --tags 2>/dev/null || echo unknown)
EOF
# Gereksiz dosyaları sil (rootfs boyutunu düşür)
rm -rf "${TARGET_DIR}/usr/share/doc"
rm -rf "${TARGET_DIR}/usr/share/man"
rm -f "${TARGET_DIR}/usr/bin/perl"
post-image.sh — SD kart image
#!/bin/bash
# post-image.sh: image oluşturulduktan sonra SD kart image yap
# Değişkenler: BINARIES_DIR, HOST_DIR, BUILD_DIR, BR2_EXTERNAL
set -e
GENIMAGE_CFG="${BR2_EXTERNAL_MYPROJECT_PATH}/board/myvendor/myboard/genimage.cfg"
# genimage aracıyla partition tablosu oluştur
"${HOST_DIR}/bin/genimage" \
--config "${GENIMAGE_CFG}" \
--rootpath "${TARGET_DIR}" \
--tmppath "${BUILD_DIR}/genimage.tmp" \
--inputpath "${BINARIES_DIR}" \
--outputpath "${BINARIES_DIR}"
genimage.cfg — SD kart partition şablonu
image boot.vfat {
vfat {
files = {
"zImage",
"myboard.dtb",
"u-boot.bin"
}
}
size = 32M
}
image sdcard.img {
hdimage {}
partition boot {
partition-type = 0xC # FAT32
bootable = "true"
image = "boot.vfat"
}
partition rootfs {
partition-type = 0x83 # Linux
image = "rootfs.ext4"
}
}
Bu bölümde
board/myvendor/myboard/: linux.config, patches, overlay, post-*.sh tek dizindemake linux-update-defconfig: kernel menuconfig değişikliklerini board dizinine kaydetpost-build.sh: hostname, build tarihi, gereksiz dosya silme — image öncesi hookgenimage.cfg+post-image.sh: boot + rootfs partition'larını tek sdcard.img'e birleştir
06 Rootfs kişiselleştirme
Rootfs overlay, post-build script, kullanıcı tablosu ve device table — paket yazmadan rootfs'i şekillendirmenin dört yolu.
BR2_ROOTFS_OVERLAY — dosya sistemi overlay
# Overlay dizin yapısını oluştur
mkdir -p board/myvendor/myboard/rootfs-overlay/etc/init.d
mkdir -p board/myvendor/myboard/rootfs-overlay/etc/my-app
mkdir -p board/myvendor/myboard/rootfs-overlay/usr/bin
# .config'te overlay dizinini belirt
# BR2_ROOTFS_OVERLAY="board/myvendor/myboard/rootfs-overlay"
# Birden fazla dizin (boşlukla ayır):
# BR2_ROOTFS_OVERLAY="board/common/overlay board/myvendor/myboard/rootfs-overlay"
| Overlay dosyası | Cihazda hedef | Amaç |
|---|---|---|
etc/init.d/S99my-app | /etc/init.d/S99my-app | BusyBox SysV init başlatma scripti |
etc/my-app/config.yaml | /etc/my-app/config.yaml | Uygulama konfigürasyonu |
etc/network/interfaces | /etc/network/interfaces | Statik IP / DHCP ağ ayarları |
etc/inittab | /etc/inittab | BusyBox init konfigürasyonu override |
usr/bin/health-check.sh | /usr/bin/health-check.sh | Script dosyaları, yardımcı araçlar |
BusyBox init scripti — /etc/init.d/S99my-app
#!/bin/sh
# S99my-app: BusyBox SysV init başlatma scripti
# 'S' prefix'i = start; sayı = sıra (99 = en son)
DAEMON=/usr/bin/my-app
PIDFILE=/var/run/my-app.pid
CFGFILE=/etc/my-app/config.yaml
case "$1" in
start)
printf "Starting my-app... "
start-stop-daemon -S -b -m -p $PIDFILE \
-x $DAEMON -- --config $CFGFILE
echo "OK"
;;
stop)
printf "Stopping my-app... "
start-stop-daemon -K -p $PIDFILE
echo "OK"
;;
restart)
"$0" stop; sleep 1; "$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
users.table — servis kullanıcısı
# Format: username uid group gid password home shell groups comment
# uid/gid = -1 → otomatik atama
# password = ! → login yasak (servis hesabı)
myapp -1 myapp -1 ! /var/lib/myapp /bin/false - "myapp service user"
# .config'te tabloyu belirt:
# BR2_ROOTFS_USERS_TABLES="board/myvendor/myboard/users.table"
device_table.txt — özel cihaz dosyaları
# Format: path type mode uid gid major minor start inc count
# type: f=dosya, d=dizin, c=char device, b=block device, l=symlink
# Özel karakter cihazı (örn: custom FPGA driver)
/dev/fpga0 c 0660 0 myapp 240 0 0 0 -
# /var/log dizini oluştur
/var/log d 0755 0 0 - - - - -
/var/run d 0755 0 0 - - - - -
# .config'te belirt:
# BR2_ROOTFS_DEVICE_TABLE="board/myvendor/myboard/device_table.txt"
Şifre hashing
# SHA256 hash ile şifre (güvenli)
BR2_TARGET_GENERIC_PASSWD_METHOD_SHA256=y
BR2_TARGET_GENERIC_ROOT_PASSWD="mysecretpassword"
# MD5 (eski sistemler, önerilmez)
# BR2_TARGET_GENERIC_PASSWD_METHOD_MD5=y
# Şifresiz root (geliştirme ortamı için)
# BR2_TARGET_GENERIC_ROOT_PASSWD=""
# Üretimde şifreyi build sistemi değişkeni üzerinden ver
# export BR2_TARGET_GENERIC_ROOT_PASSWD="$(cat /etc/secrets/rootpw)"
Bu bölümde
- Rootfs overlay:
board/*/rootfs-overlay/→ doğrudan/üzerine kopyalanır BR2_ROOTFS_POST_BUILD_SCRIPT: hostname, build tarihi gibi dinamik değişiklikler içinusers.table: servis kullanıcısı oluştur;device_table.txt: özel cihaz node'larıBR2_TARGET_GENERIC_PASSWD_METHOD_SHA256: root şifresi güvenli hash ile saklanır
07 External toolchain kullanımı
Linaro, ARM GNU veya vendor SDK gibi hazır toolchain'leri Buildroot'a entegre ederek gcc derleme adımını tamamen atlayabilirsiniz.
Ne zaman external toolchain
menuconfig — external toolchain yapılandırması
# External toolchain (pre-built binary)
BR2_TOOLCHAIN_EXTERNAL=y
# Önceden tanımlı toolchain seçimi
# menuconfig → Toolchain → Toolchain → ARM AArch64 2023.06 (Linaro)
BR2_TOOLCHAIN_EXTERNAL_LINARO_AARCH64=y
# ya da ARM32 hard-float Linaro
BR2_TOOLCHAIN_EXTERNAL_LINARO_ARMHF=y
# ya da ARM GNU (arm.com toolchain)
BR2_TOOLCHAIN_EXTERNAL_ARM_AARCH64=y
# Buildroot tanımadığı 3rd-party toolchain için:
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
BR2_TOOLCHAIN_EXTERNAL_PATH="/opt/vendor-sdk/arm-linux-gnueabihf"
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arm-linux-gnueabihf"
Custom external toolchain — tam yapılandırma
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
# Toolchain binary'lerinin konumu
BR2_TOOLCHAIN_EXTERNAL_PATH="/opt/vendor-sdk/gcc-arm-11.2"
# Prefix: arm-none-linux-gnueabihf-, arm-linux-gnueabihf- vb.
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arm-none-linux-gnueabihf"
# C library tipi (toolchain ile eşleşmeli)
BR2_TOOLCHAIN_EXTERNAL_GLIBC=y
# Kernel headers versiyonu (toolchain ile eşleşmeli)
BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_15=y
# C++ desteği varsa
BR2_TOOLCHAIN_EXTERNAL_CXX=y
Doğrulama
# Build sonrası toolchain wrapper'ları kontrol et
ls output/host/bin/ | grep -E '(gcc|g\+\+|ld|ar)$'
# arm-buildroot-linux-gnueabihf-gcc
# arm-buildroot-linux-gnueabihf-g++
# arm-buildroot-linux-gnueabihf-ld
# Versiyon ve target tuple
output/host/bin/arm-buildroot-linux-gnueabihf-gcc --version
# arm-buildroot-linux-gnueabihf-gcc (Linaro GCC 12.3) 12.3.1
# Sysroot konumu
output/host/bin/arm-buildroot-linux-gnueabihf-gcc -print-sysroot
# output/host/arm-buildroot-linux-gnueabihf/sysroot
# Test: basit cross-compile
output/host/bin/arm-buildroot-linux-gnueabihf-gcc \
-o /tmp/hello_arm hello.c
file /tmp/hello_arm
# ELF 32-bit LSB executable, ARM, EABI5
Sysroot ve soname bağımlılıkları
# Target binary'nin kütüphane bağımlılıklarını listele
output/host/bin/arm-buildroot-linux-gnueabihf-readelf \
-d output/target/usr/bin/my-app | grep 'NEEDED'
# 0x00000001 (NEEDED) libcurl.so.4
# 0x00000001 (NEEDED) libssl.so.3
# 0x00000001 (NEEDED) libc.so.6
# Rootfs'te kütüphane var mı?
ls output/target/usr/lib/libcurl.so*
# Eksikse: menuconfig → Libraries → libcurl seç
Bu bölümde
BR2_TOOLCHAIN_EXTERNAL=y: Linaro, ARM GNU, vendor SDK entegrasyonuBR2_TOOLCHAIN_EXTERNAL_PATH: 3rd-party toolchain dizini;CUSTOM_PREFIX: tuple adıoutput/host/bin/: Buildroot wrapper scriptleri — cross-compile ortamını hazırlarreadelf -d: NEEDED kütüphanelerin rootfs'te bulunduğunu doğrula
08 Build hızlandırma
BR2_DL_DIR, BR2_CCACHE ve incremental rebuild stratejileri — günlük geliştirme döngüsünü hızlandıran teknikler.
BR2_DL_DIR — download cache
# Birden fazla Buildroot projesi için ortak indirme dizini
# Her proje ayrı build dir, aynı dl/ paylaşır
mkdir -p /data/buildroot-dl
# .config'te veya komut satırında belirt
make BR2_DL_DIR=/data/buildroot-dl -j$(nproc)
# Kalıcı ayar için .bashrc veya CI environment:
export BR2_DL_DIR=/data/buildroot-dl
# Avantaj: 5+ projeniz varsa & linux kernel (~100 MB)
# yalnızca bir kez indirilir
# Toplam dl/ boyutunu kontrol et
du -sh /data/buildroot-dl
# Tipik: 3–10 GB (tüm proje kaynak tarball'ları)
BR2_CCACHE — compiler cache
# menuconfig → Build options → Enable compiler cache
BR2_CCACHE=y
BR2_CCACHE_DIR="/home/user/.buildroot-ccache"
# ccache istatistikleri (build sonrası)
ccache -s
# cache directory: /home/user/.buildroot-ccache
# cache hit (direct): 1234
# cache hit (preprocessed): 89
# cache miss: 456
# cache size: 2.4 GB
# İlk build: ~30 dakika (cache dolu değil)
# İkinci tam build: ~4-8 dakika (cache hit rate %70-90)
# Yalnızca paket değişikliği: ~1-2 dakika
Paralel build ve jlevel
# Otomatik: mevcut CPU sayısını kullan
make -j$(nproc)
# .config'te sabit değer ayarla
# BR2_JLEVEL=8 → make -j8 anlamında
BR2_JLEVEL=0 # 0 = nproc otomatik (önerilir)
# Belirli paket için paralel seviye kısıtla
# (bellek yiyen paketler için — örn. GCC kendisi)
BR2_JLEVEL_PACKAGES_PARALLELISM=4
make graph-depends ve graph-build
# Tüm paket bağımlılık grafiği
make graph-depends
dot -Tsvg output/graphs/graph-depends.dot -o deps.svg
# Büyük projeler için xdot veya graphviz kullanın
# Tek paket bağımlılık grafiği
make python3-graph-depends
# Build süresi analizi (her paketin build süresi)
make graph-build
# output/graphs/graph-build.* dosyaları oluşur
# En uzun süren paketleri gösterir → toolchain, GCC, Qt5 genellikle başta
# Lisans bilgisi raporu
make legal-info
ls output/legal-info/
# manifest.csv — tüm paket lisansları
# licenses/ — lisans metinleri
# sources/ — GPL gerektiren kaynak kopyaları
Incremental rebuild stratejisi
| Değişiklik türü | Gerekli komut | Süre |
|---|---|---|
| Tek paket kaynak değişikliği | make <pkg>-rebuild | Saniyeler–dakikalar |
| Yeni paket eklendi | make | Yeni paket + bağımlılıklar |
| Kernel konfigürasyonu değişti | make linux-rebuild | 5–15 dakika |
| Toolchain versiyonu değişti | make clean && make | Tam rebuild (~30 dk) |
| C library değişti (glibc→musl) | make clean && make | Tam rebuild (~30 dk) |
| Sadece overlay dosyası değişti | make | <1 dakika |
Toolchain veya C library değiştirildiğinde make clean zorunludur. Bu komut output/ dizinini tamamen siler (dl/ hariç). make distclean ise .config dahil her şeyi temizler — dikkatli kullanın. Yalnızca paket veya kernel konfigürasyonu değiştiyse make clean gerekmez; Buildroot ilgili paketleri yeniden derler.
Bu bölümde
BR2_DL_DIR: birden fazla proje için ortak indirme cache — disk tasarrufuBR2_CCACHE=y: 2–5x hızlanma — her projede açık tutunmake graph-build: hangi paket en uzun sürdü — bottleneck analizi- Toolchain/libc değişikliği →
make clean; paket değişikliği → sadecemake <pkg>-rebuild
09 Pratik: minimal IoT image
Hedef: ARM Cortex-A8, 16 MB rootfs, musl libc, MQTT destekli — gerçek bir endüstriyel IoT cihazının konfigürasyon seti.
Hedef gereksinimleri
Konfigürasyon seçimleri
# Target: ARM Cortex-A8 hard-float
BR2_arm=y
BR2_cortex_a8=y
BR2_ARM_EABIHF=y
BR2_ARM_FPU_NEON=y
# External toolchain (hızlı build için)
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_LINARO_ARMHF=y
# musl libc — küçük, güvenli
BR2_TOOLCHAIN_BUILDROOT_LIBC="musl"
# Build optimizasyonu
BR2_OPTIMIZE_S=y # -Os: boyut öncelikli
BR2_STRIP_strip=y # debug sembolleri kaldır
BR2_CCACHE=y
# Sistem konfigürasyonu
BR2_TARGET_GENERIC_HOSTNAME="iot-device"
BR2_INIT_BUSYBOX=y # hafif init
BR2_TARGET_GENERIC_PASSWD_METHOD_SHA256=y
# Paketler
BR2_PACKAGE_BUSYBOX=y
BR2_PACKAGE_DROPBEAR=y # ~350 KB — openssh'den küçük
BR2_PACKAGE_MOSQUITTO=y
BR2_PACKAGE_MOSQUITTO_BROKER=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON3_PY_ONLY=y # .pyc derlemesini atla → küçük
BR2_PACKAGE_PYTHON_PAHO_MQTT=y
# Kernel
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.6.21"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/iot/linux-minimal.config"
# Squashfs read-only rootfs
BR2_TARGET_ROOTFS_SQUASHFS=y
BR2_TARGET_ROOTFS_SQUASHFS_LZMA=y # iyi sıkıştırma, hızlı açma
Kernel minimal config — sadece gerekli sürücüler
# Genel
CONFIG_LOCALVERSION="-iot"
CONFIG_EXPERT=y
CONFIG_EMBEDDED=y
# Gereksiz özellikleri devre dışı bırak
# CONFIG_STAGING is not set
# CONFIG_HAMRADIO is not set
# CONFIG_ISDN is not set
# CONFIG_INPUT_KEYBOARD is not set (headless cihaz)
# Gerekli ağ desteği
CONFIG_NET=y
CONFIG_INET=y
CONFIG_TCP_CONG_CUBIC=y
# CONFIG_IPV6 is not set (gerekli değilse)
# eMMC sürücüsü
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_OMAP=y
# Ethernet
CONFIG_NET_VENDOR_TI=y
CONFIG_TI_CPSW=y
# Squashfs desteği (rootfs için)
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZO=y
Toplam boyut ve boot süresi
| Bileşen | Boyut (squashfs) | Boyut (ext4) |
|---|---|---|
| BusyBox (musl statik) | ~580 KB | ~900 KB |
| dropbear SSH | ~320 KB | ~520 KB |
| mosquitto broker | ~180 KB | ~280 KB |
| python3 (minimal) | ~5.2 MB | ~8.5 MB |
| paho-mqtt modülü | ~120 KB | ~200 KB |
| musl libc | ~410 KB | ~620 KB |
| Diğer (/etc, /dev vb.) | ~200 KB | ~300 KB |
| Toplam rootfs | ~7 MB | ~11 MB |
Deployment: eMMC yazma
# Build
make iot-cortex-a8_defconfig
make -j$(nproc)
# Çıktıları kontrol et
ls -lh output/images/
# sdcard.img — genimage tarafından üretilen tam image
# zImage — Linux kernel
# am335x-iot.dtb — device tree
# rootfs.squashfs — ~7 MB sıkıştırılmış rootfs
# SD kart / eMMC'ye yaz
sudo dd if=output/images/sdcard.img of=/dev/mmcblk0 \
bs=4M status=progress conv=fsync
sudo sync
# OTA update için squashfs'i doğrudan yaz (sadece rootfs)
sudo dd if=output/images/rootfs.squashfs \
of=/dev/mmcblk0p2 bs=1M status=progress
sudo sync
Squashfs read-only rootfs kullandığınızda uygulama verisi için ayrı bir ext4 partition gereklidir. /var, /tmp, /etc/my-app/ gibi yazılabilir konumları bu partition'a veya tmpfs'e (mount -t tmpfs tmpfs /tmp) bağlayın. Bu yapı OTA güncellemelerini basitleştirir: rootfs partition'ını atomik olarak değiştirebilirsiniz.
Bu bölümde
- ARM Cortex-A8 + musl + -Os + strip → squashfs ~7 MB rootfs
- dropbear (SSH) + mosquitto (MQTT) + python3-minimal — IoT temel stack
- Minimal kernel config: gereksiz sürücüleri kapat → kernel boyutu ve boot süresi düşer
- Squashfs read-only rootfs: OTA güncellemesi için partition atomik değiştirilir