#!/bin/bash #======================================================================================== # # This file is licensed under the terms of the GNU General Public # License version 2. This program is licensed "as is" without any # warranty of any kind, whether express or implied. # # This file is a part of the Armbian Rebuild and kernel Recompile script # https://github.com/ophub/amlogic-s9xxx-armbian # # Description: Run on x86_64 Ubuntu-20.04/22.04, Build armbian for Amlogic s9xxx tv box # Copyright (C) 2021- https://github.com/unifreq # Copyright (C) 2021- https://github.com/ophub/amlogic-s9xxx-armbian # # Command: sudo ./rebuild -d # Command optional parameters please refer to the source code repository # #==================================== Functions list ==================================== # # error_msg : Output error message # process_msg : Output process message # get_textoffset : Get kernel TEXT_OFFSET # # init_var : Initialize all variables # find_armbian : Find Armbian file (build/output/images/*.img) # download_kernel : Download the latest kernel # # confirm_version : Confirm version type # extract_armbian : Extract Armbian files # refactor_files : Refactor related files # make_image : Making Armbian file # copy_files : Copy the Armbian files # clean_tmp : Clear temporary files # # loop_rebuild : Loop to rebuild Armbian files # #============================ Set make environment variables ============================ # # Related file storage path make_path="${PWD}" armbian_outputpath="${make_path}/build/output/images" armbian_rebuild_file="${armbian_outputpath}/*.img" build_path="${make_path}/build-armbian" armbian_path="${build_path}/amlogic-armbian" kernel_path="${build_path}/amlogic-kernel" uboot_path="${build_path}/amlogic-u-boot" configfiles_path="${build_path}/common-files" tmp_dir="${make_path}/tmp_dir" tmp_outpath="${tmp_dir}/tmp_out" tmp_armbian="${tmp_dir}/tmp_armbian" tmp_build="${tmp_dir}/tmp_build" tmp_aml_image="${tmp_dir}/tmp_aml_image" arch_info="$(arch)" host_release="$(cat /etc/os-release | grep VERSION_CODENAME | cut -d"=" -f2)" # Get armbian ${VERSION_CODENAME}: such as [ jammy ] os_release_file="etc/os-release" # Set banner's ${BOARD_NAME}: such as [ s905x3 ] armbian_release_file="etc/armbian-release" # Add custom armbian firmware information ophub_release_file="etc/ophub-release" # Kernel files download repository kernel_repo="https://github.com/ophub/kernel/tree/main/pub" version_branch="stable" auto_kernel="true" build_kernel=("5.15.25" "5.10.100") # Set supported SoC build_armbian=( "s922x" "s922x-n2" "s922x-reva" "a311d" "s905x3" "s905x2" "s905x2-km3" "s905l3a" "s912" "s912-m8s" "s905d" "s905d-ki" "s905x" "s905w" "s905" ) # Set Armbian firmware size (SKIP_MB >= 4, BOOT_MB >= 256, ROOT_MB >= 2000) SKIP_MB="68" BOOT_MB="256" ROOT_MB="2748" # Set ROOTFS partition file system type, options: [ ext4 / btrfs ] ROOTFS_TYPE="ext4" # #======================================================================================== error_msg() { echo -e " [\033[1;91m Error \033[0m] ${1}" exit 1 } process_msg() { echo -e " [\033[1;92m ${soc} - ${kernel} \033[0m] ${1}" } get_textoffset() { vmlinuz_name="${1}" K510="1" # With TEXT_OFFSET patch is [ 0108 ], without TEXT_OFFSET patch is [ 0000 ] [[ "$(hexdump -n 15 -x "${vmlinuz_name}" 2>/dev/null | head -n 1 | awk '{print $7}')" == "0108" ]] && K510="0" } init_var() { cd ${make_path} # If it is followed by [ : ], it means that the option requires a parameter value get_all_ver=$(getopt "db:k:a:v:s:t:" "${@}") while [ -n "${1}" ]; do case "${1}" in -d | --default) : ${build_armbian:="${build_armbian}"} : ${build_kernel:="${build_kernel}"} : ${auto_kernel:="${auto_kernel}"} : ${version_branch:="${version_branch}"} : ${ROOT_MB:="${ROOT_MB}"} : ${ROOTFS_TYPE:="${ROOTFS_TYPE}"} ;; -b | --build) if [ -n "${2}" ]; then if [[ "${2}" != "all" ]]; then unset build_armbian oldIFS=$IFS IFS=_ build_armbian=(${2}) IFS=$oldIFS fi shift else error_msg "Invalid -b parameter [ ${2} ]!" fi ;; -k | --kernel) if [ -n "${2}" ]; then oldIFS=$IFS IFS=_ build_kernel=(${2}) IFS=$oldIFS shift else error_msg "Invalid -k parameter [ ${2} ]!" fi ;; -a | --autokernel) if [ -n "${2}" ]; then auto_kernel="${2}" shift else error_msg "Invalid -a parameter [ ${2} ]!" fi ;; -v | --versionbranch) if [ -n "${2}" ]; then version_branch="${2}" shift else error_msg "Invalid -v parameter [ ${2} ]!" fi ;; -s | --size) if [[ -n "${2}" && "${2}" -ge "2000" ]]; then ROOT_MB="${2}" shift else error_msg "Invalid -s parameter [ ${2} ]!" fi ;; -t | --rootfstype) if [[ -n "${2}" ]]; then ROOTFS_TYPE="${2}" shift else error_msg "Invalid -t parameter [ ${2} ]!" fi ;; *) error_msg "Invalid option [ ${1} ]!" ;; esac shift done } find_armbian() { cd ${make_path} # Get armbian release and version armbian_rebuild_name=$(ls ${armbian_rebuild_file} 2>/dev/null | head -n 1 | awk -F "/" '{print $NF}') [[ -n "${armbian_rebuild_name}" ]] || error_msg "The armbian original file does not exist: [ ${armbian_rebuild_file} ]" # Find armbian version info: such as [ 22.02.0 ] armbian_rebuild_version="$(echo ${armbian_rebuild_name} | grep -oE '[2-9][0-9].[0-9]{1,2}.[0-9]{1,2}' | head -n 1)" [[ -n "${armbian_rebuild_version}" ]] || { armbian_rebuild_version="22.02.02" echo -e "Missing armbian version info!" } echo -e "Armbian rebuild file: [ ${armbian_rebuild_name} ], Version: [ ${armbian_rebuild_version} ]" } download_kernel() { cd ${make_path} # Convert kernel library address to svn format if [[ ${kernel_repo} == http* && $(echo ${kernel_repo} | grep "tree/main") != "" ]]; then kernel_repo="${kernel_repo//tree\/main/trunk}" fi kernel_repo="${kernel_repo}/${version_branch}" # Set empty array tmp_arr_kernels=() # Convert kernel library address to API format server_kernel_url=${kernel_repo#*com\/} server_kernel_url=${server_kernel_url//trunk/contents} server_kernel_url="https://api.github.com/repos/${server_kernel_url}" # Query the latest kernel in a loop i=1 for KERNEL_VAR in ${build_kernel[*]}; do echo -e "(${i}) Auto query the latest kernel version of the same series for [ ${KERNEL_VAR} ]" MAIN_LINE_M=$(echo "${KERNEL_VAR}" | cut -d '.' -f1) MAIN_LINE_V=$(echo "${KERNEL_VAR}" | cut -d '.' -f2) MAIN_LINE_S=$(echo "${KERNEL_VAR}" | cut -d '.' -f3) MAIN_LINE="${MAIN_LINE_M}.${MAIN_LINE_V}" # Check the version on the server (e.g LATEST_VERSION="124") LATEST_VERSION=$(curl -s "${server_kernel_url}" | grep "name" | grep -oE "${MAIN_LINE}.[0-9]+" | sed -e "s/${MAIN_LINE}.//g" | sort -n | sed -n '$p') if [[ "$?" -eq "0" && ! -z "${LATEST_VERSION}" ]]; then tmp_arr_kernels[${i}]="${MAIN_LINE}.${LATEST_VERSION}" else tmp_arr_kernels[${i}]="${KERNEL_VAR}" fi echo -e "(${i}) [ ${tmp_arr_kernels[$i]} ] is latest kernel. \n" let i++ done # Reset the kernel array to the latest kernel version unset build_kernel build_kernel=${tmp_arr_kernels[*]} # Synchronization related kernel i=1 for KERNEL_VAR in ${build_kernel[*]}; do if [ ! -d "${kernel_path}/${KERNEL_VAR}" ]; then echo -e "(${i}) [ ${KERNEL_VAR} ] Kernel loading from [ ${kernel_repo}/${KERNEL_VAR} ]" svn export ${kernel_repo}/${KERNEL_VAR} ${kernel_path}/${KERNEL_VAR} --force else echo -e "(${i}) [ ${KERNEL_VAR} ] Kernel is in the local directory." fi let i++ done sync } confirm_version() { process_msg " (1/6) Confirm version type." cd ${make_path} # Confirm soc branch case "${soc}" in s905x3 | x96 | hk1 | h96 | ugoosx3) FDTFILE="meson-sm1-x96-max-plus-100m.dtb" UBOOT_OVERLOAD="u-boot-x96maxplus.bin" MAINLINE_UBOOT="x96maxplus-u-boot.bin.sd.bin" ANDROID_UBOOT="hk1box-bootloader.img" ;; s905x2 | x96max4g | x96max2g) FDTFILE="meson-g12a-x96-max.dtb" UBOOT_OVERLOAD="u-boot-x96max.bin" MAINLINE_UBOOT="x96max-u-boot.bin.sd.bin" ANDROID_UBOOT="" ;; s905x2-km3) FDTFILE="meson-g12a-sei510.dtb" UBOOT_OVERLOAD="u-boot-x96max.bin" MAINLINE_UBOOT="x96max-u-boot.bin.sd.bin" ANDROID_UBOOT="" ;; s905l3a | e900v22c | e900v22d) FDTFILE="meson-g12a-s905l3a-e900v22c.dtb" UBOOT_OVERLOAD="u-boot-e900v22c.bin" MAINLINE_UBOOT="e900v22c-u-boot.bin.sd.bin" ANDROID_UBOOT="" ;; s905x | hg680p | b860h) FDTFILE="meson-gxl-s905x-p212.dtb" UBOOT_OVERLOAD="u-boot-p212.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s905w | x96mini | tx3mini) FDTFILE="meson-gxl-s905w-tx3-mini.dtb" UBOOT_OVERLOAD="u-boot-s905x-s912.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s905d | n1) FDTFILE="meson-gxl-s905d-phicomm-n1.dtb" UBOOT_OVERLOAD="u-boot-n1.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="u-boot-2015-phicomm-n1.bin" ;; s905d-ki) FDTFILE="meson-gxl-s905d-mecool-ki-pro.dtb" UBOOT_OVERLOAD="u-boot-p201.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s905 | beelinkminimx | mxqpro+) FDTFILE="meson-gxbb-beelink-mini-mx.dtb" #FDTFILE="meson-gxbb-mxq-pro-plus.dtb" #FDTFILE="meson-gxbb-vega-s95-telos.dtb" UBOOT_OVERLOAD="u-boot-s905.bin" #UBOOT_OVERLOAD="u-boot-p201.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s912 | h96proplus | octopus) FDTFILE="meson-gxm-octopus-planet.dtb" UBOOT_OVERLOAD="u-boot-zyxq.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s912-m8s | s912-m8s-pro) FDTFILE="meson-gxm-q201.dtb" UBOOT_OVERLOAD="u-boot-s905x-s912.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; s922x | belink | belinkpro | ugoos) FDTFILE="meson-g12b-gtking-pro.dtb" UBOOT_OVERLOAD="u-boot-gtkingpro.bin" MAINLINE_UBOOT="gtkingpro-u-boot.bin.sd.bin" ANDROID_UBOOT="" ;; s922x-n2 | odroid-n2) FDTFILE="meson-g12b-odroid-n2.dtb" UBOOT_OVERLOAD="u-boot-gtkingpro.bin" MAINLINE_UBOOT="odroid-n2-u-boot.bin.sd.bin" ANDROID_UBOOT="" ;; s922x-reva) FDTFILE="meson-g12b-gtking-pro.dtb" UBOOT_OVERLOAD="u-boot-gtkingpro-rev-a.bin" MAINLINE_UBOOT="" ANDROID_UBOOT="" ;; a311d | khadas-vim3) FDTFILE="meson-g12b-a311d-khadas-vim3.dtb" UBOOT_OVERLOAD="u-boot-gtkingpro.bin" MAINLINE_UBOOT="khadas-vim3-u-boot.sd.bin" ANDROID_UBOOT="" ;; *) error_msg "Have no this soc: [ ${soc} ]" ;; esac # Confirm UUID ROOTFS_UUID="$(cat /proc/sys/kernel/random/uuid)" [ -z "${ROOTFS_UUID}" ] && ROOTFS_UUID="$(uuidgen)" [ -z "${ROOTFS_UUID}" ] && error_msg "The uuidgen is invalid, cannot continue." } extract_armbian() { process_msg " (2/6) Extract old armbian files." cd ${make_path} rm -rf ${tmp_dir} 2>/dev/null && sync mkdir -p ${tmp_outpath} ${tmp_armbian} ${tmp_build} ${tmp_aml_image} && sync armbian_image_file="${tmp_aml_image}/armbian_${soc}_${kernel}.img" rm -f ${armbian_image_file} 2>/dev/null && sync cp -f "${armbian_outputpath}/${armbian_rebuild_name}" "${armbian_image_file}" && sync loop_old=$(losetup -P -f --show "${armbian_image_file}") [ ${loop_old} ] || error_msg "losetup ${armbian_image_file} failed." if ! mount ${loop_old}p1 ${tmp_armbian}; then error_msg "mount ${loop_old}p1 failed!" fi cd ${tmp_armbian} # Find ID in ${os_release_file}: such as [ubuntu/debian] release_codeid="$(cat ${os_release_file} | grep -oE "^ID=.*" | cut -d"=" -f2)" [ -z "${release_codeid}" ] && error_msg "The [ ${os_release_file}: ID ] is invalid." # Find VERSION_CODENAME in ${os_release_file}: such as [jammy/focal/bullseye] release_codename="$(cat ${os_release_file} | grep -oE "^VERSION_CODENAME=.*" | cut -d"=" -f2)" [ -z "${release_codename}" ] && error_msg "The [ ${os_release_file}: VERSION_CODENAME ] is invalid." # Delete all files of /boot partition and replace it later rm -rf boot/* 2>/dev/null # Delete the kernel files and replace it later rm -rf usr/lib/modules/* usr/local/include/* 2>/dev/null # Delete the symbolic link files and relink it later rm -rf bin lib sbin tmp var/sbin 2>/dev/null sync } refactor_files() { process_msg " (3/6) Refactor related files." cd ${make_path} # Create a dual-partition general directory tag_bootfs="${tmp_build}/bootfs" tag_rootfs="${tmp_build}/rootfs" mkdir -p ${tag_bootfs} ${tag_rootfs} && sync # Copy the full Armbian image cp -rf ${tmp_armbian}/* ${tag_rootfs} && sync # Unzip the relevant files tar -xJf "${armbian_path}/boot-common.tar.xz" -C ${tag_bootfs} tar -xJf "${armbian_path}/firmware.tar.xz" -C ${tag_rootfs}/usr # Copy the same files [[ "$(ls ${configfiles_path}/bootfs 2>/dev/null | wc -w)" -ne "0" ]] && cp -rf ${configfiles_path}/bootfs/* ${tag_bootfs} [[ "$(ls ${configfiles_path}/rootfs 2>/dev/null | wc -w)" -ne "0" ]] && cp -rf ${configfiles_path}/rootfs/* ${tag_rootfs} # Copy the bootloader files [ -d "${tag_rootfs}/usr/lib/u-boot" ] || mkdir -p ${tag_rootfs}/usr/lib/u-boot cp -f ${uboot_path}/bootloader/* ${tag_rootfs}/usr/lib/u-boot # Copy the overload files cp -f ${uboot_path}/overload/* ${tag_bootfs} # Replace the kernel build_boot=$(ls ${kernel_path}/${kernel}/boot-${kernel}-*.tar.gz 2>/dev/null | head -n 1) build_dtb=$(ls ${kernel_path}/${kernel}/dtb-amlogic-${kernel}-*.tar.gz 2>/dev/null | head -n 1) build_modules=$(ls ${kernel_path}/${kernel}/modules-${kernel}-*.tar.gz 2>/dev/null | head -n 1) build_header=$(ls ${kernel_path}/${kernel}/header-${kernel}-*.tar.gz 2>/dev/null | head -n 1) [[ -n "${build_boot}" && -n "${build_dtb}" && -n "${build_modules}" && -n "${build_header}" ]] || error_msg "The 4 kernel missing." # 01 For /boot five files tar -xzf ${build_boot} -C ${tag_bootfs} && sync [[ "$(ls ${tag_bootfs}/*-${kernel}-* -l 2>/dev/null | grep "^-" | wc -l)" -ge "4" ]] || error_msg "The /boot files is missing." (cd ${tag_bootfs} && cp -f uInitrd-* uInitrd && cp -f vmlinuz-* zImage && sync) get_textoffset "${tag_bootfs}/zImage" # 02 For dtb files tar -xzf ${build_dtb} -C ${tag_bootfs}/dtb/amlogic && sync # 03 For usr/lib/modules/* tar -xzf ${build_modules} -C ${tag_rootfs}/usr/lib/modules && sync (cd ${tag_rootfs}/usr/lib/modules/${kernel}-*/ && rm -f build source 2>/dev/null && sync) [[ "$(ls ${tag_rootfs}/usr/lib/modules/${kernel}-* -l 2>/dev/null | grep "^d" | wc -l)" -eq "1" ]] || error_msg "Missing kernel." # 04 For header files, usr/local/include tar -xzf ${build_header} -C ${tag_rootfs}/usr/local && sync # Set the type of file system if [[ "${ROOTFS_TYPE}" == "btrfs" ]]; then uenv_mount_string="UUID=${ROOTFS_UUID} rootflags=compress=zstd:6 rootfstype=btrfs" fstab_mount_string="defaults,noatime,compress=zstd:6" else uenv_mount_string="UUID=${ROOTFS_UUID} rootflags=data=writeback rw rootfstype=ext4" fstab_mount_string="defaults,noatime,errors=remount-ro" fi # Processing partition files: bootfs cd ${tag_bootfs} # Add u-boot.ext for 5.10 kernel if [[ "${K510}" -eq "1" && -n "${UBOOT_OVERLOAD}" && -f "${UBOOT_OVERLOAD}" ]]; then cp -f ${UBOOT_OVERLOAD} u-boot.ext chmod +x u-boot.ext elif [[ "${K510}" -eq "1" ]] && [[ -z "${UBOOT_OVERLOAD}" || ! -f "${UBOOT_OVERLOAD}" ]]; then error_msg "${soc} SoC does not support using ${kernel} kernel, missing u-boot." fi # Edit the uEnv.txt boot_conf_file="uEnv.txt" [ -f "${boot_conf_file}" ] || error_msg "The [ ${boot_conf_file} ] file does not exist." sed -i "s|LABEL=ROOTFS|${uenv_mount_string}|g" ${boot_conf_file} sed -i "s|meson.*.dtb|${FDTFILE}|g" ${boot_conf_file} # Edit extlinux/extlinux.conf (Temporarily tested in 5.10 kernel) boot_extlinux_file="extlinux/extlinux.conf" if [[ -f "${boot_extlinux_file}" ]]; then if [[ "${K510}" -eq "1" ]]; then sed -i "s|LABEL=ROOTFS|${uenv_mount_string}|g" ${boot_extlinux_file} sed -i "s|meson.*.dtb|${FDTFILE}|g" ${boot_extlinux_file} else rm -rf extlinux 2>/dev/null fi fi # Processing partition files: rootfs cd ${tag_rootfs} # Delete related files rm -f etc/apt/sources.list.save 2>/dev/null rm -f etc/apt/*.gpg~ 2>/dev/null rm -f etc/systemd/system/basic.target.wants/armbian-resize-filesystem.service 2>/dev/null rm -rf usr/share/doc/linux-image-*-meson64 2>/dev/null rm -rf usr/lib/linux-image-*-meson64 2>/dev/null rm -f usr/sbin/ddbr 2>/dev/null rm -f var/lib/dpkg/info/linux-image* 2>/dev/null # Renaming/disabling related files mv -f etc/udev/rules.d/hdmi.rules etc/udev/rules.d/hdmi.rules.bak 2>/dev/null # Fix common releases permissions [ -d "var/tmp" ] && sudo chmod 777 var/tmp [ -d "etc/update-motd.d" ] && sudo chmod 755 etc/update-motd.d/* [ -d "var/cache/man" ] && sudo chown man:root var/cache/man -R [ -d "var/cache/man" ] && sudo chmod g+s var/cache/man -R [ -f "usr/bin/sudo" ] && sudo chown root:root usr/bin/sudo [ -f "usr/bin/sudo" ] && sudo chmod 4755 usr/bin/sudo # Fix focal permissions [ -f "usr/lib/sudo/sudoers.so" ] && sudo chown 0 usr/lib/sudo/sudoers.so [ -f "usr/lib/sudo/sudoers.so" ] && sudo chmod 644 usr/lib/sudo/sudoers.so [ -f "usr/lib/policykit-1/polkit-agent-helper-1" ] && sudo chmod 4755 usr/lib/policykit-1/polkit-agent-helper-1 # Fix jammy permissions [ -f "usr/libexec/sudo/sudoers.so" ] && sudo chown 0 usr/libexec/sudo/sudoers.so [ -f "usr/libexec/sudo/sudoers.so" ] && sudo chmod 644 usr/libexec/sudo/sudoers.so [ -f "usr/libexec/polkit-agent-helper-1" ] && sudo chmod 4755 usr/libexec/polkit-agent-helper-1 # Rebuild symbolic link files (ln -sf ${target} ${symbolic_link_file}) ln -sf /usr/bin bin ln -sf /usr/lib lib ln -sf /usr/sbin sbin ln -sf /var/tmp tmp ln -sf /usr/share/zoneinfo/Asia/Shanghai etc/localtime ln -sf /usr/sbin/armbian-ddbr usr/sbin/ddbr # Add custom firmware information echo "VERSION_CODEID='${release_codeid}'" >>${ophub_release_file} 2>/dev/null echo "VERSION_CODENAME='${release_codename}'" >>${ophub_release_file} 2>/dev/null echo "FDTFILE='${FDTFILE}'" >>${ophub_release_file} 2>/dev/null echo "UBOOT_OVERLOAD='${UBOOT_OVERLOAD}'" >>${ophub_release_file} 2>/dev/null echo "MAINLINE_UBOOT='/usr/lib/u-boot/${MAINLINE_UBOOT}'" >>${ophub_release_file} 2>/dev/null echo "ANDROID_UBOOT='/usr/lib/u-boot/${ANDROID_UBOOT}'" >>${ophub_release_file} 2>/dev/null echo "KERNEL_VERSION='${kernel}'" >>${ophub_release_file} 2>/dev/null echo "SOC='${soc}'" >>${ophub_release_file} 2>/dev/null echo "K510='${K510}'" >>${ophub_release_file} 2>/dev/null echo "PACKAGED_DATE='$(date +%Y-%m-%d)'" >>${ophub_release_file} 2>/dev/null # Edit the etc/fstab [ -f "etc/fstab" ] || error_msg "The etc/fstab File does not exist." sed -i '/LABEL=ROOTFS/d' etc/fstab 2>/dev/null echo "UUID=${ROOTFS_UUID} / ${ROOTFS_TYPE} ${fstab_mount_string} 0 0" >>etc/fstab # Custom banner name sed -i "s|BOARD_NAME=.*|BOARD_NAME=\"Aml ${soc}\"|g" ${armbian_release_file} 2>/dev/null # Make the .bashrc take effect, Default shell settings file: /etc/default/useradd echo '[[ "${SHELL}" == *bash && -f "${HOME}/.bashrc" ]] && . ${HOME}/.bashrc' >>etc/profile # Reduce network latency [ A start job is running for raise network interfaces (5 mins 1 sec) ] network_service="usr/lib/systemd/system/networking.service" sed -i "s|TimeoutStartSec=.*|TimeoutStartSec=10sec|g" ${network_service} 2>/dev/null # Add tasks that need to be executed on initial startup armbian_firstrun="usr/lib/armbian/armbian-firstrun" sed -i '/armbian-release/i\[ -f "/usr/sbin/armbian-fix" ] && . /usr/sbin/armbian-fix' ${armbian_firstrun} 2>/dev/null # Get random macaddr mac_hexchars="0123456789ABCDEF" mac_end=$(for i in {1..6}; do echo -n ${mac_hexchars:$((${RANDOM} % 16)):1}; done | sed -e 's/\(..\)/:\1/g') random_macaddr="9E:61${mac_end}" # # Set interfaces macaddr interfaces_file="etc/network/interfaces" [ -f "${interfaces_file}" ] && sed -i "s|hwaddress ether.*|hwaddress ether ${random_macaddr}:AA|g" ${interfaces_file} # # Optimize wifi/bluetooth module [ -d "usr/lib/firmware/brcm" ] && ( cd usr/lib/firmware/brcm/ && mv -f ../*.hcd . 2>/dev/null # gtking/gtking pro is bcm4356 wifi/bluetooth, wifi5 module AP6356S sed -e "s/macaddr=.*/macaddr=${random_macaddr}:00/" "brcmfmac4356-sdio.txt" >"brcmfmac4356-sdio.azw,gtking.txt" # gtking/gtking pro is bcm4356 wifi/bluetooth, wifi6 module AP6275S sed -e "s/macaddr=.*/macaddr=${random_macaddr}:01/" "brcmfmac4375-sdio.txt" >"brcmfmac4375-sdio.azw,gtking.txt" # Phicomm N1 is bcm43455 wifi/bluetooth sed -e "s/macaddr=.*/macaddr=${random_macaddr}:02/" "brcmfmac43455-sdio.txt" >"brcmfmac43455-sdio.phicomm,n1.txt" # MXQ Pro+ is AP6330(bcm4330) wifi/bluetooth sed -e "s/macaddr=.*/macaddr=${random_macaddr}:03/" "brcmfmac4330-sdio.txt" >"brcmfmac4330-sdio.crocon,mxq-pro-plus.txt" # HK1 Box & H96 Max X3 is bcm54339 wifi/bluetooth sed -e "s/macaddr=.*/macaddr=${random_macaddr}:04/" "brcmfmac4339-sdio.ZP.txt" >"brcmfmac4339-sdio.amlogic,sm1.txt" # old ugoos x3 is bcm43455 wifi/bluetooth sed -e "s/macaddr=.*/macaddr=${random_macaddr}:05/" "brcmfmac43455-sdio.txt" >"brcmfmac43455-sdio.amlogic,sm1.txt" # new ugoos x3 is brm43456 sed -e "s/macaddr=.*/macaddr=${random_macaddr}:06/" "brcmfmac43456-sdio.txt" >"brcmfmac43456-sdio.amlogic,sm1.txt" # x96max plus v5.1 (ip1001m phy) adopts am7256 (brcm4354) sed -e "s/macaddr=.*/macaddr=${random_macaddr}:07/" "brcmfmac4354-sdio.txt" >"brcmfmac4354-sdio.amlogic,sm1.txt" ) sync } make_image() { process_msg " (4/6) Make new armbian image." cd ${make_path} # Make Amlogic s9xxx armbian build_image_file="${tmp_outpath}/Armbian_${armbian_rebuild_version}_Aml_${soc}_${release_codename}_${kernel}_$(date +"%Y.%m.%d.%H%M").img" rm -f ${build_image_file} 2>/dev/null && sync IMG_SIZE=$((SKIP_MB + BOOT_MB + ROOT_MB)) dd if=/dev/zero of=${build_image_file} bs=1M count=${IMG_SIZE} conv=fsync >/dev/null 2>&1 sync parted -s ${build_image_file} mklabel msdos 2>/dev/null parted -s ${build_image_file} mkpart primary fat32 $((SKIP_MB))MiB $((SKIP_MB + BOOT_MB - 1))MiB 2>/dev/null parted -s ${build_image_file} mkpart primary ${ROOTFS_TYPE} $((SKIP_MB + BOOT_MB))MiB 100% 2>/dev/null sync loop_new=$(losetup -P -f --show "${build_image_file}") [ ${loop_new} ] || error_msg "losetup ${build_image_file} failed." mkfs.vfat -n "BOOT" ${loop_new}p1 >/dev/null 2>&1 if [[ "${ROOTFS_TYPE}" == "btrfs" ]]; then mkfs.btrfs -f -U ${ROOTFS_UUID} -L "ROOTFS" -m single ${loop_new}p2 >/dev/null 2>&1 else mkfs.ext4 -F -q -U ${ROOTFS_UUID} -L "ROOTFS" -m 0 ${loop_new}p2 >/dev/null 2>&1 fi # Write the specified bootloader if [[ -n "${MAINLINE_UBOOT}" && -f "${tag_rootfs}/usr/lib/u-boot/${MAINLINE_UBOOT}" ]]; then dd if="${tag_rootfs}/usr/lib/u-boot/${MAINLINE_UBOOT}" of="${loop_new}" bs=1 count=444 conv=fsync 2>/dev/null dd if="${tag_rootfs}/usr/lib/u-boot/${MAINLINE_UBOOT}" of="${loop_new}" bs=512 skip=1 seek=1 conv=fsync 2>/dev/null #echo -e "For [ ${soc} ] write Mainline bootloader: ${MAINLINE_UBOOT}" elif [[ -n "${ANDROID_UBOOT}" && -f "${tag_rootfs}/usr/lib/u-boot/${ANDROID_UBOOT}" ]]; then dd if="${tag_rootfs}/usr/lib/u-boot/${ANDROID_UBOOT}" of="${loop_new}" bs=1 count=444 conv=fsync 2>/dev/null dd if="${tag_rootfs}/usr/lib/u-boot/${ANDROID_UBOOT}" of="${loop_new}" bs=512 skip=1 seek=1 conv=fsync 2>/dev/null #echo -e "For [ ${soc} ] write Android bootloader: ${ANDROID_UBOOT}" fi sync } copy_files() { process_msg " (5/6) Copy the Armbian files." cd ${make_path} build_image_bootfs="${tmp_outpath}/bootfs" build_image_rootfs="${tmp_outpath}/rootfs" mkdir -p ${build_image_bootfs} ${build_image_rootfs} && sync if ! mount ${loop_new}p2 ${build_image_rootfs}; then error_msg "mount ${loop_new}p2 failed!" fi if ! mount ${loop_new}p1 ${build_image_bootfs}; then error_msg "mount ${loop_new}p1 failed!" fi cp -rf ${tag_bootfs}/* ${build_image_bootfs} cp -rf ${tag_rootfs}/* ${build_image_rootfs} sync && sleep 3 } clean_tmp() { process_msg " (6/6) Clear temp files." cd ${make_path} umount -f ${tmp_armbian} 2>/dev/null losetup -d ${loop_old} 2>/dev/null umount -f ${build_image_bootfs} 2>/dev/null umount -f ${build_image_rootfs} 2>/dev/null losetup -d ${loop_new} 2>/dev/null cd ${tmp_outpath} gzip *.img && sync && mv -f *.img.gz ${armbian_outputpath} sync cd ${make_path} rm -rf ${tmp_dir} 2>/dev/null sync } loop_rebuild() { cd ${make_path} j=1 for b in ${build_armbian[*]}; do i=1 for k in ${build_kernel[*]}; do { echo -n "(${j}.${i}) Start building Armbian [ ${b} - ${k} ]. " now_remaining_space=$(df -hT ${PWD} | grep '/dev/' | awk '{print $5}' | sed 's/.$//' | awk -F "." '{print $1}') if [[ "${now_remaining_space}" -le "2" ]]; then echo "Remaining space is less than 2G, exit this build. \n" break else echo "Remaining space is ${now_remaining_space}G." fi # The loop variable assignment soc="${b}" kernel="${k}" # Execute the following functions in sequence confirm_version extract_armbian refactor_files make_image copy_files clean_tmp echo -e "(${j}.${i}) Armbian build successfully. \n" let i++ } done let j++ done } # Check script permission [[ "$(id -u)" == "0" ]] || error_msg "please run this script as root: [ sudo ./$0 ]" # Show welcome and server start information echo -e "Welcome to Rebuild Armbian for Amlogic s9xxx tv box!" echo -e "Server running on Ubuntu: [ Release: ${host_release} / Host: ${arch_info} ] \n" echo -e "Server CPU configuration information: \n$(cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c) \n" echo -e "Server memory usage: \n$(free -h) \n" echo -e "Server space usage before starting to compile: \n$(df -hT ${PWD}) \n" # # Initialize variables init_var "${@}" # Find rebuild files find_armbian # Download the latest kernel [ "${auto_kernel}" == "true" ] && download_kernel echo -e "Armbian SoC List: [ $(echo ${build_armbian[*]} | tr "\n" " ") ]" echo -e "Kernel List: [ $(echo ${build_kernel[*]} | tr "\n" " ") ]" echo -e "ROOTFS Type: [ ${ROOTFS_TYPE} ] \n" # Loop to rebuild armbian firmware loop_rebuild # # Show server end information echo -e "Server space usage after compilation: \n$(df -hT ${PWD}) \n" # All process completed wait