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

1598 lines
56 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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
aml_log error "ROOTFS_TEMP is not set"
return 1
fi
if [[ -z "$pkgs" ]]; then
aml_log warn "no packages provided to install"
return 0
fi
# 防止空 rootfs
if [[ ! -d "$rootfs" ]]; then
aml_log error "rootfs not found" "$rootfs"
return 1
fi
mount_chroot $rootfs
aml_log info "Installing packages in rootfs: $rootfs"
aml_log debug "Packages: $pkgs"
# 核心执行:进入 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() {
aml_log info "Installing additional packages from PACKAGE_LIST_AML: ${PACKAGE_LIST_AML}"
local pkgs="${PACKAGE_LIST_AML}"
local rootfs="${ROOTFS_TEMP:-$SDCARD}"
if [[ -z "$pkgs" ]]; then
aml_log info "PACKAGE_LIST_AML is empty, skip AML additional install"
return 0
fi
if [[ ! -d "$rootfs" ]]; then
aml_log error "rootfs not found" "$rootfs"
return 1
fi
mount_chroot $rootfs
aml_log info "INFO: AML additional install in rootfs: $rootfs"
aml_log info "INFO: packages: $pkgs"
for pkg in $pkgs; do
if [[ -z "$pkg" ]]; then
continue
fi
aml_log info "Installing AML package: $pkg"
chroot "$rootfs" /bin/bash -c "
export DEBIAN_FRONTEND=noninteractive
export TMPDIR=/tmp
apt-get update -y
apt-get install -y $pkg
" || {
aml_log warn "failed to install AML package" "$pkg"
continue
}
done
umount_chroot $rootfs
aml_log info "Install PACKAGE_LIST_AML done"
}
function install_aml_deb(){
local package=$1
local name=$(basename $package)
[ -e "$package" ] || {
aml_log warn "Installing $name in chroot skipped ($package not exist)"
return 0
}
cp $package $ROOTFS_TEMP/root/$name
aml_log info "Installing $name in chroot... stand install_aml_deb"
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
aml_log debug "[SKIP Install] >> Udev disable in BUILD_UNITS"
return
fi
local udev_file=$(find "${BUILD_DEBS}" -name "aml-udev_*.deb" 2>/dev/null)
aml_log info "install udev BUILD_DEBS ${BUILD_DEBS} udev_file ${udev_file}"
install_aml_deb ${udev_file}
}
function install_modules_load_amlbian() {
if ! is_unit_enabled "modules-load"; then
aml_log debug "[SKIP Install] >> modules-load disable in BUILD_UNITS"
return
fi
local modules_file=$(find "${BUILD_DEBS}" -name "aml-modules-load_*.deb" 2>/dev/null)
aml_log info "install module-load BUILD_DEBS ${BUILD_DEBS} modules_file ${udev_file}"
install_aml_deb ${modules_file}
}
function install_gpu_amlbian() {
if ! is_unit_enabled "gpu"; then
aml_log info "[SKIP Install] >> gpu disable in BUILD_UNITS"
return
fi
local gpu_file=$(find "${BUILD_DEBS}" -name "aml-gpu-${GPU_ARCH}*.deb" 2>/dev/null)
aml_log info "install gpu BUILD_DEBS ${BUILD_DEBS} gpu_file ${gpu_file}"
install_aml_deb $gpu_file
local libgles_file=$(find "${BUILD_DEBS}" -name "aml-libgles-eabihf-${GPU_MODEL}*.deb" 2>/dev/null)
aml_log info "install gpu BUILD_DEBS ${BUILD_DEBS} libgles_file ${libgles_file}"
install_aml_deb $libgles_file
}
function install_npu_amlbian() {
if ! is_unit_enabled "npu"; then
aml_log info "[SKIP Install] >> npu disable in BUILD_UNITS"
return
fi
local npu_common_file=$(find "${BUILD_DEBS}" -name "aml-npu-common_*.deb" 2>/dev/null)
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} npu_common_file ${npu_common_file}"
install_aml_deb $npu_common_file
local adla_driver_file=$(find "${BUILD_DEBS}" -name "aml-adla-driver_*.deb" 2>/dev/null)
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} adla_driver_file ${adla_driver_file}"
install_aml_deb $adla_driver_file
local adla_lib_file=$(find "${BUILD_DEBS}" -name "aml-adla-lib_*.deb" 2>/dev/null)
aml_log info "install npu BUILD_DEBS ${BUILD_DEBS} adla_lib_file ${adla_lib_file}"
install_aml_deb $adla_lib_file
}
function install_wifi_amlbian() {
if ! is_unit_enabled "wifi"; then
aml_log info "[SKIP Install] >> wifi disable in BUILD_UNITS"
return
fi
local wifi_file=$(find "${BUILD_DEBS}" -name "aml-wifi-w*.deb" 2>/dev/null)
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wifi_file ${wifi_file}"
install_aml_deb $wifi_file
local wifi_common_file=$(find "${BUILD_DEBS}" -name "aml-wifi-common_*.deb" 2>/dev/null)
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wifi_common_file ${wifi_common_file}"
install_aml_deb $wifi_common_file
local wpa_file=$(find "${BUILD_DEBS}" -name "aml-wpa-supplicant-config_*.deb" 2>/dev/null)
aml_log info "install wifi BUILD_DEBS ${BUILD_DEBS} wpa_file ${wpa_file}"
install_aml_deb $wpa_file
}
function install_bt_amlbian() {
if ! is_unit_enabled "bt"; then
aml_log info "[SKIP Install] >> bt disable in BUILD_UNITS"
return
fi
local hciattach_file=$(find "${BUILD_DEBS}" -name "aml-hciattach*.deb" 2>/dev/null)
aml_log info "install hciattach BUILD_DEBS ${BUILD_DEBS} hciattach_file ${hciattach_file}"
install_aml_deb $hciattach_file
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}"
install_aml_deb $bt_driver
}
function install_isp_amlbian() {
if ! is_unit_enabled "isp"; then
aml_log info "[SKIP Install] >> isp disable in BUILD_UNITS"
return
fi
local isp_driver_file=$(find "${BUILD_DEBS}" -name "aml-isp_*.deb" 2>/dev/null)
aml_log info "install isp BUILD_DEBS ${BUILD_DEBS} isp_driver_file ${isp_driver_file}"
install_aml_deb $isp_driver_file
local libisp_file=$(find "${BUILD_DEBS}" -name "aml-libisp_*.deb" 2>/dev/null)
aml_log info "install isp BUILD_DEBS ${BUILD_DEBS} libisp_file ${libisp_file}"
install_aml_deb $libisp_file
}
function install_optee_deb {
if ! is_unit_enabled "optee"; then
aml_log info "[SKIP] >> optee disabled ( not install)"
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
aml_log info "[SKIP] >> libencoder disabled ( not install)"
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
aml_log info "[SKIP] >> libversenc-prebuilt disable in MEDIA_FEATURES ( not install)"
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
aml_log info "[SKIP] >> libtahoevenc disable in MEDIA_FEATURES ( not install)"
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
aml_log info "[SKIP] >> libamljpegenc disable in MEDIA_FEATURES ( not install)"
else
local libamljpegenc_file=$(find "${BUILD_DEBS}" -name "linux-libamljpegenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libamljpegenc_file
fi
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
}
function install_media_deb {
if ! is_unit_enabled "media-modules"; then
aml_log info "[SKIP] >> media-modules disabled ( not install)"
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
aml_log info "[SKIP] >> TAHOE disable in MEDIA_ENCODER_HW_CONFIG ( not install)"
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
aml_log info "[SKIP] >> libion disabled ( not install)"
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
aml_log info "[SKIP] >> libge2d disabled ( not install)"
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
aml_log info "[SKIP] >> liblog disabled ( not install)"
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
aml_log info "[SKIP] >> dma-allocator disabled ( not install)"
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
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "[SKIP] >> tvserver disabled ( not install)"
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "tvserver"; then
aml_log info "[SKIP] >> tvserver disable in DISTRO_FEATURES ( not install)"
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
}
function install_logcat_deb {
if ! is_unit_enabled "devtool" || ! is_unit_enabled "liblog"; then
aml_log info "[SKIP] >> devtool android tool logcat disabled ( not install)"
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
aml_log info "[SKIP] >> vendor-files disabled ( not install)"
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "vendor-files"; then
aml_log info "[SKIP] >> vendor-files disable in DISTRO_FEATURES ( not install)"
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
aml_log info "[SKIP] >> linux-uapi-headers disabled ( not install)"
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
}
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
}
function install_common() {
aml_log info "install amlogic debs: GPU/NPU/DEC/ENC/... ... " "IMG"
# 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}"
aml_log info "AMLOGIC: sysroot compat" "/usr/lib/${_cc_triplet} -> ${_deb_triplet}"
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
aml_log info "AMLOGIC: sysroot compat" "linked crt*.o + libc.so into /usr/lib/"
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
install_linux_uapi_deb
install_vendor_file_deb
install_chromium_amlbian
install_tvserver_deb
install_logcat_deb
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() {
aml_log info "Start create_base_rootfs rootfs-arm64-${RELEASE}*.tar.zst" "IMG"
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
aml_log error "rootfs tar not found in ${SRC}/cache/rootfs/" "IMG"
ls -la "${SRC}/cache/rootfs/" || true
exit 1
fi
aml_log info "Using rootfs: $rootfs_img_tar" "IMG"
tar -I zstd -xf "$rootfs_img_tar" -C "${ROOTFS_TEMP}"
aml_log info "End create_base_rootfs : $(ls "${ROOTFS_TEMP}")" "IMG"
}
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() {
aml_log info "Cleanup..."
sync
trap - INT TERM EXIT
umount_chroot "$ROOTFS_TEMP"
umount_chroot "$ROOTFS"
}
function build_additional_deb {
aml_log info "AMLOGIC" ">> Start build_additional_deb "
(
aml_log info "AMLOGIC" ">> Start build gst-aml-drmbufferpool "
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-drmbufferpool-plugins.sh"
)
}
function build_additional_deb_after_install {
aml_log info "AMLOGIC" ">> Start build_additional_deb_after_install "
(
aml_log info "AMLOGIC" ">> Start build bluez5 "
source "${EXTENSION_DIR}/../scripts/bt/build-bluez5.sh"
if ! is_unit_enabled "bt"; then
aml_log info "[SKIP] >> bt disabled ( not install)"
else
local bluez_file=$(find "${BUILD_DEBS}" -name "bluez_*.deb" 2>/dev/null)
install_aml_deb $bluez_file
fi
aml_log info "AMLOGIC" ">> Start build gst-plugin-venc "
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-amlvenc.sh"
if ! is_unit_enabled "gst-aml"; then
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "AMLOGIC" ">> Start build gst-plugin-venc-jpeg"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-jpeg.sh"
if ! is_unit_enabled "gst-aml"; then
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "AMLOGIC" ">> Start build gst-aml-dma-allocator "
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-dma-allocator.sh"
if ! is_unit_enabled "gst-aml"; then
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "AMLOGIC" ">> Start build gst-aml-gfx2d "
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-gfx2d.sh"
if ! is_unit_enabled "gst-aml"; then
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "AMLOGIC" ">> Start build gst-aml-conv "
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-conv.sh"
if ! is_unit_enabled "gst-aml"; then
aml_log info "[SKIP] >> gst-aml disabled ( not install)"
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
aml_log info "AMLOGIC" ">> Start build aml-tvserver "
source "${EXTENSION_DIR}/../scripts/multimedia/tvserver/build-aml-tvserver.sh"
if ! is_unit_enabled "tvserver"; then
aml_log info "[SKIP] >> tvserver disabled ( not install)"
else
local tvserver_file=$(find "${BUILD_DEBS}" -name "linux-aml-tvserver-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $tvserver_file
fi
aml_log info "AMLOGIC" ">> Start build screencapture "
source "${EXTENSION_DIR}/../scripts/multimedia/build-screencapture.sh"
if ! is_unit_enabled "screencapture"; then
aml_log info "[SKIP] >> screencapture disabled ( not install)"
else
local screencapture_file=$(find "${BUILD_DEBS}" -name "linux-screencapture-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $screencapture_file
fi
aml_log info "AMLOGIC" ">> Start build mediactrlsrc "
source "${EXTENSION_DIR}/../scripts/multimedia/build-mediactrlsrc.sh"
if ! is_unit_enabled "mediactrlsrc"; then
aml_log info "[SKIP] >> mediactrlsrc disabled ( not install)"
else
local mediactrlsrc_file=$(find "${BUILD_DEBS}" -name "linux-mediactrlsrc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $mediactrlsrc_file
fi
aml_log info "AMLOGIC" ">> Start build hdmi-test "
source "${EXTENSION_DIR}/../scripts/multimedia/build-hdmi-test.sh"
if ! is_unit_enabled "hdmi-test"; then
aml_log info "[SKIP] >> hdmi-test disabled ( not install)"
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
)
}
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
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
}
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
aml_log info "NO extlinux, need checking it ......"
fi
# Copy boot environment
if [ -f $BOOT_ENV/uEnv.txt ]; then
cp $BOOT_ENV/uEnv.txt $ROOTFS_TEMP/boot/uEnv.txt
else
aml_log info "NO boot uEnv, need checking it ......"
fi
# 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
aml_log info "NO logo, need checking it ......"
fi
# 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
# aml_log info "Found initrd: $initrd_file, BUT cp it from yct case......."
# # >>>>>>> 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
aml_log info "Found initrd: $initrd_file, "
local bootfile=$(basename $initrd_file)
ln -sf boot/$bootfile initrd.img
else
aml_log error "Error: NOT Found initrd: $initrd_file: $(ls ${ROOTFS_TEMP}/boot)"
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
i2c_dev
)
if [ ! -f $MOD_FILE ]; then
touch "$MOD_FILE"
fi
for mod in "${MODS[@]}" "${VENDOR_MODS[@]}"; do
if ! grep -qx "$mod" "$MOD_FILE"; then
echo "$mod" >> "$MOD_FILE"
aml_log info "Added module $mod " "USER"
fi
done
aml_log info "All modules added to $MOD_FILE" "USER"
}
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
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"
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() {
aml_log info "aml_create_audio_default " "AUDIO_TYPE=${AUDIO_TYPE} hdmionly=${HDMIONLY}"
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
}
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"
}
function default_user_conf() {
aml_log info "配置默认用户和系统设置" "USER"
# 1. 设置 root 密码,默认由 amlogic_common.inc 中 ROOT_PW 定义(1234),可编译参数覆盖
#aml_log "设置 root 密码为 1234" "USER" "info"
echo "root:${ROOT_PW}" | chroot "${ROOTFS_TEMP}" chpasswd
# 2. 创建默认用户 system,密码为 system
#aml_log "创建默认用户 system,密码为 system" "USER" "info"
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. 设置默认时区为亚洲/上海(北京时区)
# aml_log info "设置默认时区为亚洲/上海" "USER"
# chroot "${ROOTFS_TEMP}" ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# echo "Asia/Shanghai" > "${ROOTFS_TEMP}/etc/timezone"
# # 4. 设置默认语言环境为中文 UTF-8
# aml_log info "设置默认语言环境为中文 UTF-8" "USER"
# 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)
aml_log info "配置阿里云软件源" "USER"
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
;;
*)
aml_log warn "未知系统版本 ${release_name},使用默认源" "USER"
;;
esac
fi
# 6. 配置网络设置 - 启用 DHCP
aml_log info "配置网络 DHCP" "USER"
# 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
aml_create_version_file
aml_create_audio_default
add_modules_booting
# 7. 配置 SSH 允许 root 登录和密码认证(便于调试)
aml_log info "配置 SSH 服务" "USER"
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. 禁用首次启动配置向导
aml_log info "禁用首次启动配置向导" "USER"
chroot "${ROOTFS_TEMP}" systemctl disable armbian-firstrun 2>/dev/null || true
chroot "${ROOTFS_TEMP}" systemctl mask armbian-firstrun 2>/dev/null || true
chroot "${ROOTFS_TEMP}" systemctl disable NetworkManager-wait-online 2>/dev/null || true
# 9. 设置主机名
aml_log info "设置主机名为 amlbian" "USER"
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 无需密码(便于调试)
aml_log info "配置 sudo 无需密码" "USER"
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
aml_log info "配置 lightdm 自动登录" "USER"
cat > "${ROOTFS_TEMP}/etc/lightdm/lightdm.conf.d/50-autologin.conf" << EOF
[Seat:*]
autologin-user=system
autologin-user-timeout=0
EOF
fi
if [[ "$AUTOLOGIN" == "yes" ]]; then
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"
fi
mkdir -p "${ROOTFS_TEMP}/etc/systemd/system/[email protected]"
# 串口自动登录用户,默认由 amlogic_common.inc 中 AUTOLOGIN_USER 定义(system),可编译参数覆盖
cat >"${ROOTFS_TEMP}/etc/systemd/system/[email protected]/autologin.conf" <<EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin ${AUTOLOGIN_USER} --keep-baud 921600,115200,57600,38400,9600 %I \$TERM
EOF
fi
# 设置GStreamer环境变量
aml_log info "设置GStreamer环境变量" "USER"
echo 'GST_PLUGIN_FEATURE_RANK=v4l2video26mpeg4dec:0' >> "${ROOTFS_TEMP}/etc/environment"
aml_clapper_fix
# 12. 更新软件包列表
aml_log info "更新软件包列表" "USER"
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}
ln -s ${system_service}/systemd-timesyncd.service ${target_enable_service}
ln -s ${system_service}/tee-supplicant.service ${target_enable_service}
ln -sf ${system_service}/videoFirmwarePreload.service ${target_enable_service}
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
aml_log info "Creating ${sys_network_conf}"
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"
# default adb sh to bash
ln -sf /bin/bash "${ROOTFS_TEMP}/bin/sh"
# 配置 rc.local 以包含 rootenv 脚本
aml_log info "配置 rc.local 包含 rootenv 脚本" "USER"
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}"
aml_log info "已将 rootenv 追加到现有 rc.local 文件" "USER"
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}"
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
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
aml_log info "解压 initrd: ${initrd_source} 到 ${RAMFS_TEMP}" "RAMFS"
if [ -f "${initrd_source}" ]; then
cd "${RAMFS_TEMP}"
gunzip -c "${initrd_source}" | cpio -idm --quiet
cd - > /dev/null
else
aml_log error "initrd 文件不存在: ${initrd_source}" "RAMFS"
return 1
fi
# 2. 删除 ramdisk 目录下的所有 ko 文件
aml_log info "删除 ${ramdisk_dir} 下的所有 ko 文件" "RAMFS"
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 文件
aml_log info "从 ${ROOTFS_TEMP}/lib/modules 查找并复制指定的 ko 文件" "RAMFS"
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
aml_log info "找到并复制: ${ko}" "RAMFS"
cp -v "${source_ko}" "${ramdisk_dir}/"
else
aml_log warn "未找到: ${ko}" "RAMFS"
fi
done
# 4. 重新打包 ramdisk 目录为 cpio.gz 文件
aml_log info "重新打包 ${ramdisk_dir} 为 cpio.gz 文件" "RAMFS"
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
aml_log error "ramdisk 目录不存在: ${ramdisk_dir}" "RAMFS"
return 1
fi
if [ -e ${output_initrd} ];then
aml_log info "Mv initrd as initrd.img to boot"
mv ${output_initrd} ${ROOTFS_TEMP}/initrd.img
fi
}
## Prepare gpt table
function build_gpttable() {
aml_log info "Make gpt-partition ......"
aml_log debug "GPT_TABLE" "$GPT_TABLE"
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
aml_log info "built gpt done $(ls $BUILD_IMAGES)"
rm -rf gpt_out.bin
}
## creates image file, partitions and fs
function prepare_partitions()
{
aml_log info "Preparing image file for rootfs..."
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
aml_log info "Current rootfs cache size: $rootfs_size MiB"
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
aml_log info "Using user-defined image size: $FIXED_IMAGE_SIZE MiB"
local rootfs_image_size=$FIXED_IMAGE_SIZE
# basic sanity check
if [[ $ROOTFS_TYPE != nfs && $rootfs_image_size -lt $rootfs_size ]]; then
aml_log error "User defined image size is too small - $rootfs_image_size <= $rootfs_size"
exit 1
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
aml_log info "Creating eMMC rootfs image..."
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
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
mount -o loop $BUILD_IMAGES/rootfs.img $ROOTFS
local rootfs_uuid="UUID=$(blkid -s UUID -o value $BUILD_IMAGES/rootfs.img)"
aml_log debug "prepare_partitions 1" "rootfs_uuid=${rootfs_uuid}"
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
aml_log info "Create SD/USB image..."
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
aml_log error "Unable to find free loop device!"
exit 1
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
aml_log info "Copying files to root directory..."
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
aml_log info "Copying files to /boot directory..."
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
aml_log debug "prepare_partitions 2" "rootfs_uuid=${rootfs_uuid}"
fi
if [[ -f $ROOTFS_TEMP/boot/uEnv.txt ]]; then
sed -i s/rootdev=root=.*/rootdev=root=$rootfs_uuid/g $ROOTFS/boot/uEnv.txt
aml_log debug "prepare_partitions 3" "rootfs_uuid=${rootfs_uuid}"
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
aml_log debug "Free space"
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}
aml_log info "Image install type: $INSTALL_TYPE"
if [ "$INSTALL_TYPE" == "EMMC" ]; then
## Fixup upgrade dtb link
[ -d "$BOARD_CONFIG"/image-update ] || {
aml_log error "image-update not exist"
exit 1
}
for UTILS_DIR_ in $UTILS_DIR; do
[ -d "$UTILS_DIR_" ] || {
aml_log error "UTILS_DIR not exist: $UTILS_DIR"
exit 1
}
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"
aml_log debug "UTILS_DIR $UTILS_DIR; D: $D"
aml_log debug "DEBUG1: $(ls $BUILD_IMAGES/)"
aml_log debug "DEBUG2: $(ls $UBOOT_IMAGE_DIR/)"
# 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"
aml_log info "INFO: Linked $SOURCE_LOGO -> $TARGET_LOGO"
else
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_LOGO. ($SOURCE_LOGO)"
exit 1
fi
# 检查 amlbian.dtb
SOURCE_DTB="$DTBS_DIR/multi.dtb"
TARGET_DTB="$D/amlbian.dtb"
if [ -e "$SOURCE_DTB" ]; then
ln -sf "$SOURCE_DTB" "$TARGET_DTB"
aml_log info "INFO: Linked $SOURCE_DTB -> $TARGET_DTB"
else
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_DTB. ($SOURCE_DTB)"
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"
aml_log info "INFO: Linked $SOURCE_UBOOT_BIN -> $TARGET_UBOOT_BIN"
else
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_BIN. ($SOURCE_UBOOT_BIN)"
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"
aml_log info "INFO: Linked $SOURCE_UBOOT_SD -> $TARGET_UBOOT_SD"
else
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_SD. ($SOURCE_UBOOT_SD)"
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"
aml_log info "INFO: Linked $SOURCE_UBOOT_USB -> $TARGET_UBOOT_USB"
else
aml_log error "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_USB. ($SOURCE_UBOOT_USB)"
exit 1
fi
aml_log debug "DEBUG3: $(ls $D/)"
## 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
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}"
$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,,}
aml_log info "Create U-Boot SD image..."
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
aml_log error "ERROR Unsupported install type: '$INSTALL_TYPE'"
exit 1
fi
echo ""
aml_log info "IMAGE: $BUILD_IMAGES/$IMAGE_FILE_NAME is ready!"
}
## compress_image
function compress_image() {
[[ $COMPRESS_IMAGE != yes ]] && return
echo ""
aml_log info "Compressing image '$BUILD_IMAGES/$IMAGE_FILE_NAME' to '$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4' ..."
rm -rf "$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4"
aml_log info "lz4 $BUILD_IMAGES/$IMAGE_FILE_NAME>$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4"
lz4 $BUILD_IMAGES/$IMAGE_FILE_NAME>$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4
echo ""
aml_log info "Compressed image: $BUILD_IMAGES/$IMAGE_FILE_NAME.lz4 is ready!"
}
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
aml_log debug "fix_perms: $1 [$UID:$UID]"
$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() {
aml_log info "Start package img" "IMG"
# 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
aml_log info "End package img" "IMG"
}
export -f amlbian_package_img
export -f amlbian_additional_insatll
# ==============================================================================
# End of function-img.sh
# ==============================================================================