U-Boot¶
U-Boot (Das U-Boot) là bootloader de facto trên embedded Linux, hỗ trợ ARM, ARM64, RISC-V, MIPS, PowerPC, x86. Vị trí của U-Boot trong chuỗi boot (sau Boot ROM và SPL/FSBL, trước kernel) xem tại Bootloader trong hệ nhúng Linux. Phần riêng của Zynq (FSBL, BOOT.BIN, bootgen) xem tại U-Boot on Zynq.
Source tree và build¶
U-Boot dùng Kconfig và Kbuild giống Linux kernel, nên quy trình build quen thuộc:
git clone https://source.denx.de/u-boot/u-boot.git # mainline
cd u-boot
export CROSS_COMPILE=arm-linux-gnueabihf- # aarch64-linux-gnu- cho ARM64
make <board>_defconfig # ví dụ: xilinx_zynq_virt_defconfig
make menuconfig # tùy chọn: chỉnh cấu hình
make -j$(nproc)
Vendor thường giữ một fork riêng, ví dụ u-boot-xlnx của Xilinx/AMD hay uboot-imx của NXP. Fork có hỗ trợ phần cứng sớm hơn, mainline thì có bản vá bảo mật và tính năng mới.
Các thư mục quan trọng:
| Thư mục | Nội dung |
|---|---|
configs/ |
Các file *_defconfig cho từng board |
board/<vendor>/<board>/ |
Code khởi tạo riêng cho board |
arch/<arch>/ |
Code theo kiến trúc và SoC (arch/arm/mach-zynq/, arch/arm/mach-imx/) |
arch/<arch>/dts/ |
Device tree U-Boot dùng cho chính nó |
drivers/ |
Driver theo Driver Model (DM) |
cmd/ |
Các lệnh của U-Boot shell |
include/configs/<board>.h |
Cấu hình legacy dạng macro, đang được chuyển dần sang Kconfig |
tools/ |
Công cụ chạy trên host: mkimage, fw_printenv... |
File output thường gặp:
| File | Ý nghĩa |
|---|---|
u-boot |
ELF, có symbol, dùng để debug bằng GDB/JTAG |
u-boot.elf |
ELF dùng để đóng gói (bootgen trên Xilinx) |
u-boot.bin |
Raw binary |
u-boot.img |
u-boot.bin có header legacy để SPL nạp |
spl/u-boot-spl.bin |
SPL raw binary |
u-boot.itb |
FIT image chứa U-Boot (và ATF, DTB) cho SPL nạp, hay gặp trên ARM64 |
Driver Model và device tree trong U-Boot¶
U-Boot hiện đại dùng Driver Model (DM) và đọc device tree để biết phần cứng (CONFIG_OF_CONTROL), giống cách Linux probe driver. Lưu ý:
- DTB của U-Boot và DTB truyền cho kernel có thể là hai file khác nhau. U-Boot có các node riêng như
u-boot,dm-pre-relochoặcbootph-all(đánh dấu node cần dùng trong SPL hoặc trước relocation), thường đặt trong file*-u-boot.dtsi. CONFIG_OF_SEPARATE: DTB được nối vào cuốiu-boot.bin(u-boot-dtb.bin).CONFIG_OF_EMBED: DTB nhúng vào ELF, chỉ khuyến nghị cho debug.- U-Boot có thể sửa DTB của kernel trước khi boot (fixup): thêm node
memorytheo dung lượng DRAM thực, ghibootargsvào/chosen, thêm MAC address cho Ethernet.
Relocation¶
U-Boot proper thường được nạp vào một địa chỉ trong DRAM (CONFIG_TEXT_BASE), sau khi khởi tạo xong DRAM nó tự copy (relocate) bản thân lên vùng cuối của DRAM để giải phóng vùng thấp cho kernel. Khi debug bằng GDB sau relocation, cần nạp lại symbol với offset mới (xem gd->relocaddr, lệnh bdinfo in ra relocaddr).
Environment¶
Environment là tập biến dạng key=value điều khiển hành vi của U-Boot. Environment mặc định được build vào binary, có thể lưu vào flash, eMMC, file FAT (uboot.env) để giữ thay đổi.
| Biến | Ý nghĩa |
|---|---|
bootcmd |
Lệnh chạy tự động khi hết bootdelay |
bootdelay |
Số giây chờ người dùng bấm phím để vào shell. -1 tắt autoboot, 0 boot ngay (vẫn có thể ngắt nếu cấu hình) |
bootargs |
Command line truyền cho kernel |
loadaddr, kernel_addr_r, fdt_addr_r, ramdisk_addr_r |
Địa chỉ DRAM để nạp kernel, DTB, initramfs |
ipaddr, serverip, ethaddr |
Cấu hình mạng cho TFTP/NFS |
fdtfile |
Tên file DTB cần nạp |
=> printenv bootcmd
=> setenv bootargs console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlycon
=> saveenv
Từ Linux, đọc và sửa environment bằng fw_printenv / fw_setenv (gói libubootenv hoặc u-boot-fw-utils), cấu hình vị trí environment trong /etc/fw_env.config. Đây là cách các framework OTA (SWUpdate, RAUC, Mender) đổi slot boot.
Các lệnh hay dùng¶
| Nhóm | Lệnh | Ví dụ |
|---|---|---|
| Thông tin | version, bdinfo, help, coninfo |
bdinfo in kích thước DRAM, địa chỉ relocation |
| Bộ nhớ | md, mw, cp, cmp, mtest |
md.l 0xF8000000 10 đọc 16 word từ thanh ghi |
| Storage | mmc, sf, nand, usb, part |
mmc dev 0; mmc part, sf probe 0; sf read ${loadaddr} 0x100000 0x500000 |
| Filesystem | fatls, fatload, ext4load, load, ls |
load mmc 0:1 ${kernel_addr_r} zImage |
| Mạng | dhcp, tftpboot, ping, nfs |
tftpboot ${kernel_addr_r} zImage |
| Device tree | fdt addr, fdt print, fdt set |
Sửa DTB trước khi boot |
| Boot | bootm, bootz, booti, bootefi, bootflow |
Xem bảng dưới |
| Script | source, run, env import |
run bootcmd |
| FPGA (Zynq) | fpga load, fpga loadb |
Nạp bitstream cho PL từ U-Boot |
Lệnh boot kernel¶
| Lệnh | Kiểu image | Dùng cho |
|---|---|---|
bootz |
zImage (ARM 32-bit, tự giải nén) |
bootz ${kernel_addr_r} - ${fdt_addr_r} |
booti |
Image (ARM64, RISC-V) |
booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r} |
bootm |
uImage (legacy header) hoặc FIT image |
bootm ${loadaddr} hoặc bootm ${loadaddr}#conf-1 |
bootefi |
Ứng dụng EFI (GRUB, kernel EFI stub) | bootefi ${kernel_addr_r} ${fdt_addr_r} |
Dấu - ở vị trí initramfs nghĩa là không dùng initramfs.
uImage là image có header 64 byte của U-Boot, tạo bằng mkimage (kernel có sẵn target make uImage với LOADADDR/UIMAGE_LOADADDR). Định dạng này đã cũ: chỉ chứa một image, checksum CRC32, không có chữ ký. Thiết kế mới nên dùng zImage/Image với bootz/booti, hoặc FIT image.
FIT image¶
FIT (Flattened Image Tree) dùng chính cú pháp device tree để mô tả một gói gồm nhiều image: kernel, nhiều DTB, initramfs, bitstream FPGA, kèm hash (SHA256) và chữ ký RSA/ECDSA. Đây là nền tảng của verified boot trong U-Boot.
/dts-v1/;
/ {
description = "Kernel + DTB";
#address-cells = <1>;
images {
kernel-1 {
data = /incbin/("zImage");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x8000>;
entry = <0x8000>;
hash-1 { algo = "sha256"; };
};
fdt-1 {
data = /incbin/("system.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash-1 { algo = "sha256"; };
};
};
configurations {
default = "conf-1";
conf-1 {
kernel = "kernel-1";
fdt = "fdt-1";
signature-1 {
algo = "sha256,rsa2048";
key-name-hint = "dev";
sign-images = "kernel", "fdt";
};
};
};
};
# Đóng gói, ký bằng key trong thư mục keys/, ghi public key vào DTB của U-Boot
mkimage -f fit-image.its -k keys -K u-boot.dtb -r image.itb
Petalinux và Yocto (class kernel-fitimage) tạo FIT image tự động, ví dụ image.ub của Petalinux chính là một FIT image. Xem thêm List of Petalinux Images.
Boot script¶
Thay vì sửa bootcmd trong environment, có thể đặt logic boot trong một script trên phân vùng boot. Script viết dạng text rồi đóng gói bằng mkimage:
setenv bootargs console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait
load mmc 0:1 ${kernel_addr_r} zImage
load mmc 0:1 ${fdt_addr_r} system.dtb
bootz ${kernel_addr_r} - ${fdt_addr_r}
Một số board (trong đó có các bản Xilinx cũ) còn đọc file uEnv.txt dạng key=value rồi env import vào environment.
Distro boot và Standard Boot¶
Để một bản phân phối (Debian, Fedora, Yocto) boot được trên nhiều board mà không phải sửa bootcmd cho từng board, U-Boot có cơ chế quét boot media theo thứ tự (boot_targets) và tìm một trong các file:
extlinux/extlinux.conf(cú pháp giống syslinux, chỉ định kernel, DTB, append)boot.scr/boot.scr.uimg- Ứng dụng EFI mặc định
/EFI/BOOT/bootaa64.efi,bootarm.efi...
label linux
kernel /zImage
fdt /system.dtb
append console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait
Cơ chế cũ dùng script trong include/config_distro_bootcmd.h (distro boot). Từ khoảng 2023, U-Boot chuyển sang Standard Boot (CONFIG_BOOTSTD) viết bằng C với các khái niệm bootdev, bootmeth, bootflow:
Cập nhật firmware và fallback¶
Khi cập nhật firmware ngoài hiện trường, bootloader là chỗ quyết định boot bản nào:
- A/B (dual copy): hai bộ kernel + rootfs. Framework OTA ghi bản mới vào slot không dùng, đổi biến môi trường bằng
fw_setenv, rồi reboot. - bootcount (
CONFIG_BOOTCOUNT_LIMIT): U-Boot tăngbootcountmỗi lần boot. Linux reset nó về 0 khi boot thành công. Nếu vượtbootlimit, U-Boot chạyaltbootcmdđể quay về slot cũ. - Bản thân bootloader hiếm khi được cập nhật OTA vì nếu hỏng thì board không boot được nữa. Một số SoC hỗ trợ nhiều bản stage 1 (Zynq có multiboot/golden image, i.MX có secondary image) để giảm rủi ro.
References¶
- The U-Boot Documentation - docs.u-boot.org
- U-Boot Standard Boot - docs.u-boot.org
- Flattened Image Tree (FIT) Format - docs.u-boot.org
- Environment Variables - docs.u-boot.org
- Embedded Linux system development - bootlin.com, phần Bootloaders