Files
BPI-CM9-Linux/amlbian/lib/function-img.sh
T

1598 lines
56 KiB
Bash
Raw Normal View History

2026-08-13 11:28:40 +08:00
#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2026 AMLOGIC
#
# Environment configuration functions for AMLbian
chroot_rootfs_apt_get_install() {
local rootfs="${ROOTFS_TEMP}"
local pkgs="$1"
if [[ -z "$rootfs" ]]; then
2026-11-11 08:50:43 +08:00
aml_log error "ROOTFS_TEMP is not set"
2026-08-13 11:28:40 +08:00
return 1
fi
if [[ -z "$pkgs" ]]; then
2026-11-11 08:50:43 +08:00
aml_log warn "no packages provided to install"
2026-08-13 11:28:40 +08:00
return 0
fi
# 防止空 rootfs
if [[ ! -d "$rootfs" ]]; then
2026-11-11 08:50:43 +08:00
aml_log error "rootfs not found" "$rootfs"
2026-08-13 11:28:40 +08:00
return 1
fi
mount_chroot $rootfs
2026-11-11 08:50:43 +08:00
aml_log info "Installing packages in rootfs: $rootfs"
aml_log debug "Packages: $pkgs"
2026-08-13 11:28:40 +08:00
# 核心执行:进入 rootfs chroot, no apt-get update -y
chroot "$rootfs" /bin/bash -c "
export DEBIAN_FRONTEND=noninteractive
export TMPDIR=/tmp
apt-get update -y
apt-get install -y $pkgs
"
umount_chroot $rootfs
}
function amlbian_additional_insatll() {
2026-11-11 08:50:43 +08:00
aml_log info "Installing additional packages from PACKAGE_LIST_AML: ${PACKAGE_LIST_AML}"
2026-08-13 11:28:40 +08:00
local pkgs="${PACKAGE_LIST_AML}"
local rootfs="${ROOTFS_TEMP:-$SDCARD}"
if [[ -z "$pkgs" ]]; then
2026-11-11 08:50:43 +08:00
aml_log info "PACKAGE_LIST_AML is empty, skip AML additional install"
2026-08-13 11:28:40 +08:00
return 0
fi
if [[ ! -d "$rootfs" ]]; then
2026-11-11 08:50:43 +08:00
aml_log error "rootfs not found" "$rootfs"
2026-08-13 11:28:40 +08:00
return 1
fi
mount_chroot $rootfs
2026-11-11 08:50:43 +08:00
aml_log info "INFO: AML additional install in rootfs: $rootfs"
aml_log info "INFO: packages: $pkgs"
2026-08-13 11:28:40 +08:00
for pkg in $pkgs; do
if [[ -z "$pkg" ]]; then
continue
fi
2026-11-11 08:50:43 +08:00
aml_log info "Installing AML package: $pkg"
2026-08-13 11:28:40 +08:00
chroot "$rootfs" /bin/bash -c "
export DEBIAN_FRONTEND=noninteractive
export TMPDIR=/tmp
apt-get update -y
apt-get install -y $pkg
" || {
2026-11-11 08:50:43 +08:00
aml_log warn "failed to install AML package" "$pkg"
2026-08-13 11:28:40 +08:00
continue
}
done
umount_chroot $rootfs
2026-11-11 08:50:43 +08:00
aml_log info "Install PACKAGE_LIST_AML done"
2026-08-13 11:28:40 +08:00
}
function install_aml_deb(){
local package=$1
local name=$(basename $package)
[ -e "$package" ] || {
2026-11-11 08:50:43 +08:00
aml_log warn "Installing $name in chroot skipped ($package not exist)"
2026-08-13 11:28:40 +08:00
return 0
}
cp $package $ROOTFS_TEMP/root/$name
2026-11-11 08:50:43 +08:00
aml_log info "Installing $name in chroot... stand install_aml_deb"
2026-08-13 11:28:40 +08:00
mount_chroot "$ROOTFS_TEMP"
# Force install even if dependencies are missing, then try to configure and fix broken
chroot $ROOTFS_TEMP /bin/bash -c "
dpkg -i --force-all /root/$name || { echo 'dpkg install failed'; exit 1; }
dpkg --configure -a || { echo 'dpkg configure failed'; exit 1; }
apt --fix-broken --option Dpkg::Options::=\"--force-confdef\" install -y || { echo 'apt fix-broken failed'; exit 1; }
" || exit 1
umount_chroot "$ROOTFS_TEMP"
rm -f $ROOTFS_TEMP/root/$name
}
function install_udev_amlbian() {
if ! is_unit_enabled "udev"; then
2026-11-11 08:50:43 +08:00
aml_log debug "[SKIP Install] >> Udev disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local udev_file=$(find "${BUILD_DEBS}" -name "aml-udev_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install udev BUILD_DEBS ${BUILD_DEBS} udev_file ${udev_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb ${udev_file}
}
function install_modules_load_amlbian() {
if ! is_unit_enabled "modules-load"; then
2026-11-11 08:50:43 +08:00
aml_log debug "[SKIP Install] >> modules-load disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local modules_file=$(find "${BUILD_DEBS}" -name "aml-modules-load_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install module-load BUILD_DEBS ${BUILD_DEBS} modules_file ${udev_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb ${modules_file}
}
function install_gpu_amlbian() {
if ! is_unit_enabled "gpu"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP Install] >> gpu disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local gpu_file=$(find "${BUILD_DEBS}" -name "aml-gpu-${GPU_ARCH}*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install gpu BUILD_DEBS ${BUILD_DEBS} gpu_file ${gpu_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $gpu_file
local libgles_file=$(find "${BUILD_DEBS}" -name "aml-libgles-eabihf-${GPU_MODEL}*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install gpu BUILD_DEBS ${BUILD_DEBS} libgles_file ${libgles_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $libgles_file
}
function install_npu_amlbian() {
if ! is_unit_enabled "npu"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP Install] >> npu disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local npu_common_file=$(find "${BUILD_DEBS}" -name "aml-npu-common_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} npu_common_file ${npu_common_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $npu_common_file
local adla_driver_file=$(find "${BUILD_DEBS}" -name "aml-adla-driver_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} adla_driver_file ${adla_driver_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $adla_driver_file
local adla_lib_file=$(find "${BUILD_DEBS}" -name "aml-adla-lib_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} adla_lib_file ${adla_lib_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $adla_lib_file
}
function install_wifi_amlbian() {
if ! is_unit_enabled "wifi"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP Install] >> wifi disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local wifi_file=$(find "${BUILD_DEBS}" -name "aml-wifi-w*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wifi_file ${wifi_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $wifi_file
local wifi_common_file=$(find "${BUILD_DEBS}" -name "aml-wifi-common_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wifi_common_file ${wifi_common_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $wifi_common_file
local wpa_file=$(find "${BUILD_DEBS}" -name "aml-wpa-supplicant-config_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wpa_file ${wpa_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $wpa_file
}
function install_bt_amlbian() {
if ! is_unit_enabled "bt"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP Install] >> bt disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local hciattach_file=$(find "${BUILD_DEBS}" -name "aml-hciattach*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install hciattach BUILD_DEBS ${BUILD_DEBS} hciattach_file ${hciattach_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $hciattach_file
2026-11-11 08:50:43 +08:00
local bt_driver=$(find "${BUILD_DEBS}" -name "aml-bt-w*.deb" 2>/dev/null)
aml_log info "install bt driver BUILD_DEBS ${BUILD_DEBS} bt_driver ${bt_driver}"
2026-08-13 11:28:40 +08:00
install_aml_deb $bt_driver
}
function install_isp_amlbian() {
if ! is_unit_enabled "isp"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP Install] >> isp disable in BUILD_UNITS"
2026-08-13 11:28:40 +08:00
return
fi
local isp_driver_file=$(find "${BUILD_DEBS}" -name "aml-isp_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install isp BUILD_DEBS ${BUILD_DEBS} isp_driver_file ${isp_driver_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $isp_driver_file
local libisp_file=$(find "${BUILD_DEBS}" -name "aml-libisp_*.deb" 2>/dev/null)
2026-11-11 08:50:43 +08:00
aml_log info "install isp BUILD_DEBS ${BUILD_DEBS} libisp_file ${libisp_file}"
2026-08-13 11:28:40 +08:00
install_aml_deb $libisp_file
}
function install_optee_deb {
if ! is_unit_enabled "optee"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> optee disabled ( not install)"
2026-08-13 11:28:40 +08:00
return
fi
local optee_userspace_file=$(find "${BUILD_DEBS}" -name "linux-optee-userspace-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $optee_userspace_file
local tee_supplicant_file=$(find "${BUILD_DEBS}" -name "linux-tee-supplicant-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $tee_supplicant_file
local optee_video_firmware_file=$(find "${BUILD_DEBS}" -name "linux-optee-video-firmware-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $optee_video_firmware_file
}
function install_libencoder_deb {
if ! is_unit_enabled "libencoder"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libencoder disabled ( not install)"
2026-08-13 11:28:40 +08:00
return
fi
local libamvenc_file=$(find "${BUILD_DEBS}" -name "linux-libamvenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libamvenc_file
if ! is_feature_contains "$MEDIA_FEATURES" "libversenc-prebuilt"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libversenc-prebuilt disable in MEDIA_FEATURES ( not install)"
2026-08-13 11:28:40 +08:00
else
local libversenc_prebuilt_file=$(find "${BUILD_DEBS}" -name "linux-libversenc-prebuilt-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libversenc_prebuilt_file
fi
if ! is_feature_contains "$MEDIA_FEATURES" "libtahoevenc"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libtahoevenc disable in MEDIA_FEATURES ( not install)"
2026-08-13 11:28:40 +08:00
else
local libtahoevenc_file=$(find "${BUILD_DEBS}" -name "linux-libtahoevenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libtahoevenc_file
fi
if ! is_feature_contains "$MEDIA_FEATURES" "libamljpegenc"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libamljpegenc disable in MEDIA_FEATURES ( not install)"
2026-08-13 11:28:40 +08:00
else
local libamljpegenc_file=$(find "${BUILD_DEBS}" -name "linux-libamljpegenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libamljpegenc_file
fi
2026-11-11 08:50:43 +08:00
if ! is_feature_contains "$MEDIA_FEATURES" "aml-libamvenc-264"; then
display_alert "[SKIP] >> aml-libamvenc-264 disable in MEDIA_FEATURES ( not install)" "info"
else
local libh264bitstream_file=$(find "${BUILD_DEBS}" -name "linux-libh264bitstream-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libh264bitstream_file
local libamvenc_264_file=$(find "${BUILD_DEBS}" -name "linux-libamvenc-264-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libamvenc_264_file
fi
2026-08-13 11:28:40 +08:00
}
function install_media_deb {
if ! is_unit_enabled "media-modules"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> media-modules disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local media_mod_file=$(find "${BUILD_DEBS}" -name "linux-media-modules-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $media_mod_file
if ! is_feature_contains "$MEDIA_ENCODER_HW_CONFIG" "TAHOE"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> TAHOE disable in MEDIA_ENCODER_HW_CONFIG ( not install)"
2026-08-13 11:28:40 +08:00
else
local tahoe_file=$(find "${BUILD_DEBS}" -name "linux-tahoe-encoder-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $tahoe_file
fi
fi
if ! is_unit_enabled "libion"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libion disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local libion_file=$(find "${BUILD_DEBS}" -name "linux-libion-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libion_file
fi
if ! is_unit_enabled "libge2d"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> libge2d disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local libge2d_file=$(find "${BUILD_DEBS}" -name "linux-libge2d-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libge2d_file
fi
if ! is_unit_enabled "liblog"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> liblog disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local liblog_file=$(find "${BUILD_DEBS}" -name "linux-liblog-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $liblog_file
fi
install_optee_deb
install_libencoder_deb
if ! is_unit_enabled "dma-allocator"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> dma-allocator disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local dmabuf_file=$(find "${BUILD_DEBS}" -name "linux-libdma-allocator-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $dmabuf_file
fi
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_drmbuf_file=$(find "${BUILD_DEBS}" -name "linux-gst-aml-drmbufferpool-plugins-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_drmbuf_file
fi
}
function install_tvserver_deb {
if ! is_unit_enabled "tvserver"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> tvserver disabled ( not install)"
2026-08-13 11:28:40 +08:00
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "tvserver"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> tvserver disable in DISTRO_FEATURES ( not install)"
2026-08-13 11:28:40 +08:00
return
fi
local amaudioutils_file=$(find "${BUILD_DEBS}" -name "linux-amaudioutils-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $amaudioutils_file
local mediahal_sdk_file=$(find "${BUILD_DEBS}" -name "linux-aml-mediahal-sdk-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $mediahal_sdk_file
local ubootenv_file=$(find "${BUILD_DEBS}" -name "linux-aml-ubootenv-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $ubootenv_file
}
2026-08-25 10:02:36 +08:00
function install_logcat_deb {
if ! is_unit_enabled "devtool" || ! is_unit_enabled "liblog"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> devtool android tool logcat disabled ( not install)"
2026-08-25 10:02:36 +08:00
return
fi
local logcat_file=$(find "${BUILD_DEBS}" -name "android-tools-logcat*.deb" 2>/dev/null)
install_aml_deb $logcat_file
}
function install_vendor_file_deb {
if ! is_unit_enabled "vendor-files"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> vendor-files disabled ( not install)"
2026-08-25 10:02:36 +08:00
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "vendor-files"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> vendor-files disable in DISTRO_FEATURES ( not install)"
2026-08-25 10:02:36 +08:00
return
fi
local vendor_file=$(find "${BUILD_DEBS}" -name "linux-vendor-files-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $vendor_file
}
function install_linux_uapi_deb {
if ! is_unit_enabled "linux-uapi-headers"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> linux-uapi-headers disabled ( not install)"
2026-08-25 10:02:36 +08:00
return
fi
local linux_uapi_headers_file=$(find "${BUILD_DEBS}" -name "linux-linux-uapi-headers-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $linux_uapi_headers_file
}
2026-11-11 08:50:43 +08:00
function install_chromium_amlbian() {
if ! is_unit_enabled "chromium" 2>/dev/null; then
return 0
fi
local chromium_file=$(find "${BUILD_DEBS}" -name "chromium-browser-aml_*.deb" 2>/dev/null | head -1)
if [ -n "$chromium_file" ]; then
install_aml_deb $chromium_file
fi
}
2026-08-13 11:28:40 +08:00
function install_common() {
2026-11-11 08:50:43 +08:00
aml_log info "install amlogic debs: GPU/NPU/DEC/ENC/... ... " "IMG"
2026-08-13 11:28:40 +08:00
# Bridge cross-compiler triplet to Debian multiarch so gcc --sysroot works
local _cc_triplet="${CROSS_COMPILE%%-}"
local _deb_triplet=""
for _d in "${ROOTFS_TEMP}"/usr/lib/*/pkgconfig; do
[[ -d "$_d" ]] || continue
_deb_triplet=$(basename "$(dirname "$_d")")
break
done
if [[ -n "$_deb_triplet" ]]; then
# Directory symlink: fixes pkg-config, --libdir, install paths
if [[ -n "$_cc_triplet" && "$_cc_triplet" != "$_deb_triplet" ]]; then
ln -sfn "${_deb_triplet}" "${ROOTFS_TEMP}/usr/lib/${_cc_triplet}"
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC: sysroot compat" "/usr/lib/${_cc_triplet} -> ${_deb_triplet}"
2026-08-13 11:28:40 +08:00
fi
# Startup files: gcc --sysroot only searches $ROOTFS/usr/lib/
local _f
for _f in crt1.o crti.o crtn.o Scrt1.o gcrt1.o libc.so; do
[[ -f "${ROOTFS_TEMP}/usr/lib/${_deb_triplet}/${_f}" ]] && \
ln -sfn "${_deb_triplet}/${_f}" "${ROOTFS_TEMP}/usr/lib/${_f}"
done
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC: sysroot compat" "linked crt*.o + libc.so into /usr/lib/"
2026-08-13 11:28:40 +08:00
fi
local uboot_file=$(find "${BUILD_DEBS}" -name "linux-u-boot-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $uboot_file
local kimg_file=$(find "${BUILD_DEBS}" -name "linux-image-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $kimg_file
local dtb_file=$(find "${BUILD_DEBS}" -name "linux-dtb-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $dtb_file
local mod_file=$(find "${BUILD_DEBS}" -name "linux-modules-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $mod_file
install_udev_amlbian
install_modules_load_amlbian
install_gpu_amlbian
install_npu_amlbian
install_wifi_amlbian
install_isp_amlbian
install_bt_amlbian
install_media_deb
2026-08-25 10:02:36 +08:00
install_linux_uapi_deb
install_vendor_file_deb
2026-11-11 08:50:43 +08:00
install_chromium_amlbian
2026-08-13 11:28:40 +08:00
install_tvserver_deb
2026-08-25 10:02:36 +08:00
install_logcat_deb
2026-08-13 11:28:40 +08:00
if [[ $(type -t tweaks_platform) == function ]]; then
tweaks_platform
fi
install_gst_aml_vendor_deb
# install_dmaheap_udev_amlbian
# install_aml_deb ${BUILD_DEBS}/gst.deb
# install_aml_deb ${BUILD_DEBS}/ge2d.deb
# install_aml_deb ${BUILD_DEBS}/adb.deb
}
function install_gst_aml_vendor_deb {
amlbian_build_gst_aml_vendor || return 1
local gst_file=$(find "${BUILD_DEBS}" -name "linux-gst-aml-vendor-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_file
}
function create_base_rootfs() {
2026-11-11 08:50:43 +08:00
aml_log info "Start create_base_rootfs rootfs-arm64-${RELEASE}*.tar.zst" "IMG"
2026-08-13 11:28:40 +08:00
local rootfs_img_tar
rootfs_img_tar=$(ls -t "${SRC}"/cache/rootfs/rootfs-arm64-"${RELEASE}"-"${DESKTOP_ENVIRONMENT}"*.tar.zst 2>/dev/null | head -1)
if [ -z "$rootfs_img_tar" ] || [ ! -f "$rootfs_img_tar" ]; then
2026-11-11 08:50:43 +08:00
aml_log error "rootfs tar not found in ${SRC}/cache/rootfs/" "IMG"
2026-08-13 11:28:40 +08:00
ls -la "${SRC}/cache/rootfs/" || true
exit 1
fi
2026-11-11 08:50:43 +08:00
aml_log info "Using rootfs: $rootfs_img_tar" "IMG"
2026-08-13 11:28:40 +08:00
tar -I zstd -xf "$rootfs_img_tar" -C "${ROOTFS_TEMP}"
2026-11-11 08:50:43 +08:00
aml_log info "End create_base_rootfs : $(ls "${ROOTFS_TEMP}")" "IMG"
2026-08-13 11:28:40 +08:00
}
function prepare_tools() {
## prepare utils
[ -d "$UTILS_DIR" ] || mkdir -p "$UTILS_DIR"
ln -sf "$COMP_DIR"/prebuilt/hosttools/aml-image-packer/aml_image_v2_packer_new "$UTILS_DIR"/aml_image_v2_packer
ln -sf "$COMP_DIR"/prebuilt/hosttools/aml-image-packer/res_packer "$UTILS_DIR"/res_packer
ln -sf "$COMP_DIR"/prebuilt/hosttools/kernel/dtbTool "$UTILS_DIR"/dtbTool
ln -sf "$COMP_DIR"/prebuilt/hosttools/aml-gpt-make/makegpt "$UTILS_DIR"/makegpt
}
function cleanup() {
2026-11-11 08:50:43 +08:00
aml_log info "Cleanup..."
2026-08-13 11:28:40 +08:00
sync
trap - INT TERM EXIT
umount_chroot "$ROOTFS_TEMP"
umount_chroot "$ROOTFS"
}
function build_additional_deb {
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build_additional_deb "
2026-08-13 11:28:40 +08:00
(
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-aml-drmbufferpool "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-drmbufferpool-plugins.sh"
)
}
function build_additional_deb_after_install {
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build_additional_deb_after_install "
2026-08-13 11:28:40 +08:00
(
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build bluez5 "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/bt/build-bluez5.sh"
if ! is_unit_enabled "bt"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> bt disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local bluez_file=$(find "${BUILD_DEBS}" -name "bluez_*.deb" 2>/dev/null)
install_aml_deb $bluez_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-plugin-venc "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-amlvenc.sh"
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_enc_file=$(find "${BUILD_DEBS}" -name "linux-gst-plugin-venc-amlvenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_enc_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-plugin-venc-jpeg"
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-jpeg.sh"
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_jpeg_file=$(find "${BUILD_DEBS}" -name "linux-gst-plugin-venc-jpeg-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_jpeg_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-aml-dma-allocator "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-dma-allocator.sh"
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_dmabuf_file=$(find "${BUILD_DEBS}" -name "linux-gst-aml-dma-allocator-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_dmabuf_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-aml-gfx2d "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-gfx2d.sh"
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_gfx2d_file=$(find "${BUILD_DEBS}" -name "linux-gst-aml-gfx2d-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_gfx2d_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build gst-aml-conv "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-conv.sh"
if ! is_unit_enabled "gst-aml"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local gst_conv_file=$(find "${BUILD_DEBS}" -name "linux-gst-plugin-conv-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $gst_conv_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build aml-tvserver "
2026-08-13 11:28:40 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/tvserver/build-aml-tvserver.sh"
if ! is_unit_enabled "tvserver"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> tvserver disabled ( not install)"
2026-08-13 11:28:40 +08:00
else
local tvserver_file=$(find "${BUILD_DEBS}" -name "linux-aml-tvserver-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $tvserver_file
fi
2026-08-25 10:02:36 +08:00
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build screencapture "
2026-08-25 10:02:36 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/build-screencapture.sh"
if ! is_unit_enabled "screencapture"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> screencapture disabled ( not install)"
2026-08-25 10:02:36 +08:00
else
local screencapture_file=$(find "${BUILD_DEBS}" -name "linux-screencapture-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $screencapture_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build mediactrlsrc "
2026-08-25 10:02:36 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/build-mediactrlsrc.sh"
if ! is_unit_enabled "mediactrlsrc"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> mediactrlsrc disabled ( not install)"
2026-08-25 10:02:36 +08:00
else
local mediactrlsrc_file=$(find "${BUILD_DEBS}" -name "linux-mediactrlsrc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $mediactrlsrc_file
fi
2026-11-11 08:50:43 +08:00
aml_log info "AMLOGIC" ">> Start build hdmi-test "
2026-08-25 10:02:36 +08:00
source "${EXTENSION_DIR}/../scripts/multimedia/build-hdmi-test.sh"
if ! is_unit_enabled "hdmi-test"; then
2026-11-11 08:50:43 +08:00
aml_log info "[SKIP] >> hdmi-test disabled ( not install)"
2026-08-25 10:02:36 +08:00
else
local hdmi_test_file=$(find "${BUILD_DEBS}" -name "linux-hdmi-test-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $hdmi_test_file
fi
2026-08-13 11:28:40 +08:00
)
}
function prepare_rootfs() {
# add some safety before make rm -rf ;-)
if [ -d $ROOTFS_TEMP ];then
umount_chroot "$ROOTFS_TEMP"
rm -rf "$ROOTFS_TEMP"
fi
mkdir -p "$ROOTFS_TEMP" "$BUILD_IMAGES/cache/rootfs"
trap cleanup INT EXIT TERM QUIT
create_base_rootfs
force_initramfs_with_amlogic_modules
#amlbian_additional_insatll
build_additional_deb
# install uboot/ kernel/ gpu/ npu/ media_modules/ ...
install_common
build_additional_deb_after_install
if [[ $(type -t install_custom) == function ]]; then
install_custom
return
# remove service start blockers later!
fi
# remove service start blockers
rm -f $ROOTFS_TEMP/sbin/initctl $ROOTFS_TEMP/sbin/start-stop-daemon
chroot $ROOTFS_TEMP /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/initctl"
chroot $ROOTFS_TEMP /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/start-stop-daemon"
rm -f $ROOTFS_TEMP/usr/sbin/policy-rc.d
2026-08-25 10:02:36 +08:00
if [ -f "$ROOTFS_TEMP/usr/lib/android-sdk/platform-tools/adbd-usb-gadget" ]; then
sed -i '/rmdir ${CONFIGFS_DIR}$/s/^/#/' \
"$ROOTFS_TEMP/usr/lib/android-sdk/platform-tools/adbd-usb-gadget"
fi
2026-08-13 11:28:40 +08:00
}
function add_amlbian_conf() {
local BOOT_SCRIPTS=${AMLBIAN_DIR}/config/bootscripts
local BOOT_ENV=${AMLBIAN_DIR}/config/bootenv
# Copy boot scripts
mkdir -p $ROOTFS_TEMP/boot
# Copy extlinux
if [ -f $BOOT_SCRIPTS/extlinux/$EXTLINUX_CONF ]; then
mkdir -p $ROOTFS_TEMP/boot/extlinux
cp $BOOT_SCRIPTS/extlinux/$EXTLINUX_CONF $ROOTFS_TEMP/boot/extlinux/extlinux.conf
else
2026-11-11 08:50:43 +08:00
aml_log info "NO extlinux, need checking it ......"
2026-08-13 11:28:40 +08:00
fi
# Copy boot environment
if [ -f $BOOT_ENV/uEnv.txt ]; then
cp $BOOT_ENV/uEnv.txt $ROOTFS_TEMP/boot/uEnv.txt
else
2026-11-11 08:50:43 +08:00
aml_log info "NO boot uEnv, need checking it ......"
2026-08-13 11:28:40 +08:00
fi
2026-08-25 10:02:36 +08:00
# Copy logo bmp
if [ -f ${AMLBIAN_DIR}/patches/logo/bmp/logo.bmp ]; then
local BMP_LOGO=$ROOTFS_TEMP/usr/share/amlbian/logo/
mkdir -p $BMP_LOGO
cp ${AMLBIAN_DIR}/patches/logo/bmp/logo.bmp $BMP_LOGO/logo.bmp
else
2026-11-11 08:50:43 +08:00
aml_log info "NO logo, need checking it ......"
2026-08-25 10:02:36 +08:00
fi
2026-08-13 11:28:40 +08:00
# Add link for start
cd $ROOTFS_TEMP/
ln -sf boot/Image Image
# local initrd_file=$(find "${ROOTFS_TEMP}/boot" -name "initrd.img-*" 2>/dev/null)
# # if [ -f initrd_file ]; then
# # ln -sf boot/${initrd_file} initrd.img
# # else
# # cp $initrd_file initrd.img
# # fi
2026-11-11 08:50:43 +08:00
# aml_log info "Found initrd: $initrd_file, BUT cp it from yct case......."
2026-08-13 11:28:40 +08:00
# # >>>>>>> build initrd fix debian requirement
# cp -f $BOOT_SCRIPTS/initrd.cpio.gz initrd.img
# build_ramfs
#is_ramfs_ready
local initrd_file=$(find "${ROOTFS_TEMP}/boot" -name "initrd.img-*" 2>/dev/null)
if [ -e $initrd_file ]; then
2026-11-11 08:50:43 +08:00
aml_log info "Found initrd: $initrd_file, "
2026-08-13 11:28:40 +08:00
local bootfile=$(basename $initrd_file)
ln -sf boot/$bootfile initrd.img
else
2026-11-11 08:50:43 +08:00
aml_log error "Error: NOT Found initrd: $initrd_file: $(ls ${ROOTFS_TEMP}/boot)"
2026-08-13 11:28:40 +08:00
exit 1
fi
echo 'export PS1="\$(whoami)@amlbian:\$(pwd)\$ "' >> ${ROOTFS_TEMP}/etc/profile
default_user_conf
}
function add_modules_booting() {
MOD_FILE="${ROOTFS_TEMP}/etc/modules-load.d/modules.conf"
#auto load modules
#s6 audio snd:amlogic_snd_codec_t9015 / amlogic_snd_codec_tl1
MODS+=(
amlogic-usb
pps_core
ptp
stmmac
dwmac-meson
stmmac-platform
dwmac-meson
dwmac-dwc-qos-eth
amlogic-dvb-demux
system_heap
mali
amlogic_snd_codec_dummy
amlogic_wireless
bluetooth
2026-08-25 10:02:36 +08:00
i2c_dev
2026-08-13 11:28:40 +08:00
)
if [ ! -f $MOD_FILE ]; then
touch "$MOD_FILE"
fi
2026-08-25 10:02:36 +08:00
for mod in "${MODS[@]}" "${VENDOR_MODS[@]}"; do
2026-08-13 11:28:40 +08:00
if ! grep -qx "$mod" "$MOD_FILE"; then
echo "$mod" >> "$MOD_FILE"
2026-11-11 08:50:43 +08:00
aml_log info "Added module $mod " "USER"
2026-08-13 11:28:40 +08:00
fi
done
2026-11-11 08:50:43 +08:00
aml_log info "All modules added to $MOD_FILE" "USER"
2026-08-13 11:28:40 +08:00
}
2026-08-25 10:02:36 +08:00
function aml_create_version_file() {
DATETIME="${DATETIME:-$(date -u +%Y%m%d%H%M%S)}"
local image_name="${BOARD}-${RELEASE}-${DATETIME}"
local branch="${BRANCH}"
local version="${RELEASE_VERSION:-0.0.0.0}"
local spin="${RELEASE_SPIN:-$(hostname)#$(whoami)}"
local build_time
build_time=$(date '+%Y-%m-%d %H:%M:%S')
local compiler_info="Unknown"
if [[ -n "${CC}" ]] && command -v "${CC%% *}" >/dev/null 2>&1; then
compiler_info="$(${CC} --version 2>/dev/null)"
fi
2026-11-11 08:50:43 +08:00
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt image_name $image_name"
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt branch $branch"
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt version $version"
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt spin $spin"
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt build_time $build_time"
aml_log debug "MEDIA-MODULES-INSTALL" "version.txt compiler $compiler_info"
2026-08-25 10:02:36 +08:00
cat > "${ROOTFS_TEMP}/version.txt" << EOF
imagename:${image_name}
BRANCH=${branch}
VERSION=${version}
SPIN=${spin}
BUILD_TIME="${build_time}"
Generated on $(date -u)
Compiler:
${compiler_info}
EOF
}
function aml_create_audio_default() {
2026-11-11 08:50:43 +08:00
aml_log info "aml_create_audio_default " "AUDIO_TYPE=${AUDIO_TYPE} hdmionly=${HDMIONLY}"
2026-08-25 10:02:36 +08:00
if [[ "${HDMIONLY}" == "yes" || "${AUDIO_TYPE}" == "HDMI" ]]; then
local DEFAULT_SINK="AML-HDMI-Sink"
else
local DEFAULT_SINK="AML-PCM-Sink"
fi
mkdir -p "$ROOTFS_TEMP/home/system/.local/state/wireplumber"
cat > "$ROOTFS_TEMP/home/system/.local/state/wireplumber/default-nodes" <<EOF
[default-nodes]
default.configured.audio.sink=${DEFAULT_SINK}
default.configured.audio.source=AML-PCM-Source
EOF
chroot "${ROOTFS_TEMP}" chown -R system:system /home/system/.local/state/wireplumber
}
2026-11-11 08:50:43 +08:00
function aml_clapper_fix() {
# ------------------------------------------------------------------
# 1. Clapper desktop: add V4L2_SET_AMLOGIC_DW_MODE=1 (full 4K output)
# ------------------------------------------------------------------
local CLAPPER_DESKTOP="${ROOTFS_TEMP}/usr/share/applications/com.github.rafostar.Clapper.desktop"
if [ -f "$CLAPPER_DESKTOP" ]; then
# Only add if not already present
if ! grep -q "V4L2_SET_AMLOGIC_DW_MODE" "$CLAPPER_DESKTOP"; then
sed -i "s|^Exec=.*|Exec=env CLAPPER_DEBIAN_SINGLE_INSTANCE_BREAK_DBUS_MPRIS=1 V4L2_SET_AMLOGIC_DW_MODE=1 clapper %U|" "$CLAPPER_DESKTOP"
fi
sed -i "s|^DBusActivatable=.*|DBusActivatable=false|" "$CLAPPER_DESKTOP"
aml_log info "aml_clapper_fix " "Clapper desktop: OK"
else
aml_log info "aml_clapper_fix " "Clapper desktop: SKIP (not installed)"
fi
# ------------------------------------------------------------------
# 2. Clapper player.js: set sink properties to reduce stutter
# - max-lateness=-1 : never drop frames (default 5ms is too strict)
# - qos=false : don't send QoS events upstream
# - ts-offset=-15ms : deliver frames 15ms early to catch vsync
# ------------------------------------------------------------------
local PLAYER_JS="${ROOTFS_TEMP}/usr/share/com.github.rafostar.Clapper/src/player.js"
if [ -f "$PLAYER_JS" ]; then
if ! grep -q "max-lateness" "$PLAYER_JS"; then
sed -i '/this.clappersink = vsink;/a\
vsink.set_property("max-lateness", -1);\
vsink.set_property("qos", false);\
vsink.set_property("ts-offset", -15000000);' "$PLAYER_JS"
fi
aml_log info "aml_clapper_fix " "Clapper player.js: OK"
else
aml_log info "aml_clapper_fix " "Clapper player.js: SKIP (not installed)"
fi
rm -rf "${ROOTFS_TEMP}/root/.cache/gstreamer-1.0 ${ROOTFS_TEMP}/home/system/.cache/gstreamer-1.0"
}
2026-08-13 11:28:40 +08:00
function default_user_conf() {
2026-11-11 08:50:43 +08:00
aml_log info "配置默认用户和系统设置" "USER"
2026-08-13 11:28:40 +08:00
2026-11-11 08:50:43 +08:00
# 1. 设置 root 密码,默认由 amlogic_common.inc 中 ROOT_PW 定义(1234),可编译参数覆盖
#aml_log "设置 root 密码为 1234" "USER" "info"
echo "root:${ROOT_PW}" | chroot "${ROOTFS_TEMP}" chpasswd
2026-08-13 11:28:40 +08:00
# 2. 创建默认用户 system,密码为 system
2026-11-11 08:50:43 +08:00
#aml_log "创建默认用户 system,密码为 system" "USER" "info"
2026-08-13 11:28:40 +08:00
chroot "${ROOTFS_TEMP}" useradd -m -s /bin/bash -G sudo,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,netdev system
echo "system:system" | chroot "${ROOTFS_TEMP}" chpasswd
# # 3. 设置默认时区为亚洲/上海(北京时区)
2026-11-11 08:50:43 +08:00
# aml_log info "设置默认时区为亚洲/上海" "USER"
2026-08-13 11:28:40 +08:00
# chroot "${ROOTFS_TEMP}" ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# echo "Asia/Shanghai" > "${ROOTFS_TEMP}/etc/timezone"
# # 4. 设置默认语言环境为中文 UTF-8
2026-11-11 08:50:43 +08:00
# aml_log info "设置默认语言环境为中文 UTF-8" "USER"
2026-08-13 11:28:40 +08:00
# echo "LANG=zh_CN.UTF-8" > "${ROOTFS_TEMP}/etc/default/locale"
# echo "LC_ALL=zh_CN.UTF-8" >> "${ROOTFS_TEMP}/etc/default/locale"
# 5. 配置阿里云源(针对 Ubuntu/Debian)
2026-11-11 08:50:43 +08:00
aml_log info "配置阿里云软件源" "USER"
2026-08-13 11:28:40 +08:00
if [ -f "${ROOTFS_TEMP}/etc/apt/sources.list" ]; then
# 备份原始源文件
cp "${ROOTFS_TEMP}/etc/apt/sources.list" "${ROOTFS_TEMP}/etc/apt/sources.list.bak"
# 检测系统版本并设置相应的阿里源
local release_name=$(chroot "${ROOTFS_TEMP}" lsb_release -cs 2>/dev/null || echo "jammy")
case "${release_name}" in
focal|jammy|noble|bookworm|bullseye)
cat > "${ROOTFS_TEMP}/etc/apt/sources.list" << EOF
# 阿里云镜像源
deb https://mirrors.aliyun.com/ubuntu/ ${release_name} main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${release_name}-security main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${release_name}-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${release_name}-proposed main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${release_name}-backports main restricted universe multiverse
EOF
;;
*)
2026-11-11 08:50:43 +08:00
aml_log warn "未知系统版本 ${release_name},使用默认源" "USER"
2026-08-13 11:28:40 +08:00
;;
esac
fi
# 6. 配置网络设置 - 启用 DHCP
2026-11-11 08:50:43 +08:00
aml_log info "配置网络 DHCP" "USER"
2026-08-13 11:28:40 +08:00
# Match both legacy eth0 (s6) and renamed end0/enX (A9 — systemd v252 net_id
# gives ID_NET_NAME_ONBOARD=end0 for fe498000.ethernet, so the kernel-default
# eth0 gets renamed; literal Name=eth0 then never matches).
touch "${ROOTFS_TEMP}/etc/systemd/network/10-wired.network"
cat > "${ROOTFS_TEMP}/etc/systemd/network/10-wired.network" << EOF
[Match]
Name=eth* en*
[Network]
DHCP=yes
EOF
if [ -f "${ROOTFS_TEMP}/etc/netplan/01-netcfg.yaml" ]; then
cat > "${ROOTFS_TEMP}/etc/netplan/01-netcfg.yaml" << EOF
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: true
dhcp6: true
optional: true
enp3s0:
dhcp4: true
dhcp6: true
optional: true
EOF
fi
2026-08-25 10:02:36 +08:00
aml_create_version_file
aml_create_audio_default
2026-08-13 11:28:40 +08:00
add_modules_booting
2026-08-25 10:02:36 +08:00
2026-08-13 11:28:40 +08:00
# 7. 配置 SSH 允许 root 登录和密码认证(便于调试)
2026-11-11 08:50:43 +08:00
aml_log info "配置 SSH 服务" "USER"
2026-08-13 11:28:40 +08:00
if [ -f "${ROOTFS_TEMP}/etc/ssh/sshd_config" ]; then
sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' "${ROOTFS_TEMP}/etc/ssh/sshd_config"
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication yes/' "${ROOTFS_TEMP}/etc/ssh/sshd_config"
sed -i 's/^PasswordAuthentication.*/PasswordAuthentication yes/' "${ROOTFS_TEMP}/etc/ssh/sshd_config"
fi
# 8. 禁用首次启动配置向导
2026-11-11 08:50:43 +08:00
aml_log info "禁用首次启动配置向导" "USER"
2026-08-13 11:28:40 +08:00
chroot "${ROOTFS_TEMP}" systemctl disable armbian-firstrun 2>/dev/null || true
chroot "${ROOTFS_TEMP}" systemctl mask armbian-firstrun 2>/dev/null || true
2026-08-25 10:02:36 +08:00
chroot "${ROOTFS_TEMP}" systemctl disable NetworkManager-wait-online 2>/dev/null || true
2026-08-13 11:28:40 +08:00
# 9. 设置主机名
2026-11-11 08:50:43 +08:00
aml_log info "设置主机名为 amlbian" "USER"
2026-08-13 11:28:40 +08:00
echo "amlbian" > "${ROOTFS_TEMP}/etc/hostname"
echo "127.0.0.1 localhost" > "${ROOTFS_TEMP}/etc/hosts"
echo "127.0.1.1 amlbian" >> "${ROOTFS_TEMP}/etc/hosts"
# 10. 配置 sudo 无需密码(便于调试)
2026-11-11 08:50:43 +08:00
aml_log info "配置 sudo 无需密码" "USER"
2026-08-13 11:28:40 +08:00
echo "system ALL=(ALL) NOPASSWD: ALL" > "${ROOTFS_TEMP}/etc/sudoers.d/99-system"
chmod 440 "${ROOTFS_TEMP}/etc/sudoers.d/99-system"
# 11. 启用自动登录(如果使用桌面环境)
if [ -d "${ROOTFS_TEMP}/etc/lightdm" ]; then
2026-11-11 08:50:43 +08:00
aml_log info "配置 lightdm 自动登录" "USER"
2026-08-13 11:28:40 +08:00
cat > "${ROOTFS_TEMP}/etc/lightdm/lightdm.conf.d/50-autologin.conf" << EOF
[Seat:*]
autologin-user=system
autologin-user-timeout=0
EOF
fi
2026-08-25 10:02:36 +08:00
if [[ "$AUTOLOGIN" == "yes" ]]; then
2026-11-11 08:50:43 +08:00
if [ -d "${ROOTFS_TEMP}/etc/gdm3" ]; then
local gdm_conf=""
if [ "${RELEASE}" = "bookworm" ]; then
gdm_conf="${ROOTFS_TEMP}/etc/gdm3/daemon.conf"
elif [ "${RELEASE}" = "noble" ]; then
gdm_conf="${ROOTFS_TEMP}/etc/gdm3/custom.conf"
fi
if [ -n "${gdm_conf}" ] && [ -f "${gdm_conf}" ]; then
aml_log info "配置 gdm3 自动登录: ${gdm_conf}" "USER"
sed -i \
-e 's|^[#[:space:]]*AutomaticLoginEnable[[:space:]]*=.*|AutomaticLoginEnable=true|' \
-e 's|^[#[:space:]]*AutomaticLogin[[:space:]]*=.*|AutomaticLogin=system|' \
"${gdm_conf}"
fi
else
aml_log warn "gdm3 未安装,跳过桌面自动登录配置" "USER"
2026-08-25 10:02:36 +08:00
fi
mkdir -p "${ROOTFS_TEMP}/etc/systemd/system/serial-getty@.service.d"
2026-11-11 08:50:43 +08:00
# 串口自动登录用户,默认由 amlogic_common.inc 中 AUTOLOGIN_USER 定义(system),可编译参数覆盖
2026-08-25 10:02:36 +08:00
cat >"${ROOTFS_TEMP}/etc/systemd/system/serial-getty@.service.d/autologin.conf" <<EOF
[Service]
ExecStart=
2026-11-11 08:50:43 +08:00
ExecStart=-/sbin/agetty --autologin ${AUTOLOGIN_USER} --keep-baud 921600,115200,57600,38400,9600 %I \$TERM
2026-08-25 10:02:36 +08:00
EOF
fi
# 设置GStreamer环境变量
2026-11-11 08:50:43 +08:00
aml_log info "设置GStreamer环境变量" "USER"
2026-08-25 10:02:36 +08:00
echo 'GST_PLUGIN_FEATURE_RANK=v4l2video26mpeg4dec:0' >> "${ROOTFS_TEMP}/etc/environment"
2026-11-11 08:50:43 +08:00
aml_clapper_fix
2026-08-13 11:28:40 +08:00
# 12. 更新软件包列表
2026-11-11 08:50:43 +08:00
aml_log info "更新软件包列表" "USER"
2026-08-13 11:28:40 +08:00
chroot "${ROOTFS_TEMP}" apt-get update 2>/dev/null || true
# 13 add service conf
local systemd_patch="${AMLBIAN_DIR}/patches/systemd"
local target_enable_service="${ROOTFS_TEMP}/etc/systemd/system/multi-user.target.wants/"
local system_service="/lib/systemd/system/"
#enable servie
ln -s ${system_service}/systemd-networkd.service ${target_enable_service}
2026-11-11 08:50:43 +08:00
ln -s ${system_service}/systemd-timesyncd.service ${target_enable_service}
2026-08-13 11:28:40 +08:00
ln -s ${system_service}/tee-supplicant.service ${target_enable_service}
2026-11-11 08:50:43 +08:00
ln -sf ${system_service}/videoFirmwarePreload.service ${target_enable_service}
2026-08-13 11:28:40 +08:00
ln -sf ${system_service}/tvserver.service ${target_enable_service}
local sys_network_conf="${ROOTFS_TEMP}/etc/systemd/system/systemd-networkd.service.d"
if [ ! -d "${sys_network_conf}" ]; then
2026-11-11 08:50:43 +08:00
aml_log info "Creating ${sys_network_conf}"
2026-08-13 11:28:40 +08:00
mkdir -p "${sys_network_conf}"
fi
cp ${systemd_patch}/systemd-networkd.conf ${sys_network_conf}/override.conf
cp ${systemd_patch}/amlenv.sh ${ROOTFS_TEMP}/etc/profile.d/
display_alert "默认用户配置完成" "USER" "success"
2026-08-25 10:02:36 +08:00
# default adb sh to bash
ln -sf /bin/bash "${ROOTFS_TEMP}/bin/sh"
2026-08-13 11:28:40 +08:00
# 配置 rc.local 以包含 rootenv 脚本
2026-11-11 08:50:43 +08:00
aml_log info "配置 rc.local 包含 rootenv 脚本" "USER"
2026-08-13 11:28:40 +08:00
local rc_local_file="${ROOTFS_TEMP}/etc/rc.local"
local rootenv_file="${AMLBIAN_DIR}/patches/systemd/rootenv"
if [ -f "${rc_local_file}" ]; then
# 如果 rc.local 存在,将 rootenv 内容追加到尾部
cat "${rootenv_file}" >> "${rc_local_file}"
2026-11-11 08:50:43 +08:00
aml_log info "已将 rootenv 追加到现有 rc.local 文件" "USER"
2026-08-13 11:28:40 +08:00
else
# 如果 rc.local 不存在,创建它并添加 rootenv 内容
mkdir -p "${ROOTFS_TEMP}/etc/"
# 创建标准的 rc.local 头部
cat > "${rc_local_file}" << 'EOF'
#!/bin/bash
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
EOF
# 添加 rootenv 内容
cat "${rootenv_file}" >> "${rc_local_file}"
# 确保脚本可执行
chmod +x "${rc_local_file}"
2026-11-11 08:50:43 +08:00
aml_log info "已创建 rc.local 文件并添加 rootenv 内容" "USER"
fi
if [ "${RT_LINUX}" = "yes" ]; then
#Force disable sleep and screen saver <<< ONLY for RT Preempt Linux Debug
# 1. 创建 keyfile 配置文件
mkdir -p "${ROOTFS_TEMP}/etc/dconf/db/local.d"
cat << 'EOF' > "${ROOTFS_TEMP}/etc/dconf/db/local.d/00-disable-auto-suspend"
[org/gnome/desktop/session]
idle-delay=uint32 0
[org/gnome/settings-daemon/plugins/power]
sleep-inactive-ac-type='nothing'
sleep-inactive-battery-type='nothing'
EOF
mkdir -p "${ROOTFS_TEMP}/etc/dconf/profile"
cat << 'EOF' > "${ROOTFS_TEMP}/etc/dconf/profile/user"
user-db:user
system-db:local
EOF
chroot "${ROOTFS_TEMP}" dconf update
2026-08-13 11:28:40 +08:00
fi
}
function build_ramfs() {
local BOOT_SCRIPTS=${AMLBIAN_DIR}/config/bootscripts
local initrd_source="${BOOT_SCRIPTS}/initrd.cpio.gz"
local ramdisk_dir="${RAMFS_TEMP}/modules/ramdisk"
# 确保目录存在
if [ -d $RAMFS_TEMP ]; then
mkdir -p $RAMFS_TEMP
else
mkdir -p $RAMFS_TEMP
fi
# 1. 解压 initrd.cpio.gz 到 RAMFS_TEMP
2026-11-11 08:50:43 +08:00
aml_log info "解压 initrd: ${initrd_source} 到 ${RAMFS_TEMP}" "RAMFS"
2026-08-13 11:28:40 +08:00
if [ -f "${initrd_source}" ]; then
cd "${RAMFS_TEMP}"
gunzip -c "${initrd_source}" | cpio -idm --quiet
cd - > /dev/null
else
2026-11-11 08:50:43 +08:00
aml_log error "initrd 文件不存在: ${initrd_source}" "RAMFS"
2026-08-13 11:28:40 +08:00
return 1
fi
# 2. 删除 ramdisk 目录下的所有 ko 文件
2026-11-11 08:50:43 +08:00
aml_log info "删除 ${ramdisk_dir} 下的所有 ko 文件" "RAMFS"
2026-08-13 11:28:40 +08:00
if [ -d "${ramdisk_dir}" ]; then
find "${ramdisk_dir}" -name "*.ko" -type f -delete
else
mkdir -p "${ramdisk_dir}"
fi
# 3. 从 ROOTFS_TEMP/lib/modules 查找并复制指定的 ko 文件
2026-11-11 08:50:43 +08:00
aml_log info "从 ${ROOTFS_TEMP}/lib/modules 查找并复制指定的 ko 文件" "RAMFS"
2026-08-13 11:28:40 +08:00
local ko_files=(
"amlogic-inphy.ko"
"amlogic-input.ko"
"pwm-regulator.ko"
"amlogic-irblaster.ko"
"amlogic-mailbox.ko"
"amlogic-memory-debug.ko"
"tee.ko"
"amlogic-mmc.ko"
)
for ko in "${ko_files[@]}"; do
local source_ko=$(find "${ROOTFS_TEMP}/lib/modules" -name "${ko}" -type f 2>/dev/null | head -1)
if [ -n "${source_ko}" ] && [ -f "${source_ko}" ]; then
2026-11-11 08:50:43 +08:00
aml_log info "找到并复制: ${ko}" "RAMFS"
2026-08-13 11:28:40 +08:00
cp -v "${source_ko}" "${ramdisk_dir}/"
else
2026-11-11 08:50:43 +08:00
aml_log warn "未找到: ${ko}" "RAMFS"
2026-08-13 11:28:40 +08:00
fi
done
# 4. 重新打包 ramdisk 目录为 cpio.gz 文件
2026-11-11 08:50:43 +08:00
aml_log info "重新打包 ${ramdisk_dir} 为 cpio.gz 文件" "RAMFS"
2026-08-13 11:28:40 +08:00
local output_initrd="${ROOTFS_TEMP}/initrd.cpio.gz"
if [ -d "${ramdisk_dir}" ]; then
cd "${ramdisk_dir}"
find . -type f -o -type l | cpio -o -H newc --quiet | gzip -9 > "${output_initrd}"
cd - > /dev/null
display_alert "新的 initrd 已创建: ${output_initrd}" "RAMFS" "success"
else
2026-11-11 08:50:43 +08:00
aml_log error "ramdisk 目录不存在: ${ramdisk_dir}" "RAMFS"
2026-08-13 11:28:40 +08:00
return 1
fi
if [ -e ${output_initrd} ];then
2026-11-11 08:50:43 +08:00
aml_log info "Mv initrd as initrd.img to boot"
2026-08-13 11:28:40 +08:00
mv ${output_initrd} ${ROOTFS_TEMP}/initrd.img
fi
}
## Prepare gpt table
function build_gpttable() {
2026-11-11 08:50:43 +08:00
aml_log info "Make gpt-partition ......"
aml_log debug "GPT_TABLE" "$GPT_TABLE"
2026-08-13 11:28:40 +08:00
local size=$1
$UTILS_DIR/makegpt -o gpt_out.bin -s $size -v 2 --partitions ${AMLBIAN_DIR}/config/gpt-partition/${GPT_TABLE}
cp gpt_out.bin $BUILD_IMAGES/gpt.img
2026-11-11 08:50:43 +08:00
aml_log info "built gpt done $(ls $BUILD_IMAGES)"
2026-08-13 11:28:40 +08:00
rm -rf gpt_out.bin
}
## creates image file, partitions and fs
function prepare_partitions()
{
2026-11-11 08:50:43 +08:00
aml_log info "Preparing image file for rootfs..."
2026-08-13 11:28:40 +08:00
EXT4_MKOPTS="-q -F -L ROOTFS -m 2 -O ^64bit,^metadata_csum"
BOOT_EXT4_MKOPTS="-q -F -L BOOT -m 2 -O ^64bit,^metadata_csum"
if [[ $(lsb_release -sc) =~ bionic|focal|jammy|noble ]]; then
EXT4_MKOPTS="-q -F -L ROOTFS -m 2 -O ^64bit,^metadata_csum"
BOOT_EXT4_MKOPTS="-q -F -L BOOT -m 2 -O ^64bit,^metadata_csum"
elif [[ $(lsb_release -sc) == "xenial" ]]; then
EXT4_MKOPTS="-q -F -L ROOTFS -m 2"
BOOT_EXT4_MKOPTS="-q -F -L BOOT -m 2"
fi
# calculate rootfs size
local rootfs_size=$(du -sm $ROOTFS_TEMP/ | cut -f1) # MiB
2026-11-11 08:50:43 +08:00
aml_log info "Current rootfs cache size: $rootfs_size MiB"
2026-08-13 11:28:40 +08:00
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
2026-11-11 08:50:43 +08:00
aml_log info "Using user-defined image size: $FIXED_IMAGE_SIZE MiB"
2026-08-13 11:28:40 +08:00
local rootfs_image_size=$FIXED_IMAGE_SIZE
# basic sanity check
if [[ $ROOTFS_TYPE != nfs && $rootfs_image_size -lt $rootfs_size ]]; then
2026-11-11 08:50:43 +08:00
aml_log error "User defined image size is too small - $rootfs_image_size <= $rootfs_size"
exit 1
2026-08-13 11:28:40 +08:00
fi
else
# Hardcoded overhead +30% for ext4 is needed for desktop images,
# file creation and align the size up to 4MiB
if [[ "$DISTRIB_TYPE" != "server" ]] && [[ "$DISTRIB_TYPE" != "minimal" ]]; then
# Desktop image size
local rootfs_image_size=$(bc -l <<< "scale=0; ((($rootfs_size * 1.3) / 1 + 0) / 4 + 1) * 4")
else
# Server image size
local rootfs_image_size=$(bc -l <<< "scale=0; ((($rootfs_size * 1.2) / 1 + 0) / 4 + 1) * 4")
fi
fi
if [ "$INSTALL_TYPE" == "EMMC" ]; then
2026-11-11 08:50:43 +08:00
aml_log info "Creating eMMC rootfs image..."
2026-08-13 11:28:40 +08:00
rm -rf ${BUILD_IMAGES}/rootfs.img
dd if=/dev/zero of=$BUILD_IMAGES/rootfs.img bs=1M count=0 seek=$rootfs_image_size
mkfs.ext4 $EXT4_MKOPTS $BUILD_IMAGES/rootfs.img
rm -rf $ROOTFS && install -d $ROOTFS
2026-11-11 08:50:43 +08:00
losetup -j "" 2>/dev/null | cut -d: -f1 | while read -r dev; do
if [ -n "$dev" ]; then
aml_log info "发现空闲设备 $dev, 正在解绑清理..."
losetup -d "$dev"
fi
done
2026-08-13 11:28:40 +08:00
mount -o loop $BUILD_IMAGES/rootfs.img $ROOTFS
local rootfs_uuid="UUID=$(blkid -s UUID -o value $BUILD_IMAGES/rootfs.img)"
2026-11-11 08:50:43 +08:00
aml_log debug "prepare_partitions 1" "rootfs_uuid=${rootfs_uuid}"
2026-08-13 11:28:40 +08:00
elif [ "$INSTALL_TYPE" == "SD-USB" ]; then
rm -rf ${BUILD_IMAGES}/${IMAGE_FILE_NAME}
IMAGE_SIZE=$((rootfs_image_size + 300)) # SD/USB image size = BOOT(256MB) + ROOTFS
2026-11-11 08:50:43 +08:00
aml_log info "Create SD/USB image..."
2026-08-13 11:28:40 +08:00
dd if=/dev/zero of=${BUILD_IMAGES}/${IMAGE_FILE_NAME} bs=1M count=0 seek=$IMAGE_SIZE
if [ "$GENERIC_IMAGE_PARTITION_TABLE" != "gpt" ]; then
fdisk "${BUILD_IMAGES}/${IMAGE_FILE_NAME}" <<-EOF
o
n
p
1
32768
524287
a
t
b
n
p
2
524288
p
w
EOF
else
parted -s ${BUILD_IMAGES}/${IMAGE_FILE_NAME} mklabel gpt
parted -s ${BUILD_IMAGES}/${IMAGE_FILE_NAME} unit s mkpart boot 32768 524287
parted -s ${BUILD_IMAGES}/${IMAGE_FILE_NAME} unit s mkpart rootfs 524288 "100%"
#parted -s ${BUILD_IMAGES}/${IMAGE_FILE_NAME} set 1 boot on
fi
IMAGE_LOOP_DEV="$(losetup --show -f ${BUILD_IMAGES}/${IMAGE_FILE_NAME})"
if [[ -z $IMAGE_LOOP_DEV ]]; then
2026-11-11 08:50:43 +08:00
aml_log error "Unable to find free loop device!"
exit 1
2026-08-13 11:28:40 +08:00
fi
export IMAGE_LOOP_DEV
IMAGE_LOOP_DEV_BOOT="${IMAGE_LOOP_DEV}p1"
IMAGE_LOOP_DEV_ROOTFS="${IMAGE_LOOP_DEV}p2"
partprobe "${IMAGE_LOOP_DEV}"
check_loop_device "$IMAGE_LOOP_DEV"
if [ "$BOOTFS_TYPE" == "vfat" ]; then
mkfs.vfat -n BOOT "${IMAGE_LOOP_DEV_BOOT}"
elif [ "$BOOTFS_TYPE" == "ext4" ]; then
mkfs.ext4 $BOOT_EXT4_MKOPTS "${IMAGE_LOOP_DEV_BOOT}"
fi
mkfs.ext4 $EXT4_MKOPTS "${IMAGE_LOOP_DEV_ROOTFS}"
rm -rf $ROOTFS && mkdir -p $ROOTFS
mount "${IMAGE_LOOP_DEV_ROOTFS}" $ROOTFS
mkdir -p $ROOTFS/boot
mount -t $BOOTFS_TYPE "${IMAGE_LOOP_DEV_BOOT}" $ROOTFS/boot
local rootfs_uuid="UUID=$(blkid -s UUID -o value $IMAGE_LOOP_DEV_ROOTFS)"
local bootfs_uuid="UUID=$(blkid -s UUID -o value $IMAGE_LOOP_DEV_BOOT)"
fi
rm -rf $ROOTFS/lost+found
rm -rf $ROOTFS/boot/lost+found
2026-11-11 08:50:43 +08:00
aml_log info "Copying files to root directory..."
2026-08-13 11:28:40 +08:00
rsync_progress="--info=progress2,stats1"
[ "$NO_PROGRESS" ] && \
rsync_progress=
rsync -aHWXh --exclude="/boot/*" --exclude="/dev/*" --exclude="/proc/*" --exclude="/run/*" --exclude="/tmp/*" \
--exclude="/sys/*" $rsync_progress $ROOTFS_TEMP/ $ROOTFS/
# rsync /boot
2026-11-11 08:50:43 +08:00
aml_log info "Copying files to /boot directory..."
2026-08-13 11:28:40 +08:00
if [[ $(findmnt --target $ROOTFS/boot -o FSTYPE -n) == vfat ]]; then
# fat32
rsync -rLtWh $rsync_progress $ROOTFS_TEMP/boot $ROOTFS
else
# ext4
rsync -aHWXh $rsync_progress $ROOTFS_TEMP/boot $ROOTFS
fi
if [[ -f $ROOTFS_TEMP/boot/env.txt ]]; then
sed -i s/rootdev=.*/rootdev=$rootfs_uuid/g $ROOTFS/boot/env.txt
2026-11-11 08:50:43 +08:00
aml_log debug "prepare_partitions 2" "rootfs_uuid=${rootfs_uuid}"
2026-08-13 11:28:40 +08:00
fi
if [[ -f $ROOTFS_TEMP/boot/uEnv.txt ]]; then
sed -i s/rootdev=root=.*/rootdev=root=$rootfs_uuid/g $ROOTFS/boot/uEnv.txt
2026-11-11 08:50:43 +08:00
aml_log debug "prepare_partitions 3" "rootfs_uuid=${rootfs_uuid}"
2026-08-13 11:28:40 +08:00
if [ "$INSTALL_TYPE" == "SD-USB" ]; then
sed -i s/partition_type=.*/partition_type=generic/g $ROOTFS/boot/uEnv.txt
else
sed -i s/partition_type=.*/partition_type=vendor/g $ROOTFS/boot/uEnv.txt
fi
fi
# create /etc/fstab
echo "# <file system> <mount point> <type> <options> <dump> <pass>" > $ROOTFS/etc/fstab
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> $ROOTFS/etc/fstab
echo "$rootfs_uuid / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide 0 1" >> $ROOTFS/etc/fstab
if [ "$INSTALL_TYPE" == "SD-USB" ]; then
if [ "$BOOTFS_TYPE" == "vfat" ]; then
echo "$bootfs_uuid /boot vfat defaults 0 2" >> $ROOTFS/etc/fstab
else
echo "$bootfs_uuid /boot ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide 0 1" >> $ROOTFS/etc/fstab
fi
fi
if [ "$BUILD_TYPE" == develop ]; then
# DEBUG: print free space
2026-11-11 08:50:43 +08:00
aml_log debug "Free space"
2026-08-13 11:28:40 +08:00
eval 'df -h'
fi
sync
if [ "$INSTALL_TYPE" == "SD-USB" ]; then
umount $ROOTFS/boot
losetup -d "${IMAGE_LOOP_DEV}"
fi
umount $ROOTFS
}
function build_rootfs() {
build_gpttable 16G
## Logo
$UTILS_DIR/res_packer -r $AMLBIAN_DIR/patches/logo/bmp $BUILD_IMAGES/logo.img
add_amlbian_conf
#Maybe move to initrd compile function
# compile_initrd_amlbian_main <<<<<<<<<<<<<<<<<<<<<<<,,, TODO: build it from rootfs ???
prepare_partitions
}
function pack_image_platform() {
if [ "$1" == "uboot-image" ]; then
PACK_UBOOT_IMAGE="yes"
else
PACK_UBOOT_IMAGE="no"
fi
cd ${ROOT}
2026-11-11 08:50:43 +08:00
aml_log info "Image install type: $INSTALL_TYPE"
2026-08-13 11:28:40 +08:00
if [ "$INSTALL_TYPE" == "EMMC" ]; then
## Fixup upgrade dtb link
[ -d "$BOARD_CONFIG"/image-update ] || {
2026-11-11 08:50:43 +08:00
aml_log error "image-update not exist"
exit 1
2026-08-13 11:28:40 +08:00
}
for UTILS_DIR_ in $UTILS_DIR; do
[ -d "$UTILS_DIR_" ] || {
2026-11-11 08:50:43 +08:00
aml_log error "UTILS_DIR not exist: $UTILS_DIR"
exit 1
2026-08-13 11:28:40 +08:00
}
done
BUILD=${BUILD_DEBS}
D="$BUILD"/image-update
rm -rf $D
cp -rf "$BOARD_CONFIG"/image-update/$WORK_BOARD $D
cp -rf "$BOARD_CONFIG"/image-update/aml_sdc_burn.ini $D
cp -rf "$BOARD_CONFIG"/image-update/fake-rootfs.img $D
UBOOT_IMAGE_DIR="$ROOTFS_TEMP/usr/lib/linux-u-boot-$BOARD-amlbian"
#display_alert "uboot include: $(ls $UBOOT_IMAGE_DIR)"
DTBS_DIR="$ROOTFS_TEMP/boot"
2026-11-11 08:50:43 +08:00
aml_log debug "UTILS_DIR $UTILS_DIR; D: $D"
aml_log debug "DEBUG1: $(ls $BUILD_IMAGES/)"
aml_log debug "DEBUG2: $(ls $UBOOT_IMAGE_DIR/)"
2026-08-13 11:28:40 +08:00
# ln -fs "$BUILD_IMAGES/logo.img" "$D"/logo.img
# ln -fs "$DTBS_DIR/$KERNEL_DEVICETREE" "$D"/amlbian.dtb
# ln -fs "$UBOOT_IMAGE_DIR"/u-boot.bin.signed "$D"/u-boot.bin.signed
# ln -fs "$UBOOT_IMAGE_DIR"/u-boot.bin.sd.bin.signed "$D"/u-boot.bin.sd.bin.signed
# ln -fs "$UBOOT_IMAGE_DIR"/u-boot.bin.usb.signed "$D"/u-boot.bin.usb.signed
# 检查 logo.img
SOURCE_LOGO="$BUILD_IMAGES/logo.img"
TARGET_LOGO="$D/logo.img"
if [ -e "$SOURCE_LOGO" ]; then
ln -sf "$SOURCE_LOGO" "$TARGET_LOGO"
2026-11-11 08:50:43 +08:00
aml_log info "INFO: Linked $SOURCE_LOGO -> $TARGET_LOGO"
2026-08-13 11:28:40 +08:00
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_LOGO. ($SOURCE_LOGO)"
2026-08-13 11:28:40 +08:00
exit 1
fi
2026-11-11 08:50:43 +08:00
2026-08-13 11:28:40 +08:00
# 检查 amlbian.dtb
2026-11-11 08:50:43 +08:00
SOURCE_DTB="$DTBS_DIR/multi.dtb"
2026-08-13 11:28:40 +08:00
TARGET_DTB="$D/amlbian.dtb"
if [ -e "$SOURCE_DTB" ]; then
ln -sf "$SOURCE_DTB" "$TARGET_DTB"
2026-11-11 08:50:43 +08:00
aml_log info "INFO: Linked $SOURCE_DTB -> $TARGET_DTB"
2026-08-13 11:28:40 +08:00
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_DTB. ($SOURCE_DTB)"
2026-08-13 11:28:40 +08:00
exit 1
fi
# 检查 u-boot.bin.signed
SOURCE_UBOOT_BIN="$UBOOT_IMAGE_DIR/u-boot.bin.signed"
TARGET_UBOOT_BIN="$D/u-boot.bin.signed"
if [ -e "$SOURCE_UBOOT_BIN" ]; then
ln -sf "$SOURCE_UBOOT_BIN" "$TARGET_UBOOT_BIN"
2026-11-11 08:50:43 +08:00
aml_log info "INFO: Linked $SOURCE_UBOOT_BIN -> $TARGET_UBOOT_BIN"
2026-08-13 11:28:40 +08:00
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_BIN. ($SOURCE_UBOOT_BIN)"
2026-08-13 11:28:40 +08:00
exit 1
fi
# 检查 u-boot.bin.sd.bin.signed
SOURCE_UBOOT_SD="$UBOOT_IMAGE_DIR/u-boot.bin.sd.bin.signed"
TARGET_UBOOT_SD="$D/u-boot.bin.sd.bin.signed"
if [ -e "$SOURCE_UBOOT_SD" ]; then
ln -sf "$SOURCE_UBOOT_SD" "$TARGET_UBOOT_SD"
2026-11-11 08:50:43 +08:00
aml_log info "INFO: Linked $SOURCE_UBOOT_SD -> $TARGET_UBOOT_SD"
2026-08-13 11:28:40 +08:00
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_SD. ($SOURCE_UBOOT_SD)"
2026-08-13 11:28:40 +08:00
exit 1
fi
# 检查 u-boot.bin.usb.signed
SOURCE_UBOOT_USB="$UBOOT_IMAGE_DIR/u-boot.bin.usb.signed"
TARGET_UBOOT_USB="$D/u-boot.bin.usb.signed"
if [ -e "$SOURCE_UBOOT_USB" ]; then
ln -sf "$SOURCE_UBOOT_USB" "$TARGET_UBOOT_USB"
2026-11-11 08:50:43 +08:00
aml_log info "INFO: Linked $SOURCE_UBOOT_USB -> $TARGET_UBOOT_USB"
2026-08-13 11:28:40 +08:00
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_USB. ($SOURCE_UBOOT_USB)"
2026-08-13 11:28:40 +08:00
exit 1
fi
2026-11-11 08:50:43 +08:00
aml_log debug "DEBUG3: $(ls $D/)"
2026-08-13 11:28:40 +08:00
## pack gpt.img
if [ -n "$GPT_TABLE" ]; then
ln -fs "$BUILD_IMAGES/gpt.img" "$D"/gpt.img
sed -i '/usb_flow/a\file="gpt.img" main_type="bin" sub_type="gpt" file_type="normal"' "$D"/package.conf
fi
## Fixup rootfs.img
if [ "$PACK_UBOOT_IMAGE" != "yes" ]; then
ln -fs "$BUILD_IMAGES"/rootfs.img "$D"/rootfs.img
IMAGE_FILE_NAME="${WORK_BOARD}${DESKTOP_ENVIRONMENT:+-${DESKTOP_ENVIRONMENT}}${IMAGE_VERSION:+-${IMAGE_VERSION}}-emmc.img"
IMAGE_FILE_NAME=${IMAGE_FILE_NAME,,}
else
IMAGE_FILE_NAME="${WORK_BOARD}-uboot-${UBOOT}${IMAGE_VERSION:+-${IMAGE_VERSION}}-emmc.img"
IMAGE_FILE_NAME=${IMAGE_FILE_NAME,,}
ln -fs fake-rootfs.img "$D"/rootfs.img
fi
#cd - > /dev/null
2026-11-11 08:50:43 +08:00
aml_log debug "DEBUG4: $(ls -l $D/)"
aml_log debug "DEBUG5: $UTILS_DIR/aml_image_v2_packer -r $D/package.conf $D $BUILD_IMAGES/${IMAGE_FILE_NAME}"
2026-08-13 11:28:40 +08:00
$UTILS_DIR/aml_image_v2_packer -r $D/package.conf $D $BUILD_IMAGES/${IMAGE_FILE_NAME}
elif [ "$INSTALL_TYPE" == "SD-USB" ]; then
if [ "$PACK_UBOOT_IMAGE" == "yes" ]; then
IMAGE_FILE_NAME="${WORK_BOARD}-uboot-${UBOOT}${IMAGE_VERSION:+-${IMAGE_VERSION}}-sd.img"
IMAGE_FILE_NAME=${IMAGE_FILE_NAME,,}
2026-11-11 08:50:43 +08:00
aml_log info "Create U-Boot SD image..."
2026-08-13 11:28:40 +08:00
dd if=/dev/zero of=${BUILD_IMAGES}/${IMAGE_FILE_NAME} bs=1M count=0 seek=4 > /dev/null 2>&1
fi
write_uboot_platform "$UBOOT_IMAGE_DIR" "$BUILD_IMAGES/$IMAGE_FILE_NAME"
else
2026-11-11 08:50:43 +08:00
aml_log error "ERROR Unsupported install type: '$INSTALL_TYPE'"
exit 1
2026-08-13 11:28:40 +08:00
fi
echo ""
2026-11-11 08:50:43 +08:00
aml_log info "IMAGE: $BUILD_IMAGES/$IMAGE_FILE_NAME is ready!"
2026-08-13 11:28:40 +08:00
}
## compress_image
function compress_image() {
[[ $COMPRESS_IMAGE != yes ]] && return
echo ""
2026-11-11 08:50:43 +08:00
aml_log info "Compressing image '$BUILD_IMAGES/$IMAGE_FILE_NAME' to '$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4' ..."
2026-08-13 11:28:40 +08:00
rm -rf "$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4"
2026-11-11 08:50:43 +08:00
aml_log info "lz4 $BUILD_IMAGES/$IMAGE_FILE_NAME>$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4"
2026-08-13 11:28:40 +08:00
lz4 $BUILD_IMAGES/$IMAGE_FILE_NAME>$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4
echo ""
2026-11-11 08:50:43 +08:00
aml_log info "Compressed image: $BUILD_IMAGES/$IMAGE_FILE_NAME.lz4 is ready!"
2026-08-13 11:28:40 +08:00
}
function fix_perms() {
# fix files perm for original user
[ -e "$1" ] || return 0
#display_alert "fix_perms_check: $1 [$UID:$UID]"
if [ "$SUDO_UID" ]; then
find "$1" ! -user $SUDO_UID -exec chown $SUDO_UID:$SUDO_GID {} \;
return
else
if find "$1" ! -user $UID | grep -q -m1 "" ; then
2026-11-11 08:50:43 +08:00
aml_log debug "fix_perms: $1 [$UID:$UID]"
2026-08-13 11:28:40 +08:00
$sudo chown -R $UID:$UID "$1"
fi
return
fi
return 0
}
function post_create_image() {
cleanup
# add some safety ;-) before make rm -rf
# umount_chroot "$ROOTFS"
# umount_chroot "$BUILD_IMAGES"/.tmp
# remove tmp files
#rm -rf "$BUILD_IMAGES"/.tmp
fix_perms "$BUILD_IMAGES"
#TODO: if need custom_script
# upload images
# TODO: upload?
# if [ "$UPLOAD_SCRIPT" -a -x "$UPLOAD_SCRIPT" ]; then
# echo BUILD_IMAGES="$BUILD_IMAGES" \
# IMAGE_FILE_NAME="$IMAGE_FILE_NAME" \
# "$UPLOAD_SCRIPT"
# BUILD_IMAGES="$BUILD_IMAGES" \
# IMAGE_FILE_NAME="$IMAGE_FILE_NAME" \
# "$UPLOAD_SCRIPT"
# return
# fi
# if [ "$UPLOAD" -a -d "$UPLOAD" ]; then
# for f in "$BUILD_IMAGES/"$IMAGE_FILE_NAME*; do
# if [ -e "$f" ]; then
# display_alert "UPLOAD : $f to $UPLOAD"
# if [ "$SUDO_UID" ]; then
# sudo -u $SUDO_USER mv "$f" "$UPLOAD"
# else
# mv "$f" "$UPLOAD"
# fi
# fi
# done
# fi
}
function amlbian_package_img() {
2026-11-11 08:50:43 +08:00
aml_log info "Start package img" "IMG"
2026-08-13 11:28:40 +08:00
# local compile_script="${SRC}/build/compile.sh"
# local amlbian_output_dir="${SRC}/amlbian/output"
# local build_output_debs_dir="${SRC}/build/output/debs"
COMP_DIR="${SRC}/../aml-comp"
BUILD_IMAGES="${SRC}/output/images"
ROOTFS_TEMP="${SRC}/output/img/.tmp/rootfs"
ROOTFS="${SRC}/output/img/rootfs"
BUILD_DEBS="${SRC}/output/"
UTILS_DIR="${SRC}/output/utils"
AMLBIAN_DIR="${SRC}/userpatches"
BOARD_CONFIG="${AMLBIAN_DIR}/config/boards/"
RAMFS_TEMP="${SRC}/output/img/.tmp/ramfs"
prepare_tools
prepare_rootfs
build_rootfs
pack_image_platform
compress_image
post_create_image
2026-11-11 08:50:43 +08:00
aml_log info "End package img" "IMG"
2026-08-13 11:28:40 +08:00
}
export -f amlbian_package_img
export -f amlbian_additional_insatll
# ==============================================================================
# End of function-img.sh
2026-11-11 08:50:43 +08:00
# ==============================================================================