找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888广告投放联系QQ68610888
广告投放联系QQ68610888广告投放联系QQ68610888
查看: 425|回复: 2

S905L3B芯片 刷飞牛 fnOS emmc 想预留5G空间存储,求问改哪儿

[复制链接]
发表于 2026-2-8 17:55 | 显示全部楼层 |阅读模式
有大佬发过旧版的改 fnnas-install 实现预留空间做存储分区。  但是新的这个找不到位置了。求大佬赐教

只谈技术、莫论政事!(点击见详情) | 互相尊重、友善交流、切勿过度反应、玻璃心。胡乱输入灌水等操作将会被封禁ID。
 楼主| 发表于 2026-2-8 17:55 | 显示全部楼层
#!/bin/bash
#================================================================================================
#
# This file is licensed under the terms of the GNU General PublicF
# 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 remake fnnas
# https://github.com/ophub/fnnas
#
# Function: Install fnnas to eMMC for Amlogic box
# Copyright (C) 2021- https://github.com/unifreq/openwrt_packit
# Copyright (C) 2022- https://github.com/7Ji/ampart
# Copyright (C) 2021- https://github.com/ophub/fnnas
#
# Command: fnnas-install [-m yes/no] [-a yes/no] [-l yes/no]
# Optional parameters: -m = use mainline u-boot (default: no)
#                      -a = use ampart partition table adjustment tool (default: yes)
#                      -l = show a list of all devices (default: no)
#
# Examples:
#  Use mainline u-boot       : fnnas-install -m yes
#  Disable ampart tool       : fnnas-install -a no
#  Show all available devices: fnnas-install -l yes
#
#======================================== Functions list ========================================
#
# error_msg           : Output error message
# check_depends       : Check dependencies
# init_var            : Initialize all variables
# ampart_tool         : Repartition using ampart
# search_aml_model    : Search the model list
# show_aml_model      : Display the model list
# show_partition_menu : Display disk option info
# partition_sizing    : Determine partition sizes
# create_partition    : Create emmc partition
# copy_bootfs         : Copy bootfs partition files
# copy_rootfs         : Copy rootfs partition files
#
#==================================== Set default parameters ====================================
#
# Use mainline u-boot by default (-m)
auto_mainline_uboot="no"
# Use ampart partition tool by default (-a)
use_ampart="no"
# Show all device list by default (-l)
show_all_list="no"

# Set install list profile
model_conf="/etc/model_database.conf"
# Add custom fnnas firmware information
ophub_release_file="/etc/ophub-release"
# Add fnnas configuration file
fnnas_conf="/etc/fnnas.conf"
# Set the installation file preprocessing directory
tmp_path="/ddbr"

# Set font color
STEPS="[\033[95m STEPS \033[0m]"
INFO="[\033[94m INFO \033[0m]"
SUCCESS="[\033[92m SUCCESS \033[0m]"
OPTIONS="[\033[93m OPTIONS \033[0m]"
ERROR="[\033[91m ERROR \033[0m]"
IDX="\033[4;93m3\033[0m"
#
#================================================================================================

# Encountered a serious error, abort the script execution
error_msg() {
    echo -e "${ERROR} ${1}"
    exit 1
}

# Check dependencies
check_depends() {
    echo -e "${STEPS} Checking dependencies..."

    is_missing="0"
    necessary_packages=("tar" "hexdump" "mkfs.vfat" "mkfs.ext4" "mkfs.btrfs" "parted" "losetup" "fdisk" "lsblk")
    install_packages=("tar" "bsdextrautils" "dosfstools" "e2fsprogs" "btrfs-progs" "parted" "mount" "fdisk" "util-linux")

    i="1"
    for package in ${necessary_packages
  • }; do
            [[ -n "$(which "${package}" 2>/dev/null)" ]] || is_missing="1"
            ((i++))
        done

        if [[ "${is_missing}" -eq "1" ]]; then
            echo -e "${INFO} Installing necessary dependencies."
            sudo apt-get update
            sudo apt-get install -y ${install_packages
  • }
            [[ "${?}" -eq "0" ]] || error_msg "Failed to install dependencies, aborting!"
        else
            echo -e "${INFO} Dependency check completed. Proceeding installation..."
        fi
    }

    # Initialize all variables
    init_var() {
        echo -e "${STEPS} Initializing the environment..."

        # If it is followed by [ : ], it means that the option requires a parameter value
        get_all_ver="$(getopt "m:a:l:" "${@}")"

        while [[ -n "${1}" ]]; do
            case "${1}" in
            -m | --Mainline_u-boot)
                if [[ -n "${2}" ]]; then
                    [[ "${2}" == "yes" ]] && auto_mainline_uboot="yes" || auto_mainline_uboot="no"
                    shift
                else
                    error_msg "Invalid -m parameter [ ${2} ]!"
                fi
                ;;
            -a | --Ampart_tool)
                if [[ -n "${2}" ]]; then
                    [[ "${2}" == "yes" ]] && use_ampart="yes" || use_ampart="no"
                    shift
                else
                    error_msg "Invalid -a parameter [ ${2} ]!"
                fi
                ;;
            -l | --List_all)
                if [[ -n "${2}" ]]; then
                    [[ "${2}" == "yes" ]] && show_all_list="yes" || show_all_list="no"
                    shift
                else
                    error_msg "Invalid -l parameter [ ${2} ]!"
                fi
                ;;
            *)
                error_msg "Invalid option [ ${1} ]!"
                ;;
            esac
            shift
        done

        # Display settings results
        echo -e "${INFO} Use mainline u-boot: [ ${auto_mainline_uboot} ]"
        echo -e "${INFO} Use ampart tool: [ ${use_ampart} ]"
        echo -e "${INFO} Show all devices: [ ${show_all_list} ]"

        # Find a list of devices of the same family
        SEARCH_FAMILY=""
        [[ "${show_all_list}" == "no" ]] && {
            [[ -s "${ophub_release_file}" ]] || error_msg "[ ${ophub_release_file} ] file is missing!"
            source "${ophub_release_file}" && SEARCH_FAMILY="$(basename ${FAMILY})"
            [[ -n "${SEARCH_FAMILY}" ]] && SEARCH_FAMILY="{SEARCH_FAMILY}:"
        }

        # Check if the ${fnnas_conf} file exists
        if [[ -f "${fnnas_conf}" ]]; then
            source "${fnnas_conf}"
        else
            # Set root partition size limit (Unit: GiB)
            echo "rootfs_limit_gib=\"16\"" >"${fnnas_conf}"
            echo "rootfs_resize=\"yes\"" >>"${fnnas_conf}"
            rootfs_limit_gib="16"
            rootfs_resize="yes"
        fi
        # Ensure variables are set
        [[ -n "${rootfs_limit_gib}" ]] || rootfs_limit_gib="16"
        [[ -n "${rootfs_resize}" ]] || rootfs_resize="yes"
        MG="${rootfs_limit_gib}GiB"

        # Check if the ${model_conf} file exists
        [[ -s "${model_conf}" ]] || error_msg "[ ${model_conf} ] file is missing!"
        model_database="$(cat ${model_conf} | sed -e 's/NA//g' -e 's/NULL//g' -e 's/[ ][ ]*//g' | grep -E "^[0-9]{1,3}:.*${SEARCH_FAMILY}.*")"
        if [[ -z "${model_database}" ]]; then
            if [[ "${SEARCH_FAMILY}" == ":meson-gxbb:" ]]; then
                error_msg "The [ s905 ] series do not support writing to eMMC. Please use it via USB."
            else
                error_msg "The [ ${SEARCH_FAMILY} ] series in the [ ${model_conf} ] file is empty and does not support write to eMMC!"
            fi
        fi

        # Check if current system is booted from eMMC
        root_devname="$(df / | tail -n1 | awk '{print $1}' | awk -F '/' '{print substr($3, 1, length($3)-2)}')"
        if lsblk -l | grep -E "^${root_devname}boot0" >/dev/null; then
            error_msg "Current system is already installed to eMMC!"
        fi

        # Find emmc disk, first find emmc containing boot0 partition
        install_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?boot0)' | sed "s/boot0//g")"
        # Find emmc disk, find emmc that does not contain the boot0 partition
        [[ -z "${install_emmc}" ]] && install_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?)' | grep -vE ^${root_devname} | sort -u)"
        # Check if emmc exists
        [[ -z "${install_emmc}" ]] && error_msg "Internal eMMC storage was't found in this device!"
        # Location of emmc
        DEV_EMMC="/dev/${install_emmc}"
        echo -e "${INFO} Internal eMMC : [ ${DEV_EMMC} ]"

        # Create a file preprocessing directory
        DIR_INSTALL="${tmp_path}/install"
        [[ -d "${DIR_INSTALL}" ]] && rm -rf ${DIR_INSTALL}
        mkdir -p ${DIR_INSTALL} && chmod 777 ${tmp_path}

        # Regenerate new machine-id
        rm -f /etc/machine-id /var/lib/dbus/machine-id
        dbus-uuidgen --ensure=/etc/machine-id
        dbus-uuidgen --ensure

        # Generate New BOOT_UUID
        BOOT_UUID="$(cat /proc/sys/kernel/random/uuid)"
        [[ -z "${BOOT_UUID}" ]] && BOOT_UUID="$(uuidgen)"
        [[ -z "${BOOT_UUID}" ]] && error_msg "The uuidgen is invalid, cannot continue."
        FAT_ID_RAW=$(echo "${BOOT_UUID}" | tr -d '-' | cut -c1-8)
        FAT_ID_FSTAB=$(echo "${FAT_ID_RAW}" | awk '{print toupper(substr($0,1,4) "-" substr($0,5,4))}')
        # Generate New ROOTFS UUID
        ROOTFS_UUID="$(cat /proc/sys/kernel/random/uuid)"
        [[ -z "${ROOTFS_UUID}" ]] && ROOTFS_UUID="$(uuidgen)"
        [[ -z "${ROOTFS_UUID}" ]] && error_msg "The new UUID is invalid, cannot continue."

        # Get kernel TEXT_OFFSET, For u-boot.ext and u-boot.emmc
        # With TEXT_OFFSET patch is [ 0108 ], without TEXT_OFFSET patch is [ 0000 ] and need to ues [ UBOOT_OVERLOAD ] file.
        NEED_OVERLOAD="yes"
        [[ "$(hexdump -n 15 -x "/boot/zImage" 2>/dev/null | head -n 1 | awk '{print $7}')" == "0108" ]] && NEED_OVERLOAD="no"
    }

    # Project repository:   https://github.com/7Ji/ampart
    # Download from:        https://github.com/7Ji/ampart/re ... 2-aarch64-static.gz
    # Function description: ampart is a partitioning tool which can modify the proprieary partition table on internal eMMC.
    ampart_tool() {
        # declare the partition layout
        local snapshot_expected='data::-1:4'

        # Note there's no quote around ${snapshot_expected}
        ampart "${DEV_EMMC}" --mode dclone ${snapshot_expected} &>/dev/null
        if ((${?})); then
            # Handle the situation where ampart fails to change the layout
            return 1
        fi

        local log="$(ampart "${DEV_EMMC}" --mode dsnapshot 2>/dev/null)"
        if ((${?})); then
            # Handle the situation where ampart fails to read the new partitions
            return 2
        fi

        local snapshots
        readarray -d $'\n' -t snapshots <<<"${log}"

        # compare snapshots, 0 here refers to the decimal one
        if [[ "${snapshots[0]}" == "${snapshot_expected}" ]]; then
            # Successfully written the partitions
            return 0
        else
            # Result partitions different, maybe should handle it
            return 3
        fi
    }

    # Search the model list
    search_aml_model() {
        local search_soc_id="${1}"
        local ret_count="$(echo "${model_database}" | grep -E "^${search_soc_id}:" | wc -l)"
        if [[ "${ret_count}" -eq "1" ]]; then
            echo "${model_database}" | grep -E "^${search_soc_id}:"
        fi
    }

    # Functions: Displays a list of supported amlogic devices
    # Configure: View ${model_database}
    # 1.ID  2.MODEL  3.SOC  4.FDTFILE  5.UBOOT_OVERLOAD  6.MAINLINE_UBOOT  7.BOOTLOADER_IMG  8.DESCRIPTION
    # 9.KERNEL_TAGS  10.PLATFORM  11.FAMILY  12.BOOT_CONF  13.CONTRIBUTORS  14.BOARD  15.BUILD
    show_aml_model() {
        echo -e "${STEPS} Start selecting device..."

        # Define split line style
        split_line="-----------------------------------------------------------------------------------------------------"
        # Print header information
        printf "%-s\n" "${split_line}"
        printf "%-5s %-10s %-45s %-50s\n" ID SOC MODEL DTB
        printf "%-s\n" "${split_line}"
        # Print device list
        echo "${model_database}" | awk -F':' '{print $1,$3,$2,$4}' | while read line; do
            # Print device information
            printf "%-5s %-10s %-45s %-50s\n" $(echo "${line}")
            # Add a split line every 10 lines
            [[ "$(echo ${line} | awk '{print $1}')" == *"0" ]] && printf "%-s\n" "${split_line}"
        done
        # Print custom options and end split lines
        printf "%-5s %-10s %-45s %-50s\n" 0 Other Customize Enter-custom-dtb-name
        printf "%-s\n" "${split_line}"

        # Display device options
        echo -ne "${OPTIONS} Please Input ID: "
        read boxid
        if [[ "${boxid}" -eq "0" ]]; then
            read -p "lease Input SoC Name(such as s9xxx): " AMLOGIC_SOC
            AMLOGIC_SOC="${AMLOGIC_SOC}"
            #
            read -p "lease Input DTB Name(such as meson-xxx.dtb): " FDTFILE
            FDTFILE="${FDTFILE}"
            #
            read -p "lease Input UBOOT_OVERLOAD Name(such as u-boot-xxx.bin): " UBOOT_OVERLOAD
            UBOOT_OVERLOAD="${UBOOT_OVERLOAD}"
            #
            read -p "lease Input MAINLINE_UBOOT Name(such as xxx-u-boot.bin.sd.bin): " MAINLINE_UBOOT
            MAINLINE_UBOOT="${MAINLINE_UBOOT}"
            #
            read -p "lease Input BOOTLOADER_IMG Name(such as xxx-bootloader.img): " BOOTLOADER_IMG
            BOOTLOADER_IMG="${BOOTLOADER_IMG}"
        else
            ret="$(search_aml_model "${boxid}")"
            [[ -z "${ret}" ]] && error_msg "Input error, exit!"

            MODEL_NAME="$(echo "${ret}" | awk -F ':' '{print $2}')"
            AMLOGIC_SOC="$(echo "${ret}" | awk -F ':' '{print $3}')"
            FDTFILE="$(echo "${ret}" | awk -F ':' '{print $4}')"
            UBOOT_OVERLOAD="$(echo "${ret}" | awk -F ':' '{print $5}')"
            MAINLINE_UBOOT="$(echo "${ret}" | awk -F ':' '{print $6}')"
            BOOTLOADER_IMG="$(echo "${ret}" | awk -F ':' '{print $7}')"
        fi

        echo -e "${INFO} Input Box ID: [ ${boxid} ]"
        echo -e "${INFO} Model Name: [ ${MODEL_NAME} ]"
        echo -e "${INFO} FDTFILE: [ ${FDTFILE} ]"
        echo -e "${INFO} MAINLINE_UBOOT: [ ${MAINLINE_UBOOT} ]"
        echo -e "${INFO} BOOTLOADER_IMG:  [ ${BOOTLOADER_IMG} ]"
        echo -e "${INFO} UBOOT_OVERLOAD: [ ${UBOOT_OVERLOAD} ]"
        echo -e "${INFO} NEED_OVERLOAD: [ ${NEED_OVERLOAD} ]"

        # Check dtb file
        [[ -n "${FDTFILE}" && -f "/boot/dtb/amlogic/${FDTFILE}" ]] || error_msg "The [ ${FDTFILE} ] is missing, aborting!"
        # Check UBOOT_OVERLOAD file
        [[ -n "${UBOOT_OVERLOAD}" && -f "/boot/${UBOOT_OVERLOAD}" ]] || error_msg "The [ ${UBOOT_OVERLOAD} ] is missing, aborting!"
    }

    # Show partition menu
    show_partition_menu() {
        cat <<EOF
      ┌────────────────────────────────────────────────────────────────────────┐
      │  Remaining disk space is greater than ${MG}.                           │
      ├───────────┬────────────────────────────────────────────────────────────┤
      │  Optional │ Description                                                │
      ├───────────┼────────────────────────────────────────────────────────────┤
      │     1     │ Rootfs partition limit to ${MG}.                           │
      │     2     │ [default] Rootfs partition expand to full disk (100%).     │
      │     3     │ Retain current Rootfs size (Preserve P3 Data).             │
      │    ≥16    │ Enter a number (GiB) to specify Rootfs partition size.     │
      └───────────┴────────────────────────────────────────────────────────────┘
    EOF
    }

    # Determine partition sizes
    partition_sizing() {
        # Use the ampart partition tool
        AMPART_STATUS="no"
        [[ -x "/usr/bin/ampart" && "${use_ampart}" == "yes" ]] && {
            ampart_tool
            [[ "${?}" -eq "0" ]] && AMPART_STATUS="yes" && echo -e "${STEPS} Successfully partitioned internal eMMC with amaprt."
        }

        # Set partition size (Unit: MiB)
        if [[ "${AMPART_STATUS}" == "yes" ]]; then
            BLANK1="117" # After using the ampart to part disk, space after [ 117 MiB ] could be used.
            BOOT="512"
            BLANK2="0"
        elif [[ "${AMLOGIC_SOC}" == "s912" && "${boxid}" -eq "213" ]]; then
            BLANK1="700" # OneCloudPro-V1.2
            BOOT="512"
            BLANK2="220"
        elif [[ "${AMLOGIC_SOC}" == "s912" && "${boxid}" -eq "214" ]]; then
            BLANK1="256" # new OneCloudPro-V1.2 based on base image android_tv_onethingcloud-money-maker-pro-3rd-s912.tar.xz
            BOOT="256"
            BLANK2="0"
        elif [[ "${AMLOGIC_SOC}" == "s912" || "${AMLOGIC_SOC}" == "s905d" ]]; then
            BLANK1="68"
            BOOT="512"
            BLANK2="220"
        elif [[ "${AMLOGIC_SOC}" == "s905x" ]]; then
            BLANK1="700"
            BOOT="512"
            BLANK2="0"
        elif [[ "${AMLOGIC_SOC}" == "s905l3a" && "${boxid}" -eq "304" ]]; then
            BLANK1="570" # e900v22c/d: The first [ 570 MiB ] is not writable.
            BOOT="512"
            BLANK2="0"
        elif [[ "${AMLOGIC_SOC}" == "s905l3a" && "${boxid}" -eq "305" ]]; then
            BLANK1="108" # CM311-1a-YST: Must skip [ 108 MiB ]
            BOOT="512"   # A total of [ 1024 MiB ] can be used in this block, gave up [ 1024-512=512 MiB ]
            BLANK2="778" # Rootfs partition could be set after [ 1398 MiB ] of the total disk, Multi-backward offset 100 MiB, [ 1398-108-512=778 MiB ]
        elif [[ "${AMLOGIC_SOC}" == "s905l3b" ]]; then
            BLANK1="128" # https://github.com/janko888/MBH-M30xA
            BOOT="513"   # M302A/M304A, Compatible with Android 4 and Android 9 firmware
            BLANK2="720"
        elif [[ "${FDTFILE}" == "meson-sm1-skyworth-lb2004-a4091.dtb" ]]; then
            BLANK1="108" # Tencent Aurora 3Pro: Must skip [ 108 MiB ]
            BOOT="512"   # A total of [ 768 MiB ] can be used in this block, gave up [ 768-512=256 MiB ]
            BLANK2="562" # Rootfs partition could be set after [ 1182 MiB ] of the total disk, [ 1182-108-512=562 MiB ]
        elif [[ "${boxid}" -eq "525" ]]; then
            BLANK1="108" # Whale(S905X3): Must skip [ 108 MiB ]
            BOOT="512"   # A total of [ 1024 MiB ] can be used in this block, gave up [ 1024-512=512 MiB ]
            BLANK2="650" # Rootfs partition could be set after [ 1270 MiB ] of the total disk, [ 1270-108-512=650 MiB ]
        elif [[ "${boxid}" -eq "409" || "${boxid}" -eq "410" ]]; then
            BLANK1="700" # WXY-OES(A311D), WXY-OES-Plus(s922x): Must skip [ 700 MiB ]
            BOOT="512"
            BLANK2="0"
        else
            BLANK1="68"
            BOOT="512"   # S905x3: A total of [ 1120 MiB ] can be used in this block, and the remaining [ 608 MiB ] can be used.
            BLANK2="770" # Rootfs partition could be set after [ 1350 MiB ] of the total disk.
        fi

        # Calculate partition size limits(Unit: MiB)
        ROOTFS_START_MiB="$((BLANK1 + BOOT + BLANK2))"
        MAX_SIZE_MiB="$((rootfs_limit_gib * 1024))"
        TARGET_END_MiB="$((ROOTFS_START_MiB + MAX_SIZE_MiB))"
        # Calculate target end position in bytes
        TARGET_END_BYTES="$((TARGET_END_MiB * 1024 * 1024))"

        # Get disk size in bytes
        DISK_SIZE_BYTES="$(lsblk -b -n -o SIZE -d "${DEV_EMMC}")"
        [[ "${DISK_SIZE_BYTES}" =~ ^[0-9]+$ ]] || DISK_SIZE_BYTES="0"
        [[ "${DISK_SIZE_BYTES}" -le "0" ]] && error_msg "Failed to get eMMC disk size."

        # Calculate the remaining disk space size
        FREE_SIZE_BYTES="$((DISK_SIZE_BYTES - (ROOTFS_START_MiB * 1024 * 1024)))"
        FREE_SIZE_GiB="$((FREE_SIZE_BYTES / 1024 / 1024 / 1024))"
        echo -e "${INFO} eMMC Disk Free Size: [ ${FREE_SIZE_GiB}GiB ]."

        # Detect current P3 size if it exists
        if lsblk "${DEV_EMMC}p3" >/dev/null 2>&1; then
            # Get P2 size in bytes
            P2_SIZE_BYTES="$(lsblk -b -n -o SIZE "${DEV_EMMC}p2" | head -n1)"
            # Convert to GiB for display
            P2_SIZE_GiB="$((P2_SIZE_BYTES / 1024 / 1024 / 1024))"
            # Try to get exact end position from parted
            P2_END_EXACT="$(parted -s "${DEV_EMMC}" unit B print 2>/dev/null | grep "^ 2" | awk '{print $3}' | tr -d 'B')"

            # Get P3 size in bytes
            P3_SIZE_BYTES="$(lsblk -b -n -o SIZE "${DEV_EMMC}p3" | head -n1)"
            # Convert to GiB for display
            P3_SIZE_GiB="$((P3_SIZE_BYTES / 1024 / 1024 / 1024))"
        fi

        # Default root end position
        ROOTFS_END="100%"

        # Select partition expansion strategy
        if [[ "${FREE_SIZE_BYTES}" -gt "${TARGET_END_BYTES}" ]]; then
            if [[ -n "${P2_END_EXACT}" && "${P3_SIZE_GiB}" -ge "1" ]]; then
                show_partition_menu
                echo -e "${INFO} Found System Partition (P2): ${P2_SIZE_GiB} GiB, Data Partition (P3): ${P3_SIZE_GiB} GiB."
                echo -e "         Input ${IDX} to inherit current partition layout and PRESERVE data on P3."
                echo -ne "${OPTIONS} Please Input ID(1/2/3) or Size(16 ~ ${FREE_SIZE_GiB}): "
            else
                show_partition_menu | grep -v '│     3     │'
                echo -ne "${OPTIONS} Please Input ID(1/2) or Size(16 ~ ${FREE_SIZE_GiB}): "
            fi
            read deskid

            # Validate user input
            deskid="$(echo "${deskid}" | tr -cd '0-9.' | cut -d. -f1)"
            [[ -z "${deskid}" || ! "${deskid}" =~ ^[0-9]+$ ]] && deskid="2"
            echo -e "${INFO} Input ID or Size: [ ${deskid} ]"

            # Determine partition expansion strategy
            if [[ "${deskid}" == "1" ]]; then
                ROOTFS_END="${TARGET_END_MiB}MiB"
                echo -e "${INFO} Strategy: Limit Rootfs to ${rootfs_limit_gib}GiB."
            elif [[ "${deskid}" == "2" ]]; then
                ROOTFS_END="100%"
                echo -e "${INFO} Strategy: Expand Rootfs to Full Disk."
            elif [[ "${deskid}" == "3" && -n "${P2_END_EXACT}" ]]; then
                ROOTFS_END="${P2_END_EXACT}B"
                echo -e "${INFO} Strategy: Keeping exact previous partition layout to preserve P3."
            elif [[ "${deskid}" -ge "${rootfs_limit_gib}" && "${deskid}" -le "${FREE_SIZE_GiB}" ]]; then
                CUSTOM_SIZE_MiB="$((deskid * 1024))"
                ROOTFS_END="$((ROOTFS_START_MiB + CUSTOM_SIZE_MiB))MiB"
                echo -e "${INFO} Strategy: Custom Rootfs size to ${deskid}GiB."
            else
                ROOTFS_END="100%"
                echo -e "${INFO} Strategy: Expand Rootfs to Full Disk."
            fi
        fi
    }

    # Nuclear re-partition function
    redo_partitions() {
        echo -e "${INFO} Re-initializing partition table (Nuclear Option)..."

        # Stop all active LVM/RAID groups
        vgchange -an >/dev/null 2>&1
        dmsetup remove_all >/dev/null 2>&1
        mdadm --stop --scan >/dev/null 2>&1

        # Unmount everything forcefully
        for i in $(seq 1 16); do
            umount -f "${DEV_EMMC}p${i}" >/dev/null 2>&1
            umount -l "${DEV_EMMC}p${i}" >/dev/null 2>&1
        done

        # Violently clear MBR (To break the kernel lock)
        dd if=/dev/zero of="${DEV_EMMC}" bs=512 count=1 conv=fsync 2>/dev/null
        sync
        partprobe "${DEV_EMMC}" 2>/dev/null
        sleep 3

        # Recreate all partitions
        parted -s "${DEV_EMMC}" mklabel msdos
        parted -s "${DEV_EMMC}" mkpart primary fat32 $((BLANK1))MiB $((BLANK1 + BOOT - 1))MiB
        parted -s "${DEV_EMMC}" mkpart primary btrfs ${ROOTFS_START_MiB}MiB ${ROOTFS_END}
    }

    # Create emmc partition
    create_partition() {
        cd /
        echo -e "${STEPS} Partitioning eMMC..."

        # Backup the bootloader, necessary for system recovery
        [[ -d "/usr/lib/u-boot" ]] || mkdir -p /usr/lib/u-boot
        MYBOX_UBOOT="/usr/lib/u-boot/mybox-bootloader.img"
        if [[ ! -f "${MYBOX_UBOOT}" ]]; then
            echo -e "${INFO} Start backing up the default bootloader."
            dd if="${DEV_EMMC}" of="${MYBOX_UBOOT}" bs=1M count=4 conv=fsync
            [[ "${?}" -eq "0" ]] || error_msg "Using dd to backup [ ${MYBOX_UBOOT} ] failed."
        else
            MAGIC_SIG="$(head -c 512 "${MYBOX_UBOOT}" 2>/dev/null | tail -c 2 | hexdump -e '1/1 "%02x"' 2>/dev/null || true)"
            if [[ "${MAGIC_SIG}" != "55aa" ]]; then
                echo -e "${INFO} Existing backup is invalid (No 55aa signature). Re-backing up..."
                dd if="${DEV_EMMC}" of="${MYBOX_UBOOT}" bs=1M count=4 conv=fsync
                [[ "${?}" -eq "0" ]] || error_msg "Using dd to backup [ ${MYBOX_UBOOT} ] failed."
            else
                echo -e "${INFO} Bootloader backup file [ ${MYBOX_UBOOT} ] already exists."
            fi
        fi

        echo -e "${INFO} Checking and stopping active LVM/RAID groups..."

        # Stop all active LVM/RAID groups
        vgchange -an >/dev/null 2>&1
        dmsetup remove_all >/dev/null 2>&1
        mdadm --stop --scan >/dev/null 2>&1

        # Unmount all mounted partitions on the eMMC
        for i in $(seq 1 16); do
            if lsblk "${DEV_EMMC}p${i}" >/dev/null 2>&1; then
                umount -f "${DEV_EMMC}p${i}" >/dev/null 2>&1
                umount -l "${DEV_EMMC}p${i}" >/dev/null 2>&1
            fi
        done

        # Try to wipe existing filesystem signatures
        if command -v wipefs >/dev/null 2>&1; then
            # Wipe first two partitions only (Do NOT wipe the main device/MBR)
            for i in 1 2; do
                [[ -b "${DEV_EMMC}p${i}" ]] && wipefs -a "${DEV_EMMC}p${i}" >/dev/null 2>&1
            done
        fi

        sync
        partprobe "${DEV_EMMC}" 2>/dev/null
        sleep 3

        # Clear emmc disk data (Modified to preserve Partition 3+)
        echo -e "${INFO} Deleting only BOOT and ROOTFS partitions (p1, p2)..."
        for i in 1 2; do
            if lsblk "${DEV_EMMC}p${i}" >/dev/null 2>&1; then
                parted -s ${DEV_EMMC} rm ${i}
                [[ "${?}" -eq "0" ]] || error_msg "Failed to delete partition [ ${i} ]."
                echo -e "${INFO} Partition ${i} deleted."
            fi
        done

        echo -e "${INFO} Start creating partitions..."
        if ! parted -s "${DEV_EMMC}" print >/dev/null 2>&1; then
            echo -e "${INFO} No partition table found. Creating msdos label."
            parted -s "${DEV_EMMC}" mklabel msdos
        else
            echo -e "${INFO} Partition table exists. Trying to preserve partition 3+..."
        fi

        # Create BOOTFS partition
        P1_RECREATED="no"
        echo -e "${INFO} Creating BOOTFS partition..."
        if ! parted -s "${DEV_EMMC}" mkpart primary fat32 $((BLANK1))MiB $((BLANK1 + BOOT - 1))MiB 2>/dev/null; then
            echo -e "${INFO} Failed to create BOOTFS partition. Invoking Nuclear Re-partition..."
            redo_partitions
            [[ "${?}" -eq "0" ]] || error_msg "Failed to create BOOTFS partition after MBR wipe."
            P1_RECREATED="yes"
        fi

        # Create Rootfs partition
        if [[ "${P1_RECREATED}" != "yes" ]]; then
            echo -e "${INFO} Creating Rootfs partition..."
            if ! parted -s "${DEV_EMMC}" mkpart primary btrfs ${ROOTFS_START_MiB}MiB ${ROOTFS_END} 2>/dev/null; then
                echo -e "${INFO} Overlap detected. Invoking Nuclear Re-partition to apply new size..."
                redo_partitions
                [[ "${?}" -eq "0" ]] || error_msg "Failed to create Rootfs partition after re-initialization."
            fi
        fi

        # Inform the kernel of partition table changes
        sync
        partprobe "${DEV_EMMC}" 2>/dev/null
        sleep 3

        # Write bootloader
        if [[ -n "${MAINLINE_UBOOT}" && -f "/usr/lib/u-boot/${MAINLINE_UBOOT}" && "${auto_mainline_uboot}" == "yes" ]]; then
            echo -e "${INFO} 01. Write Mainline bootloader: [ ${MAINLINE_UBOOT} ]"
            dd if="/usr/lib/u-boot/${MAINLINE_UBOOT}" of="${DEV_EMMC}" conv=fsync bs=1 count=444
            dd if="/usr/lib/u-boot/${MAINLINE_UBOOT}" of="${DEV_EMMC}" conv=fsync bs=512 skip=1 seek=1
        elif [[ -n "${BOOTLOADER_IMG}" && -f "/usr/lib/u-boot/${BOOTLOADER_IMG}" ]]; then
            echo -e "${INFO} 02. Write Android bootloader: [ ${BOOTLOADER_IMG} ]"
            dd if="/usr/lib/u-boot/${BOOTLOADER_IMG}" of="${DEV_EMMC}" conv=fsync bs=1 count=444
            dd if="/usr/lib/u-boot/${BOOTLOADER_IMG}" of="${DEV_EMMC}" conv=fsync bs=512 skip=1 seek=1
        elif [[ -n "${MYBOX_UBOOT}" && -f "${MYBOX_UBOOT}" ]]; then
            echo -e "${INFO} 03. Write the mybox bootloader: [ ${MYBOX_UBOOT} ]"
            dd if="${MYBOX_UBOOT}" of="${DEV_EMMC}" conv=fsync bs=1 count=444
            dd if="${MYBOX_UBOOT}" of="${DEV_EMMC}" conv=fsync bs=512 skip=1 seek=1
        fi
        [[ "${?}" -eq "0" ]] || error_msg "Failed to write bootloader using [ dd ]."

        # Generate a random disk signature and write it to the eMMC at offset 440
        dd if=/dev/urandom of="${DEV_EMMC}" bs=1 count=4 seek=440 conv=notrunc status=none
        sync && sleep 3
    }

    # Copy bootfs partition files
    copy_bootfs() {
        cd /
        echo -e "${STEPS} Processing BOOTFS partition..."

        PART_BOOT="${DEV_EMMC}p1"

        if grep -q ${PART_BOOT} /proc/mounts; then
            echo -e "${INFO} Unmounting BOOT partition."
            umount -f ${PART_BOOT}
            [[ "${?}" -eq "0" ]] || error_msg "Failed to umount [ ${PART_BOOT} ]."
        fi

        echo -e "${INFO} Formatting BOOTFS partition..."
        sleep 1
        mkfs.vfat -F 32 -i "${FAT_ID_RAW}" -n "BOOT_EMMC" ${PART_BOOT}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to format BOOTFS with [ mkfs.vfat ]."

        mount -o rw ${PART_BOOT} ${DIR_INSTALL}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to mount BOOTFS partition."

        echo -e "${INFO} Copying BOOTFS ..."
        cp -rf /boot/* ${DIR_INSTALL}
        # Remove useless files
        rm -rf ${DIR_INSTALL}/'System Volume Information'
        rm -f ${DIR_INSTALL}/s9*
        rm -f ${DIR_INSTALL}/aml*
        # Replace eMMC boot files
        [[ -f "${DIR_INSTALL}/boot-emmc.scr" ]] && mv -f ${DIR_INSTALL}/boot-emmc.scr ${DIR_INSTALL}/boot.scr
        [[ -f "${DIR_INSTALL}/boot-emmc.cmd" ]] && mv -f ${DIR_INSTALL}/boot-emmc.cmd ${DIR_INSTALL}/boot.cmd
        [[ -f "${DIR_INSTALL}/boot-emmc.ini" ]] && mv -f ${DIR_INSTALL}/boot-emmc.ini ${DIR_INSTALL}/boot.ini
        [[ -f "${DIR_INSTALL}/boot.ini" ]] && sed -i "s|u-boot.ext|u-boot.emmc|g" ${DIR_INSTALL}/boot.ini

        # Set new rootfs mount string
        uenv_mount_string="UUID=${ROOTFS_UUID} rootflags=compress=zstd:1 rootfstype=btrfs"

        # Update [ /boot/uEnv.txt ] settings
        uenv_conf_file="${DIR_INSTALL}/uEnv.txt"
        [[ -f "${uenv_conf_file}" ]] && {
            echo -e "${INFO} Update the [ uEnv.txt ] file."
            BOOT_CONF="uEnv.conf"
            sed -i "s|root=.*console=ttyAML0|root=${uenv_mount_string} console=ttyAML0|g" ${uenv_conf_file}
            sed -i "s|meson.*.dtb|${FDTFILE}|g" ${uenv_conf_file}
        }

        # Update [ /boot/extlinux/extlinux.conf ] settings
        boot_extlinux_file="${DIR_INSTALL}/extlinux/extlinux.conf"
        [[ -f "${boot_extlinux_file}" ]] && {
            echo -e "${INFO} Update the [ extlinux.conf ] file."
            BOOT_CONF="extlinux.conf"
            sed -i "s|root=.*console=ttyAML0|root=${uenv_mount_string} console=ttyAML0|g" ${boot_extlinux_file}
            sed -i "s|meson.*.dtb|${FDTFILE}|g" ${boot_extlinux_file}
        }

        # Copy u-boot.ext and u-boot.emmc
        if { [[ "${NEED_OVERLOAD}" == "yes" || "${auto_mainline_uboot}" == "yes" ]]; } &&
            { [[ -n "${UBOOT_OVERLOAD}" && -f "${DIR_INSTALL}/${UBOOT_OVERLOAD}" ]]; }; then
            echo -e "${INFO} Copy [ ${UBOOT_OVERLOAD} ] to u-boot.emmc"
            if [[ -f "${DIR_INSTALL}/u-boot.ext" ]]; then
                cp -f ${DIR_INSTALL}/u-boot.ext ${DIR_INSTALL}/u-boot.emmc
            else
                cp -f ${DIR_INSTALL}/${UBOOT_OVERLOAD} ${DIR_INSTALL}/u-boot.ext
                cp -f ${DIR_INSTALL}/${UBOOT_OVERLOAD} ${DIR_INSTALL}/u-boot.emmc
            fi
            chmod +x ${DIR_INSTALL}/u-boot.ext
            chmod +x ${DIR_INSTALL}/u-boot.emmc
        fi

        sync && sleep 3
        umount -f ${DIR_INSTALL}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to umount [ ${DIR_INSTALL} ]."
    }

    # Copy rootfs partition files
    copy_rootfs() {
        cd /
        echo -e "${STEPS} Start processing the rootfs partition..."

        PART_ROOT="${DEV_EMMC}p2"

        if grep -q ${PART_ROOT} /proc/mounts; then
            echo -e "${INFO} Unmounting ROOT partition."
            umount -f ${PART_ROOT}
            [[ "${?}" -eq "0" ]] || error_msg "Failed to umount [ ${PART_ROOT} ]."
        fi

        echo -e "${INFO} Formatting ROOTFS ..."
        mkfs.btrfs -f -U ${ROOTFS_UUID} -L "ROOTFS_EMMC" -m single ${PART_ROOT}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to format ROOTFS with [ mkfs.btrfs ]"

        mount -t btrfs -o compress=zstd:1 ${PART_ROOT} ${DIR_INSTALL}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to mount ROOTFS."

        echo -e "${INFO} Copying ROOTFS ..."
        # Create relevant directories
        mkdir -p ${DIR_INSTALL}/{boot/,dev/,media/,mnt/,proc/,run/,sys/,tmp/}
        chmod 1777 ${DIR_INSTALL}/tmp
        # Copy the relevant directory
        COPY_SRC="etc home opt root selinux srv usr var"
        for src in ${COPY_SRC}; do
            if [[ -d "${src}" ]]; then
                echo -e "${INFO} Copying [ ${src} ] ..."
                tar -cf - ${src} | (
                    cd ${DIR_INSTALL}
                    tar -xpf -
                )
            fi
        done
        # Create relevant symbolic link
        ln -sf usr/bin ${DIR_INSTALL}/bin
        ln -sf usr/lib ${DIR_INSTALL}/lib
        ln -sf usr/sbin ${DIR_INSTALL}/sbin

        echo -e "${INFO} Generate the new fstab file."
        rm -f ${DIR_INSTALL}/etc/fstab
        cat >${DIR_INSTALL}/etc/fstab <<EOF
    # <file system>   <mount point>   <type>   <options>   <dump>   <pass>
    UUID=${ROOTFS_UUID}       /       btrfs   defaults,noatime,compress=zstd:1        0       1
    UUID=${FAT_ID_FSTAB}      /boot   vfat    defaults,noatime,errors=remount-ro      0       2
    tmpfs                     /tmp    tmpfs   defaults,nosuid                         0       0

    EOF

        echo -e "${INFO} Update parameters related to the releases file."
        ophub_config_file="${DIR_INSTALL}${ophub_release_file}"
        sed -i "s|^MODEL_ID=.*|MODEL_ID='${boxid}'|g" ${ophub_config_file}
        sed -i "s|^MODEL_NAME=.*|MODEL_NAME='${MODEL_NAME}'|g" ${ophub_config_file}
        sed -i "s|^SOC=.*|SOC='${AMLOGIC_SOC}'|g" ${ophub_config_file}
        sed -i "s|^FDTFILE=.*|FDTFILE='${FDTFILE}'|g" ${ophub_config_file}
        sed -i "s|^MAINLINE_UBOOT=.*|MAINLINE_UBOOT='/usr/lib/u-boot/${MAINLINE_UBOOT}'|g" ${ophub_config_file}
        sed -i "s|^BOOTLOADER_IMG=.*|BOOTLOADER_IMG='/usr/lib/u-boot/${BOOTLOADER_IMG}'|g" ${ophub_config_file}
        sed -i "s|^UBOOT_OVERLOAD=.*|UBOOT_OVERLOAD='${UBOOT_OVERLOAD}'|g" ${ophub_config_file}
        sed -i "s|^ROOTFS_TYPE=.*|ROOTFS_TYPE='btrfs'|g" ${ophub_config_file}
        sed -i "s|^BOOT_CONF=.*|BOOT_CONF='${BOOT_CONF}'|g" ${ophub_config_file}
        sed -i "s|^DISK_TYPE=.*|DISK_TYPE='emmc'|g" ${ophub_config_file}
        sed -i "s|^MLUBOOT_STATUS=.*|MLUBOOT_STATUS='${auto_mainline_uboot}'|g" ${ophub_config_file}
        sed -i "s|^AMPART_STATUS=.*|AMPART_STATUS='${AMPART_STATUS}'|g" ${ophub_config_file}

        # Update fnnas.conf to disable rootfs resize on first boot
        echo -e "${INFO} Update parameters related to the fnnas configuration file."
        fnnas_conf_file="${DIR_INSTALL}${fnnas_conf}"
        sed -i "s|^rootfs_resize=.*|rootfs_resize=\"no\"|g" "${fnnas_conf_file}"

        sync && sleep 3
        umount -f ${DIR_INSTALL}
        [[ "${?}" -eq "0" ]] || error_msg "Failed to umount [ ${DIR_INSTALL} ]."
    }

    # Check script permission
    [[ "$(id -u)" == "0" ]] || error_msg "lease run this script as root: [ sudo $0 ]"
    echo -e "${STEPS} Installing fnnas to internal eMMC..."

    # Check dependencies
    check_depends
    # Initialize all variables
    init_var "${@}"
    # Display the model list
    show_aml_model
    # Determine partition sizes
    partition_sizing
    # Create emmc partition
    create_partition
    # Copy bootfs partition files
    copy_bootfs
    # Copy rootfs partition files
    copy_rootfs

    echo -e "${SUCCESS} Installation successful. Run [ poweroff ], remove the installation media then re-insert the power supply to boot new system."
    exit 0
  • 只谈技术、莫论政事!(点击见详情) | 互相尊重、友善交流、切勿过度反应、玻璃心。胡乱输入灌水等操作将会被封禁ID。
    回复

    使用道具 举报

     楼主| 发表于 2026-2-8 18:01 | 显示全部楼层
    原先的位置在     parted -s "${DEV_EMMC}" mkpart primary btrfs $((BLANK1 + BOOT + BLANK2))MiB 100%    现在找不到这个语句了
    只谈技术、莫论政事!(点击见详情) | 互相尊重、友善交流、切勿过度反应、玻璃心。胡乱输入灌水等操作将会被封禁ID。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    欢迎大家光临恩山无线论坛上一条 /2 下一条

    有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

    GMT+8, 2026-8-23 21:15

    Powered by Discuz! X3.5

    © 2001-2026 Discuz! Team.

    | 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 电话:13506125623

    快速回复 返回顶部 返回列表