Files

1492 lines
53 KiB
Bash
Raw Permalink 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
echo "ERROR: ROOTFS_TEMP is not set" >&2
return 1
fi
if [[ -z "$pkgs" ]]; then
echo "WARNING: no packages provided to install" >&2
return 0
fi
# 防止空 rootfs
if [[ ! -d "$rootfs" ]]; then
echo "ERROR: rootfs not found: $rootfs" >&2
return 1
fi
mount_chroot $rootfs
display_alert "Installing packages in rootfs: $rootfs"
display_alert "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() {
display_alert "Installing additional packages from PACKAGE_LIST_AML: ${PACKAGE_LIST_AML}" "info"
local pkgs="${PACKAGE_LIST_AML}"
local rootfs="${ROOTFS_TEMP:-$SDCARD}"
if [[ -z "$pkgs" ]]; then
echo "INFO: PACKAGE_LIST_AML is empty, skip AML additional install"
return 0
fi
if [[ ! -d "$rootfs" ]]; then
echo "ERROR: rootfs not found: $rootfs" >&2
return 1
fi
mount_chroot $rootfs
display_alert "INFO: AML additional install in rootfs: $rootfs"
display_alert "INFO: packages: $pkgs"
for pkg in $pkgs; do
if [[ -z "$pkg" ]]; then
continue
fi
display_alert "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
" || {
echo "WARNING: failed to install AML package: $pkg" >&2
continue
}
done
umount_chroot $rootfs
display_alert "Install PACKAGE_LIST_AML done"
}
function install_aml_deb(){
local package=$1
local name=$(basename $package)
[ -e "$package" ] || {
display_alert "Installing $name in chroot skipped ($package not exist)"
return 0
}
cp $package $ROOTFS_TEMP/root/$name
display_alert "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
echo "[SKIP Install] >> Udev disable in BUILD_UNITS"
return
fi
local udev_file=$(find "${BUILD_DEBS}" -name "aml-udev_*.deb" 2>/dev/null)
display_alert "istall udev BUILD_DEBS ${BUILD_DEBS} udev_file ${udev_file}" "info"
install_aml_deb ${udev_file}
}
function install_modules_load_amlbian() {
if ! is_unit_enabled "modules-load"; then
echo "[SKIP Install] >> modules-load disable in BUILD_UNITS"
return
fi
local modules_file=$(find "${BUILD_DEBS}" -name "aml-modules-load_*.deb" 2>/dev/null)
display_alert "istall module-load BUILD_DEBS ${BUILD_DEBS} modules_file ${udev_file}" "info"
install_aml_deb ${modules_file}
}
function install_gpu_amlbian() {
if ! is_unit_enabled "gpu"; then
echo "[SKIP Install] >> gpu disable in BUILD_UNITS"
return
fi
local gpu_file=$(find "${BUILD_DEBS}" -name "aml-gpu-${GPU_ARCH}*.deb" 2>/dev/null)
display_alert "istall gpu BUILD_DEBS ${BUILD_DEBS} gpu_file ${gpu_file}" "info"
install_aml_deb $gpu_file
local libgles_file=$(find "${BUILD_DEBS}" -name "aml-libgles-eabihf-${GPU_MODEL}*.deb" 2>/dev/null)
display_alert "istall gpu BUILD_DEBS ${BUILD_DEBS} libgles_file ${libgles_file}" "info"
install_aml_deb $libgles_file
}
function install_npu_amlbian() {
if ! is_unit_enabled "npu"; then
echo "[SKIP Install] >> npu disable in BUILD_UNITS"
return
fi
local npu_common_file=$(find "${BUILD_DEBS}" -name "aml-npu-common_*.deb" 2>/dev/null)
display_alert "istall npu BUILD_DEBS ${BUILD_DEBS} npu_common_file ${npu_common_file}" "info"
install_aml_deb $npu_common_file
local adla_driver_file=$(find "${BUILD_DEBS}" -name "aml-adla-driver_*.deb" 2>/dev/null)
display_alert "istall npu BUILD_DEBS ${BUILD_DEBS} adla_driver_file ${adla_driver_file}" "info"
install_aml_deb $adla_driver_file
local adla_lib_file=$(find "${BUILD_DEBS}" -name "aml-adla-lib_*.deb" 2>/dev/null)
display_alert "istall npu BUILD_DEBS ${BUILD_DEBS} adla_lib_file ${adla_lib_file}" "info"
install_aml_deb $adla_lib_file
}
function install_wifi_amlbian() {
if ! is_unit_enabled "wifi"; then
echo "[SKIP Install] >> wifi disable in BUILD_UNITS"
return
fi
local wifi_file=$(find "${BUILD_DEBS}" -name "aml-wifi-w*.deb" 2>/dev/null)
display_alert "istall wifi BUILD_DEBS ${BUILD_DEBS} wifi_file ${wifi_file}" "info"
install_aml_deb $wifi_file
local wifi_common_file=$(find "${BUILD_DEBS}" -name "aml-wifi-common_*.deb" 2>/dev/null)
display_alert "istall wifi BUILD_DEBS ${BUILD_DEBS} wifi_common_file ${wifi_common_file}" "info"
install_aml_deb $wifi_common_file
local wpa_file=$(find "${BUILD_DEBS}" -name "aml-wpa-supplicant-config_*.deb" 2>/dev/null)
display_alert "istall wifi BUILD_DEBS ${BUILD_DEBS} wpa_file ${wpa_file}" "info"
install_aml_deb $wpa_file
}
function install_bt_amlbian() {
if ! is_unit_enabled "bt"; then
echo "[SKIP Install] >> bt disable in BUILD_UNITS"
return
fi
local hciattach_file=$(find "${BUILD_DEBS}" -name "aml-hciattach*.deb" 2>/dev/null)
display_alert "istall hciattach BUILD_DEBS ${BUILD_DEBS} wifi_file ${hciattach_file}" "info"
install_aml_deb $hciattach_file
local bt_driver=$(find "${BUILD_DEBS}" -name "aml-bt-w2*.deb" 2>/dev/null)
display_alert "istall bt driver BUILD_DEBS ${BUILD_DEBS} wifi_common_file ${bt_driver}" "info"
install_aml_deb $bt_driver
}
function install_isp_amlbian() {
if ! is_unit_enabled "isp"; then
echo "[SKIP Install] >> isp disable in BUILD_UNITS"
return
fi
local isp_driver_file=$(find "${BUILD_DEBS}" -name "aml-isp_*.deb" 2>/dev/null)
display_alert "istall isp BUILD_DEBS ${BUILD_DEBS} isp_driver_file ${isp_driver_file}" "info"
install_aml_deb $isp_driver_file
local libisp_file=$(find "${BUILD_DEBS}" -name "aml-libisp_*.deb" 2>/dev/null)
display_alert "istall isp BUILD_DEBS ${BUILD_DEBS} libisp_file ${libisp_file}" "info"
install_aml_deb $libisp_file
}
function install_optee_deb {
if ! is_unit_enabled "optee"; then
display_alert "[SKIP] >> optee disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> libencoder disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> libversenc-prebuilt disable in MEDIA_FEATURES ( not install)" "info"
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
display_alert "[SKIP] >> libtahoevenc disable in MEDIA_FEATURES ( not install)" "info"
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
display_alert "[SKIP] >> libamljpegenc disable in MEDIA_FEATURES ( not install)" "info"
else
local libamljpegenc_file=$(find "${BUILD_DEBS}" -name "linux-libamljpegenc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $libamljpegenc_file
fi
}
function install_media_deb {
if ! is_unit_enabled "media-modules"; then
display_alert "[SKIP] >> media-modules disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> TAHOE disable in MEDIA_ENCODER_HW_CONFIG ( not install)" "info"
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
display_alert "[SKIP] >> libion disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> libge2d disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> liblog disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> dma-allocator disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> tvserver disabled ( not install)" "" "info"
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "tvserver"; then
display_alert "[SKIP] >> tvserver disable in DISTRO_FEATURES ( not install)" "info"
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
display_alert "[SKIP] >> devtool android tool logcat disabled ( not install)" "" "info"
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
display_alert "[SKIP] >> vendor-files disabled ( not install)" "" "info"
return
fi
if ! is_feature_contains "$DISTRO_FEATURES" "vendor-files"; then
display_alert "[SKIP] >> vendor-files disable in DISTRO_FEATURES ( not install)" "info"
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
display_alert "[SKIP] >> linux-uapi-headers disabled ( not install)" "" "info"
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-08-13 11:28:40 +08:00
function install_common() {
display_alert "install amlogic debs: GPU/NPU/DEC/ENC/... ... " "IMG" "info"
# 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}"
display_alert "AMLOGIC: sysroot compat" "/usr/lib/${_cc_triplet} -> ${_deb_triplet}" "info"
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
display_alert "AMLOGIC: sysroot compat" "linked crt*.o + libc.so into /usr/lib/" "info"
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-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() {
display_alert "Start create_base_rootfs rootfs-arm64-${RELEASE}*.tar.zst" "IMG" "info"
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
display_alert "rootfs tar not found in ${SRC}/cache/rootfs/" "IMG" "err"
ls -la "${SRC}/cache/rootfs/" || true
exit 1
fi
display_alert "Using rootfs: $rootfs_img_tar" "IMG" "info"
tar -I zstd -xf "$rootfs_img_tar" -C "${ROOTFS_TEMP}"
display_alert "End create_base_rootfs : $(ls "${ROOTFS_TEMP}")" "IMG" "info"
}
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() {
echo "Cleanup..."
sync
trap - INT TERM EXIT
umount_chroot "$ROOTFS_TEMP"
umount_chroot "$ROOTFS"
}
function build_additional_deb {
display_alert "AMLOGIC" ">> Start build_additional_deb " "info"
(
display_alert "AMLOGIC" ">> Start build gst-aml-drmbufferpool " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-drmbufferpool-plugins.sh"
)
}
function build_additional_deb_after_install {
display_alert "AMLOGIC" ">> Start build_additional_deb_after_install " "info"
(
display_alert "AMLOGIC" ">> Start build bluez5 " "info"
source "${EXTENSION_DIR}/../scripts/bt/build-bluez5.sh"
if ! is_unit_enabled "bt"; then
display_alert "[SKIP] >> bt disabled ( not install)" "" "info"
else
local bluez_file=$(find "${BUILD_DEBS}" -name "bluez_*.deb" 2>/dev/null)
install_aml_deb $bluez_file
fi
display_alert "AMLOGIC" ">> Start build gst-plugin-venc " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-amlvenc.sh"
if ! is_unit_enabled "gst-aml"; then
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build gst-plugin-venc-jpeg" "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-venc-jpeg.sh"
if ! is_unit_enabled "gst-aml"; then
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build gst-aml-dma-allocator " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-dma-allocator.sh"
if ! is_unit_enabled "gst-aml"; then
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build gst-aml-gfx2d " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-aml-gfx2d.sh"
if ! is_unit_enabled "gst-aml"; then
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build gst-aml-conv " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/gstreamer/build-gst-plugin-conv.sh"
if ! is_unit_enabled "gst-aml"; then
display_alert "[SKIP] >> gst-aml disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build aml-tvserver " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/tvserver/build-aml-tvserver.sh"
if ! is_unit_enabled "tvserver"; then
display_alert "[SKIP] >> tvserver disabled ( not install)" "" "info"
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
display_alert "AMLOGIC" ">> Start build screencapture " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/build-screencapture.sh"
if ! is_unit_enabled "screencapture"; then
display_alert "[SKIP] >> screencapture disabled ( not install)" "" "info"
else
local screencapture_file=$(find "${BUILD_DEBS}" -name "linux-screencapture-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $screencapture_file
fi
display_alert "AMLOGIC" ">> Start build mediactrlsrc " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/build-mediactrlsrc.sh"
if ! is_unit_enabled "mediactrlsrc"; then
display_alert "[SKIP] >> mediactrlsrc disabled ( not install)" "" "info"
else
local mediactrlsrc_file=$(find "${BUILD_DEBS}" -name "linux-mediactrlsrc-$BOARD-amlbian_*.deb" 2>/dev/null)
install_aml_deb $mediactrlsrc_file
fi
display_alert "AMLOGIC" ">> Start build hdmi-test " "info"
source "${EXTENSION_DIR}/../scripts/multimedia/build-hdmi-test.sh"
if ! is_unit_enabled "hdmi-test"; then
display_alert "[SKIP] >> hdmi-test disabled ( not install)" "" "info"
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
display_alert "NO extlinux, need checking it ......" "info"
fi
# Copy boot environment
if [ -f $BOOT_ENV/uEnv.txt ]; then
cp $BOOT_ENV/uEnv.txt $ROOTFS_TEMP/boot/uEnv.txt
else
display_alert "NO boot uEnv, need checking it ......" "info"
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
display_alert "NO logo, need checking it ......" "info"
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
# display_alert "Found initrd: $initrd_file, BUT cp it from yct case......." "info"
# # >>>>>>> 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
display_alert "Found initrd: $initrd_file, " "info"
local bootfile=$(basename $initrd_file)
ln -sf boot/$bootfile initrd.img
else
display_alert "Error: NOT Found initrd: $initrd_file: $(ls ${ROOTFS_TEMP}/boot)" "info"
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
protected_memory_allocator
mali
adla_core
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"
display_alert "Added module $mod " "USER" "info"
fi
done
display_alert "All modules added to $MOD_FILE" "USER" "info"
}
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
display_alert "MEDIA-MODULES-INSTALL" "version.txt image_name $image_name" "info"
display_alert "MEDIA-MODULES-INSTALL" "version.txt branch $branch" "info"
display_alert "MEDIA-MODULES-INSTALL" "version.txt version $version" "info"
display_alert "MEDIA-MODULES-INSTALL" "version.txt spin $spin" "info"
display_alert "MEDIA-MODULES-INSTALL" "version.txt build_time $build_time" "info"
display_alert "MEDIA-MODULES-INSTALL" "version.txt compiler $compiler_info" "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() {
display_alert "aml_create_audio_default " "AUDIO_TYPE=${AUDIO_TYPE} hdmionly=${HDMIONLY}" "info"
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-08-13 11:28:40 +08:00
function default_user_conf() {
display_alert "配置默认用户和系统设置" "USER" "info"
# 1. 设置 root 密码为 1234
#display_alert "设置 root 密码为 1234" "USER" "info"
echo "root:1234" | chroot "${ROOTFS_TEMP}" chpasswd
# 2. 创建默认用户 system,密码为 system
#display_alert "创建默认用户 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. 设置默认时区为亚洲/上海(北京时区)
# display_alert "设置默认时区为亚洲/上海" "USER" "info"
# chroot "${ROOTFS_TEMP}" ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# echo "Asia/Shanghai" > "${ROOTFS_TEMP}/etc/timezone"
# # 4. 设置默认语言环境为中文 UTF-8
# display_alert "设置默认语言环境为中文 UTF-8" "USER" "info"
# 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)
display_alert "配置阿里云软件源" "USER" "info"
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
;;
*)
display_alert "未知系统版本 ${release_name},使用默认源" "USER" "warn"
;;
esac
fi
# 6. 配置网络设置 - 启用 DHCP
display_alert "配置网络 DHCP" "USER" "info"
# 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 登录和密码认证(便于调试)
display_alert "配置 SSH 服务" "USER" "info"
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. 禁用首次启动配置向导
display_alert "禁用首次启动配置向导" "USER" "info"
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. 设置主机名
display_alert "设置主机名为 amlbian" "USER" "info"
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 无需密码(便于调试)
display_alert "配置 sudo 无需密码" "USER" "info"
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
display_alert "配置 lightdm 自动登录" "USER" "info"
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
if [ -f "${ROOTFS_TEMP}/etc/gdm3/daemon.conf" ]; then
display_alert "配置 gdm3 自动登录" "USER" "info"
sed -i \
-e 's|^[#[:space:]]*AutomaticLoginEnable.*|AutomaticLoginEnable=true|' \
-e 's|^[#[:space:]]*AutomaticLogin[[:space:]]*=.*|AutomaticLogin=system|' \
"${ROOTFS_TEMP}/etc/gdm3/daemon.conf"
fi
mkdir -p "${ROOTFS_TEMP}/etc/systemd/system/serial-getty@.service.d"
cat >"${ROOTFS_TEMP}/etc/systemd/system/serial-getty@.service.d/autologin.conf" <<EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin system --keep-baud 921600,115200,57600,38400,9600 %I \$TERM
EOF
fi
# 设置GStreamer环境变量
display_alert "设置GStreamer环境变量" "USER" "info"
echo 'GST_PLUGIN_FEATURE_RANK=v4l2video26mpeg4dec:0' >> "${ROOTFS_TEMP}/etc/environment"
2026-08-13 11:28:40 +08:00
# 12. 更新软件包列表
display_alert "更新软件包列表" "USER" "info"
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}/ssystemd-timesyncd.service ${target_enable_service}
ln -s ${system_service}/tee-supplicant.service ${target_enable_service}
ln -s ${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
echo "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"
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 脚本
display_alert "配置 rc.local 包含 rootenv 脚本" "USER" "info"
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}"
display_alert "已将 rootenv 追加到现有 rc.local 文件" "USER" "info"
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}"
display_alert "已创建 rc.local 文件并添加 rootenv 内容" "USER" "info"
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
display_alert "解压 initrd: ${initrd_source} 到 ${RAMFS_TEMP}" "RAMFS" "info"
if [ -f "${initrd_source}" ]; then
cd "${RAMFS_TEMP}"
gunzip -c "${initrd_source}" | cpio -idm --quiet
cd - > /dev/null
else
display_alert "initrd 文件不存在: ${initrd_source}" "RAMFS" "error"
return 1
fi
# 2. 删除 ramdisk 目录下的所有 ko 文件
display_alert "删除 ${ramdisk_dir} 下的所有 ko 文件" "RAMFS" "info"
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 文件
display_alert "从 ${ROOTFS_TEMP}/lib/modules 查找并复制指定的 ko 文件" "RAMFS" "info"
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
display_alert "找到并复制: ${ko}" "RAMFS" "info"
cp -v "${source_ko}" "${ramdisk_dir}/"
else
display_alert "未找到: ${ko}" "RAMFS" "warn"
fi
done
# 4. 重新打包 ramdisk 目录为 cpio.gz 文件
display_alert "重新打包 ${ramdisk_dir} 为 cpio.gz 文件" "RAMFS" "info"
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
display_alert "ramdisk 目录不存在: ${ramdisk_dir}" "RAMFS" "error"
return 1
fi
if [ -e ${output_initrd} ];then
display_alert "Mv initrd as initrd.img to boot" "info"
mv ${output_initrd} ${ROOTFS_TEMP}/initrd.img
fi
}
## Prepare gpt table
function build_gpttable() {
display_alert "Make gpt-partition ......" "info"
echo "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
display_alert "built gpt done $(ls $BUILD_IMAGES)"
rm -rf gpt_out.bin
}
## creates image file, partitions and fs
function prepare_partitions()
{
display_alert "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
display_alert "Current rootfs cache size: $rootfs_size MiB"
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
display_alert "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
display_alert "User defined image size is too small - $rootfs_image_size <= $rootfs_size" && return -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
display_alert "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
mount -o loop $BUILD_IMAGES/rootfs.img $ROOTFS
local rootfs_uuid="UUID=$(blkid -s UUID -o value $BUILD_IMAGES/rootfs.img)"
echo " 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
display_alert "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
display_alert "Unable to find free loop device!"
return -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
display_alert "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
display_alert "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
echo " 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
echo " 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
echo -e "\nFree 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}
display_alert "Image install type: $INSTALL_TYPE"
if [ "$INSTALL_TYPE" == "EMMC" ]; then
## Fixup upgrade dtb link
[ -d "$BOARD_CONFIG"/image-update ] || {
display_alert "image-update not exist"
return 1
}
for UTILS_DIR_ in $UTILS_DIR; do
[ -d "$UTILS_DIR_" ] || {
display_alert "UTILS_DIR not exist: $UTILS_DIR"
return 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"
display_alert "UTILS_DIR $UTILS_DIR; D: $D"
display_alert "DEBUG1: $(ls $BUILD_IMAGES/)"
display_alert "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"
display_alert "INFO: Linked $SOURCE_LOGO -> $TARGET_LOGO"
else
display_alert "ERROR: Source file does not exist, skipping link creation for $TARGET_LOGO. ($SOURCE_LOGO)"
exit 1
fi
# 检查 amlbian.dtb
SOURCE_DTB="$DTBS_DIR/$KERNEL_DEVICETREE"
TARGET_DTB="$D/amlbian.dtb"
if [ -e "$SOURCE_DTB" ]; then
ln -sf "$SOURCE_DTB" "$TARGET_DTB"
display_alert "INFO: Linked $SOURCE_DTB -> $TARGET_DTB"
else
display_alert "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"
display_alert "INFO: Linked $SOURCE_UBOOT_BIN -> $TARGET_UBOOT_BIN"
else
display_alert "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"
display_alert "INFO: Linked $SOURCE_UBOOT_SD -> $TARGET_UBOOT_SD"
else
display_alert "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"
display_alert "INFO: Linked $SOURCE_UBOOT_USB -> $TARGET_UBOOT_USB"
else
display_alert "ERROR: Source file does not exist, skipping link creation for $TARGET_UBOOT_USB. ($SOURCE_UBOOT_USB)"
exit 1
fi
display_alert "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
display_alert "DEBUG4: $(ls -l $D/)"
display_alert "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,,}
display_alert "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
display_alert "ERROR Unsupported install type: '$INSTALL_TYPE'"
return 1
fi
echo ""
display_alert "IMAGE: $BUILD_IMAGES/$IMAGE_FILE_NAME is ready!"
}
## compress_image
function compress_image() {
[[ $COMPRESS_IMAGE != yes ]] && return
echo ""
display_alert "Compressing image '$BUILD_IMAGES/$IMAGE_FILE_NAME' to '$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4' ..."
rm -rf "$BUILD_IMAGES/$IMAGE_FILE_NAME.lz4"
echo "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 ""
display_alert "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
display_alert "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() {
display_alert "Start package img" "IMG" "info"
# 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
display_alert "End package img" "IMG" "info"
}
export -f amlbian_package_img
export -f amlbian_additional_insatll
# ==============================================================================
# End of function-img.sh
# ==============================================================================