Cấu hình Package Manager cho Rootfs tối ưu
Bật Meta-OPKG và tắt Package Manager mặc định
Bước đầu tiên là chuyển đổi package manager mặc định (thường là RPM hoặc Apt) sang OPKG để giảm kích thước Rootfs, phù hợp với hệ thống nhúng như Raspberry Pi CM5.
Tại sao: OPKG nhẹ hơn, không yêu cầu dependencies phức tạp, giúp giảm dung lượng image và tăng tốc độ cài đặt gói trong môi trường tài nguyên hạn chế.
Kết quả mong đợi: Build process sẽ tạo file `.ipk` thay vì `.rpm` hoặc `.deb`, và thư mục `/var/lib/opkg` sẽ xuất hiện trong rootfs.
Trước khi sửa file, hãy mở file cấu hình distro của bạn (thường nằm trong `meta-custom/recipes-core/images/custom-image.bb` hoặc file `.bbappend` tương ứng).
IMAGE_INSTALL:append = " opkg opkg-list-packages"
IMAGE_INSTALL:remove = " busybox-syslogd"
IMAGE_INSTALL:remove = " busybox-runlevel"
Sau đó, trong file `local.conf` hoặc `bblayers.conf`, đảm bảo bạn đã thêm layer `meta-openembedded` và `meta-raspberrypi` nếu chưa có.
SOURCE_URI:append = " file://meta-openembedded/meta-oe"
SOURCERECIPE:append = " file://meta-openembedded/meta-oe"
Tiếp theo, tạo file `meta-custom/recipes-core/images/custom-image.bbappend` để override cấu hình package manager.
IMAGE_INSTALL:append = " opkg opkg-list-packages"
IMAGE_INSTALL:remove = " package-management"
Chạy lệnh rebuild để áp dụng thay đổi.
bitbake custom-image -c cleanall
bitbake custom-image
Verify kết quả: Chạy lệnh `opkg list` trong rootfs đã build xong để xem danh sách gói đã cài đặt.
Cài đặt các gói phần mềm cốt lõi (Network, SSH, Logging)
Thêm gói SSH Server (Dropbear)
Dropbear là SSH server nhẹ, tối ưu cho nhúng, thay thế OpenSSH để tiết kiệm RAM và CPU.
Tại sao: OpenSSH quá nặng cho các tác vụ đơn giản, Dropbear chỉ cần vài MB RAM và hỗ trợ đầy đủ tính năng bảo mật cơ bản.
Kết quả mong đợi: Dịch vụ SSH sẽ chạy khi boot, cho phép bạn kết nối từ xa vào CM5.
Thêm gói `dropbear` vào danh sách cài đặt trong file `custom-image.bbappend`.
IMAGE_INSTALL:append = " dropbear dropbear-init-scripts"
Tùy chỉnh cấu hình để Dropbear chạy ngay khi boot và không yêu cầu password (chỉ dùng key) nếu cần.
FILESDIR = "${THISDIR}/dropbear"
FILES_append = " ${FILESDIR}/dropbear.conf"
Cấu hình Network Manager hoặc DHCP Client
Đối với hệ thống nhúng, `udhcpc` hoặc `dhcpcd` là lựa chọn tốt hơn NetworkManager để giảm overhead.
Tại sao: `dhcpcd` (dhcp client daemon) rất nhẹ, hỗ trợ IPv6 tốt và tích hợp sâu với systemd, phù hợp cho Raspberry Pi.
Kết quả mong đợi: Hệ thống sẽ tự động lấy IP từ DHCP khi cắm dây mạng.
Thêm gói `dhcpcd` vào `IMAGE_INSTALL`.
IMAGE_INSTALL:append = " dhcpcd dhcpcd-init-scripts"
Tạo file cấu hình `dhcpcd.conf` trong thư mục `meta-custom/recipes-connectivity/dhcpcd/files/`.
interface eth0
static ip_address=192.168.1.50/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8 8.8.4.4
Copy file này vào rootfs thông qua `FILES` trong recipe.
FILES_${PN} += "/etc/dhcpcd.conf"
Cấu hình Logging với Syslog-ng hoặc Rsyslog
Sử dụng `syslog-ng` hoặc `rsyslog` để ghi log hệ thống vào file hoặc gửi qua mạng.
Tại sao: Busybox syslog quá cơ bản, không hỗ trợ phân loại log (facility/priority) tốt. `syslog-ng` mạnh mẽ hơn nhưng vẫn nhẹ.
Kết quả mong đợi: Log hệ thống được ghi vào `/var/log/messages` hoặc `/var/log/syslog`.
Thêm gói `syslog-ng` vào `IMAGE_INSTALL`.
IMAGE_INSTALL:append = " syslog-ng syslog-ng-init-scripts"
Tạo file cấu hình `syslog-ng.conf` trong `meta-custom/recipes-core/syslog-ng/files/`.
@version: 3.26
@include "scl.conf"
@include "scl.conf"
source s_local {
unix-dgram( "/dev/log" );
unix-dgram( "/var/run/syslogd.sock" );
};
destination f_messages {
file( "/var/log/messages" flags( create ) owner( "root" ) group( "root" ) perm( 0640 ) );
};
log {
source( s_local );
filter( f_local );
destination( f_messages );
};
Verify kết quả: Sau khi boot, chạy `cat /var/log/messages` để xem log khởi động.
Cấu hình Systemd Services tự động khởi động
Tạo Unit File cho dịch vụ tùy chỉnh
Viết file unit `.service` để systemd quản lý các tiến trình cần chạy sau boot.
Tại sao: Systemd là init system tiêu chuẩn trên Linux hiện đại, giúp quản lý lifecycle, log, và tự động restart nếu service crash.
Kết quả mong đợi: Dịch vụ sẽ tự động chạy khi hệ thống lên, không cần can thiệp thủ công.
Tạo file `custom-app.service` trong `meta-custom/recipes-custom/custom-app/files/`.
[Unit]
Description=Custom Application Service
After=network.target sshd.service
[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/app/main.py
Restart=on-failure
RestartSec=5
User=root
Group=root
[Install]
WantedBy=multi-user.target
Trong recipe của package (`custom-app.bb`), thêm file này vào `FILES` và enable nó.
FILES_${PN} += "/etc/systemd/system/custom-app.service"
Sử dụng `sysupdate` hoặc `systemd` command trong recipe để enable service.
do_install_append() {
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/custom-app.service ${D}${systemd_system_unitdir}/custom-app.service
# Enable service
${D}${bindir}/systemctl enable custom-app.service || true
}
Verify kết quả: Chạy `systemctl status custom-app` sau khi boot để xem trạng thái.
Disable dịch vụ không cần thiết
Tắt các dịch vụ mặc định không dùng đến để tiết kiệm tài nguyên.
Tại sao: Mặc định Yocto có thể bật nhiều service không cần thiết (như bluetooth, sound) gây lãng phí RAM.
Kết quả mong đợi: Số lượng service đang chạy giảm, hệ thống khởi động nhanh hơn.
Trong `custom-image.bbappend`, thêm lệnh disable service.
IMAGE_INSTALL:remove = " systemd-boot"
IMAGE_INSTALL:remove = " bluetooth"
Sử dụng `systemctl disable` trong recipe nếu cần disable cụ thể.
do_install_append() {
${D}${bindir}/systemctl disable bluetooth.service || true
${D}${bindir}/systemctl disable sound.service || true
}
Tùy chỉnh User và Group mặc định
Tạo User và Group thông qua Recipe
Định nghĩa user và group trong recipe để tạo tự động khi build image.
Tại sao: Tạo user trong build time giúp đảm bảo UID/GID cố định, tránh xung đột khi chạy container hoặc mount volume.
Kết quả mong đợi: User `appuser` và group `appgroup` tồn tại trong `/etc/passwd` và `/etc/group` khi boot.
Sử dụng `useradd` và `groupadd` trong recipe.
do_install_append() {
${D}${sbindir}/groupadd -g 1000 appgroup
${D}${sbindir}/useradd -u 1000 -g 1000 -d /home/appuser -m appuser
chown -R appuser:appgroup ${D}/opt/app
}
Cấu hình quyền sở hữu thư mục `/opt/app` cho user mới.
FILES_${PN} += "/opt/app"
Thiết lập Sudoers cho User
Cho phép user không phải root chạy lệnh sudo nếu cần.
Tại sao: Bảo mật tốt hơn là không dùng root trực tiếp, nhưng vẫn cần quyền admin cho một số tác vụ.
Kết quả mong đợi: User `appuser` có thể chạy `sudo ` sau khi nhập password (hoặc không nếu cấu hình NOPASSWD).
Tạo file sudoers trong `meta-custom/recipes-extended/sudo/files/`.
appuser ALL=(ALL) NOPASSWD: ALL
Thêm vào `FILES` trong recipe sudo.
FILES_${PN} += "/etc/sudoers.d/appuser"
Verify kết quả: Sau khi boot, switch sang user `appuser` và chạy `sudo whoami`.
su - appuser
sudo whoami
Điều hướng series:
Mục lục: Series: Xây dựng hệ điều hành Linux tùy biến từ source cho Raspberry Pi CM5
« Phần 4: Cấu hình Bootloader và tạo Image Boot cho CM5
Phần 6: Tích hợp ứng dụng người dùng và tối ưu hóa hiệu năng »