Yocto: Build Your Own Linux Distro
Yocto Project không phải là một bản Linux, mà là một bộ công cụ và quy trình để tự tạo ra bản Linux của riêng mình cho thiết bị nhúng. Chính dự án tự mô tả điều này bằng một câu hay được trích: nó không phải một distribution nhúng, nó tạo ra distribution tùy biến cho bạn. Yocto ra đời năm 2010 dưới sự bảo trợ của Linux Foundation. Mục tiêu là để các hãng chip, nhà sản xuất thiết bị và cộng đồng dùng chung một nền tảng build, thay vì mỗi nơi tự viết script riêng rồi tự vật lộn với nó.
Có thể hình dung Ubuntu hay Debian như món ăn đã nấu sẵn: bạn nhận về và dùng, thêm bớt chút gia vị bằng trình quản lý gói. Yocto thì trao cho bạn cả căn bếp. Có sách công thức cho từng nguyên liệu (kernel, bootloader, glibc, busybox, systemd, Qt…), có đầu bếp đọc công thức và nấu theo đúng thứ tự phụ thuộc. Món cuối cùng được nấu từ mã nguồn, cho đúng kiến trúc CPU, đúng board, và chỉ có những gì bạn cần. Nhờ vậy một image Yocto có thể nhỏ vài chục MB, hoặc đầy đủ tới mức có giao diện đồ họa và trình duyệt, tùy người thiết kế.
Các thành phần
Căn bếp ấy gồm vài thành phần mà người mới thường nghe lẫn lộn:
| Thành phần | Vai trò |
|---|---|
| BitBake | Công cụ thực thi tác vụ, là “đầu bếp”. Nó đọc metadata, dựng đồ thị phụ thuộc, rồi chạy song song các bước fetch, unpack, patch, configure, compile, install, package cho từng gói |
Recipe (.bb) | Công thức cho một phần mềm: lấy source ở đâu, áp patch nào, build thế nào, cài vào đâu |
.bbappend | Phần sửa bổ sung cho một recipe có sẵn mà không phải đụng vào file gốc, ví dụ thêm patch hay đổi cấu hình kernel |
Class (.bbclass) | Logic dùng chung, ví dụ cách build một dự án CMake, autotools hay kernel module |
Layer (meta-*) | Một tập recipe, class và cấu hình có cùng chủ đề. Các layer xếp chồng lên nhau, layer trên ghi đè hoặc mở rộng layer dưới |
| OpenEmbedded-Core | Layer nền tảng chứa các recipe cốt lõi mà hầu như mọi hệ thống đều cần |
| Poky | Bản phân phối tham chiếu của Yocto, gói sẵn BitBake, OE-Core và một layer mẫu để bắt đầu |
| BSP layer | Layer do hãng chip hoặc hãng board cung cấp (như meta-ti, meta-raspberrypi, meta-freescale…), chứa kernel, bootloader, firmware và device tree cho phần cứng cụ thể |
MACHINE / DISTRO / local.conf | Ba lớp cấu hình: build cho phần cứng nào, theo chính sách phân phối nào, và các tùy chỉnh cục bộ của người build |
Cấu trúc thư mục
Cấu trúc thư mục cơ bản khi mới repo sync:
yocto-bsp/├── .repo/│ ├── manifests/ ← git repo chứa các file manifest│ ├── manifest.xml ← manifest đang có hiệu lực│ ├── repo/ ← mã nguồn của chính công cụ repo│ ├── projects/ ← thư mục .git thật của từng project│ └── project-objects/├── setup-environment ← sinh ra nhờ <copyfile> trong manifest└── sources/ ├── poky/ │ ├── bitbake/ │ ├── meta/ ← OpenEmbedded-Core │ ├── meta-poky/ │ ├── meta-yocto-bsp/ │ ├── meta-skeleton/ │ ├── meta-selftest/ │ ├── documentation/ │ ├── scripts/ │ └── oe-init-build-env ├── meta-openembedded/ │ ├── meta-oe/ │ ├── meta-python/ │ ├── meta-networking/ │ ├── meta-multimedia/ │ └── ... ├── meta-vendor-bsp/ └── meta-mycompany/Layer tự viết
Một layer tự viết cho sản phẩm, ở dạng tối thiểu mà đủ dùng, có hình hài như sau:
meta-mycompany/├── conf/│ ├── layer.conf│ ├── machine/│ │ └── myboard.conf│ └── distro/│ └── mydistro.conf├── recipes-bsp/│ └── u-boot/│ ├── u-boot_%.bbappend│ └── files/0001-add-myboard-support.patch├── recipes-kernel/│ └── linux/│ ├── linux-vendor_%.bbappend│ └── files/│ ├── myboard.dts│ └── enable-feature.cfg├── recipes-apps/│ └── hello/│ ├── hello_1.0.bb│ └── files/hello.c├── recipes-core/│ └── images/│ └── myimage.bb├── COPYING.MIT└── READMETrái tim của layer là conf/layer.conf. File này cho BitBake biết layer tìm recipe ở đâu, có độ ưu tiên bao nhiêu khi đè lên layer khác, phụ thuộc layer nào, và tương thích với release Yocto nào:
BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "mycompany"BBFILE_PATTERN_mycompany = "^${LAYERDIR}/"BBFILE_PRIORITY_mycompany = "10"
LAYERDEPENDS_mycompany = "core openembedded-layer"LAYERSERIES_COMPAT_mycompany = "scarthgap"Một recipe đơn giản
Một recipe đơn giản nhất, biên dịch một file C rồi cài vào /usr/bin, đọc lên gần như tự giải thích. Riêng dòng checksum license là thứ Yocto bắt buộc, để quá trình kiểm tra giấy phép không bị bỏ qua:
SUMMARY = "Hello world example"LICENSE = "MIT"LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://hello.c"S = "${WORKDIR}"
do_compile() { ${CC} ${CFLAGS} ${LDFLAGS} hello.c -o hello}
do_install() { install -d ${D}${bindir} install -m 0755 hello ${D}${bindir}}Hai file cấu hình
Hai file quan trọng nhất cả dự án. File thứ nhất, bblayers.conf, quyết định những layer nào tham gia bữa tiệc:
BBLAYERS ?= " \ ${TOPDIR}/../sources/poky/meta \ ${TOPDIR}/../sources/poky/meta-poky \ ${TOPDIR}/../sources/meta-openembedded/meta-oe \ ${TOPDIR}/../sources/meta-vendor-bsp \ ${TOPDIR}/../sources/meta-mycompany \"File thứ hai, local.conf, quyết định build cho máy nào, theo distro nào, và dùng tài nguyên ra sao:
MACHINE ?= "myboard"DISTRO ?= "poky"PACKAGE_CLASSES ?= "package_ipk"
BB_NUMBER_THREADS ?= "8"PARALLEL_MAKE ?= "-j 8"
DL_DIR ?= "${TOPDIR}/../downloads"SSTATE_DIR ?= "${TOPDIR}/../sstate-cache"Sau lần build đầu tiên
Sau khi chạy bitbake myimage lần đầu, cây thư mục phình ra thêm những phần sau:
| Đường dẫn | Chứa gì |
|---|---|
downloads/ | Tarball và git mirror của mọi source đã fetch |
sstate-cache/ | Kết quả từng task đã đóng gói, để lần build sau tái sử dụng |
build/tmp/work/<arch>/<recipe>/<version>/ | Không gian làm việc riêng của từng recipe: source đã giải nén, thư mục build, image/ (kết quả do_install), packages-split/ |
build/tmp/work/.../temp/ | log.do_<task> và run.do_<task>, nơi đầu tiên cần mở khi một task lỗi |
build/tmp/deploy/images/<machine>/ | Sản phẩm cuối: kernel, device tree, bootloader, rootfs image |
build/tmp/deploy/ipk/ (hoặc rpm/, deb/) | Các gói phần mềm riêng lẻ |
build/tmp/sysroots-components/ | Header và thư viện mỗi recipe công bố cho các recipe phụ thuộc vào nó |
build/cache/ | Cache kết quả parse metadata của BitBake |










