RK 平臺安裝 ubuntu 系統

浇筑菜鸟發表於2024-04-29

一、簡介

之前有介紹到 ARM 平臺移植 ubuntu 的操作流程,在 RK 系列的平臺同樣適用,所以這裡就不介紹怎麼一步步的去對 ubuntu 進行移植,而是怎麼將移植的過程編寫成指令碼,這樣便可以在 SDK 中透過一行命令即可生成 rootfs.img 映象,管理起來也也比較方便,需要裁剪摸個工具時也很便捷。

可能沒有進行過系統移植的小夥伴看著比較困難,建議先從前面的筆記看著來,在看這篇筆記就會發現很簡單,也可以理解 RK 平臺的 SDK 是怎麼回事。

二、準備材料

我使用的晶片是RK3588,小夥伴可以根據自己的情況選擇開發版。
開發環境:VMware
作業系統:ubuntu
開發版:RK3588

三、Debian 目錄

因為 RK 平臺的 SDK 中是已經支援 Debian 的,所以我們可以根據 Debian 系統的編譯方式來模仿 ubuntu 指令碼的編寫,這樣大大降低了操作的難度,還可以明白系統移植是的流程。

目錄 作用
overlay 適配Rockchip平臺共性配置⽂件
overlay-debug 系統常使⽤的除錯⼯具
overlay-firmware ⼀些裝置firmware的存放,⽐如npu/dp等
packages 包含armhf arm64系統適配硬加速使⽤的預編譯的包
packages-patches 預編包,基於官⽅打上的補丁
ubuntu-build-service 從官⽅獲取Debian發⾏版,可依賴包和定製安裝相關包
mk-base-debian.sh 獲取Debian基礎包和編譯
mk-image.sh 打包⽣成ext4的韌體
mk-rootfs-buster/bullseye.sh 適配Rockchip相關硬體加速包
mk-rootfs.sh 指向具體Rootfs版本,⽬前有Buster、Bullseye兩個版本
readme.md ⽂檔指引

注意: 以上這些檔案都是與外設相關的,也就是解決安裝第三方系統後與硬體環境不相容問題的關鍵,這裡應該會有小夥伴和一樣好奇,這裡面的檔案是怎麼來的,我也沒仔細去研究過,但是一定是從官方提供的 external 中程式設計出來的。

  • 配置檔案、 .so、.a 檔案:可以與 buildroot 進行對比,沒猜錯的話,一定能在 buildroot 編譯輸出的目錄中能找到。
  • deb 工具包:這裡就不用過多的介紹了,看我之前的筆記便可明白
  • ubuntu-build-service/packages 目錄下的 deb:這裡需要注意一下,這裡面的包是編譯時宿主機必須具備的環境,並不是廠商提供的,而是從網上下載的,路徑如下
    live-build_*.deb來源https://mirrors.ustc.edu.cn/debian/pool/main/l/live-build/
    debootstrap_*.deb來源https://mirrors.ustc.edu.cn/debian/pool/main/d/debootstrap/
    
    當然也是可以透過 apt 命令進行安裝。

瞭解這些基本資訊後,變可以仿照編寫一個 ubuntu 編譯的指令碼。這個工程量還是有點大的,難度雖然不大,但是也是一個比較費時的事,不過好在我在網上找了一下,找到了野火已經編寫好了,這裡我們就不用重複造輪子了,在這裡感謝野火的無私奉獻。

四、編譯 ubuntu

  1. 下載地址

    https://github.com/LubanCat/ubuntu/tree/ubuntu22.04
    
  2. 編譯

    ./mk-base-ubuntu.sh
    ./mk-ubuntu-rootfs.sh
    

五、ubuntu 製作過程

  1. 下載 ubuntu 系統

        if [ ! -d $TARGET_ROOTFS_DIR ] ; then
        sudo mkdir -p $TARGET_ROOTFS_DIR
    
        if [ ! -e ubuntu-base-20.04.5-base-$ARCH.tar.gz ]; then
            echo -e "\033[47;36m wget ubuntu-base-20.04-base-x.tar.gz \033[0m"
            wget -c http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.5-base-$ARCH.tar.gz
        fi
        sudo tar -xzf ubuntu-base-20.04.5-base-$ARCH.tar.gz -C $TARGET_ROOTFS_DIR/
        sudo cp sources.list $TARGET_ROOTFS_DIR/etc/apt/sources.list
        sudo cp -b /etc/resolv.conf $TARGET_ROOTFS_DIR/etc/resolv.conf
    
        if [ "$ARCH" == "armhf" ]; then
    	    sudo cp -b /usr/bin/qemu-arm-static $TARGET_ROOTFS_DIR/usr/bin/
        elif [ "$ARCH" == "arm64"  ]; then
    	    sudo cp -b /usr/bin/qemu-aarch64-static $TARGET_ROOTFS_DIR/usr/bin/
        fi
    fi
    

    不難看出來,這個環節下載 ubuntu 系統,不論選擇的版本型別是什麼,下載的都是 base 版。

  2. 構建獨立環境

    function mnt() {
        echo "MOUNTING"
        sudo mount -t proc /proc ${2}/proc
        sudo mount -t sysfs /sys ${2}/sys
        sudo mount -o bind /dev ${2}/dev
    }
    

    透過掛載 proc、sysfs 和 /dev 是為了構建一個隔離的執行環境,讓 chroot 內的程式以為自己執行在一個獨立的系統環境中,而不是主機的實際系統環境。

    • 掛載 /proc 檔案系統: /proc 是一個虛擬檔案系統,提供了關於系統核心和程序的資訊。
    • 掛載 /sys 檔案系統: /sys 檔案系統包含了關於系統硬體、裝置和驅動程式的資訊。
    • 繫結掛載 /dev 目錄: /dev 目錄包含了裝置檔案,用於訪問系統的各種硬體裝置。
  3. 進入 chroot 環境

    cat <<EOF | sudo chroot $TARGET_ROOTFS_DIR/
    
    export APT_INSTALL="apt-get install -fy --allow-downgrades"
    
    export LC_ALL=C.UTF-8
    
    apt-get -y update
    apt-get -f -y upgrade
    ......
    ......
    ......
    EOF
    

    前面已經準備好了獨立的 chroot 環境,現在需要的做便是進入 chroot 環境後,安裝自己需要的元件即可

  4. 安裝自己所需的工具

    if [ "$TARGET" == "gnome" ]; then
        DEBIAN_FRONTEND=noninteractive apt install -y ubuntu-desktop-minimal rsyslog sudo dialog apt-utils ntp evtest onboard
        mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/
        mkdir /var/lib/dpkg/info/
        apt-get update
        DEBIAN_FRONTEND=noninteractive apt install -y ubuntu-desktop-minimal rsyslog sudo dialog apt-utils ntp evtest onboard
        mv /var/lib/dpkg/info_old/* /var/lib/dpkg/info/
    elif [ "$TARGET" == "xfce" ]; then
        DEBIAN_FRONTEND=noninteractive apt install -y xubuntu-core onboard rsyslog sudo dialog apt-utils ntp evtest udev
        mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/
        mkdir /var/lib/dpkg/info/
        apt-get update
        DEBIAN_FRONTEND=noninteractive apt install -y xubuntu-core onboard rsyslog sudo dialog apt-utils ntp evtest udev
        mv /var/lib/dpkg/info_old/* /var/lib/dpkg/info/
    elif [ "$TARGET" == "lite" ]; then
        DEBIAN_FRONTEND=noninteractive apt install -y rsyslog sudo dialog apt-utils ntp evtest acpid
    elif [ "$TARGET" == "gnome-full" ]; then
        DEBIAN_FRONTEND=noninteractive apt install -y ubuntu-desktop-minimal rsyslog sudo dialog apt-utils ntp evtest onboard
        mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/
        mkdir /var/lib/dpkg/info/
        apt-get update
        DEBIAN_FRONTEND=noninteractive apt install -y ubuntu-desktop-minimal rsyslog sudo dialog apt-utils ntp evtest onboard
        mv /var/lib/dpkg/info_old/* /var/lib/dpkg/info/
    elif [ "$TARGET" == "xfce-full" ]; then
        DEBIAN_FRONTEND=noninteractive apt install -y xubuntu-desktop onboard rsyslog sudo dialog apt-utils ntp evtest udev
        mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/
        mkdir /var/lib/dpkg/info/
        apt-get update
        DEBIAN_FRONTEND=noninteractive apt install -y xubuntu-desktop onboard rsyslog sudo dialog apt-utils ntp evtest udev
        mv /var/lib/dpkg/info_old/* /var/lib/dpkg/info/
    fi
    
    \${APT_INSTALL} net-tools openssh-server ifupdown alsa-utils ntp network-manager gdb inetutils-ping libssl-dev \
        vsftpd tcpdump can-utils i2c-tools strace vim iperf3 ethtool netplan.io toilet htop pciutils usbutils curl \
        whiptail gnupg bc xinput gdisk parted gcc sox libsox-fmt-all gpiod libgpiod-dev python3-pip python3-libgpiod \
        guvcview
    
    \${APT_INSTALL} ttf-wqy-zenhei xfonts-intl-chinese
    
    if [[ "$TARGET" == "gnome-full" ||  "$TARGET" == "xfce-full" ]]; then
        apt purge ibus firefox -y
    
        echo -e "\033[47;36m Install Chinese fonts.................... \033[0m"
        \${APT_INSTALL} language-pack-zh-hans fonts-noto-cjk-extra gnome-user-docs-zh-hans language-pack-gnome-zh-hans
    
        # set default xinput for fcitx
        \${APT_INSTALL} fcitx fcitx-table fcitx-googlepinyin fcitx-pinyin fcitx-config-gtk
        sed -i 's/default/fcitx/g' /etc/X11/xinit/xinputrc
    
        \${APT_INSTALL} ipython3 jupyter
    fi
    
    if [[ "$TARGET" == "gnome-full" ||  "$TARGET" == "xfce-full" ]]; then
        # Uncomment zh_CN.UTF-8 for inclusion in generation
        sed -i 's/^# *\(zh_CN.UTF-8\)/\1/' /etc/locale.gen
        echo "LANG=zh_CN.UTF-8" >> /etc/default/locale
    
        # Generate locale
        locale-gen zh_CN.UTF-8
    
        # Export env vars
        echo "LC_ALL=zh_CN.UTF-8" >> /etc/environment    
        echo "LANG=zh_CN.UTF-8" >> /etc/environment
        echo "LANGUAGE=zh_CN:zh:en_US:en" >> /etc/environment
    
        echo "export LC_ALL=zh_CN.UTF-8" >> /etc/profile.d/zh_CN.sh
        echo "export LANG=zh_CN.UTF-8" >> /etc/profile.d/zh_CN.sh
        echo "export LANGUAGE=zh_CN:zh:en_US:en" >> /etc/profile.d/zh_CN.sh
    
        \${APT_INSTALL} $(check-language-support)
    fi
    
    if [[ "$TARGET" == "gnome" || "$TARGET" == "gnome-full" ]]; then
        \${APT_INSTALL} mpv acpid gnome-sound-recorder
    elif [[ "$TARGET" == "xfce" || "$TARGET" == "xfce-full" ]]; then
        \${APT_INSTALL} mpv acpid gnome-sound-recorder
    elif [ "$TARGET" == "lite" ]; then
        \${APT_INSTALL}  
    fi
    
    pip3 install python-periphery Adafruit-Blinka -i https://mirrors.aliyun.com/pypi/simple/
    

    不難看出來,這裡的操作都是為了,安裝自己所需要的工具,所以需要新增或者裁減時,直接在這裡新增即可。

  5. 建立使用者

    HOST=lubancat
    
    # Create User
    useradd -G sudo -m -s /bin/bash cat
    passwd cat <<IEOF
    temppwd
    temppwd
    IEOF
    gpasswd -a cat video
    gpasswd -a cat audio
    passwd root <<IEOF
    root
    root
    IEOF
    
  6. 允許 root 登入

    sed -i '/pam_securetty.so/s/^/# /g' /etc/pam.d/login
    
  7. 設定主機名

    echo lubancat > /etc/hostname
    
  8. 設定本地時間

    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    
  9. 禁用指定服務的等待線上服務單元,以防止啟動過程中等待網路服務線上的延遲

    services=(NetworkManager systemd-networkd)
    for service in ${services[@]}; do
      systemctl mask ${service}-wait-online.service
    done
    
  10. 透過禁用這些單元,系統將不會自動啟動相關的 wpa_supplicant 服務

    systemctl mask wpa_supplicant-wired@
    systemctl mask wpa_supplicant-nl80211@
    systemctl mask wpa_supplicant@
    
  11. 調整 systemd 日誌級別

    # 將 /etc/systemd/system.conf 檔案中的日誌級別從 info 改為 warning,減少系統日誌的輸出。
    sed -i 's/#LogLevel=info/LogLevel=warning/' \
      /etc/systemd/system.conf
    
    # 將日誌目標從 journal-or-kmsg 改為 journal,將日誌傳送到 journal。
    sed -i 's/#LogTarget=journal-or-kmsg/LogTarget=journal/' \
      /etc/systemd/system.conf
    
  12. 檢查以確保 sudoers 檔案具有 sudo 組的 ref

    SUDOEXISTS="$(awk '$1 == "%sudo" { print $1 }' /etc/sudoers)"
    if [ -z "$SUDOEXISTS" ]; then
      # append sudo entry to sudoers
      echo "# Members of the sudo group may gain root privileges" >> /etc/sudoers
      echo "%sudo	ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
    fi
    
  13. 確保為 %sudo 設定了 NOPASSWD

    sed -i -e '
    /\%sudo/ c \
    %sudo    ALL=(ALL) NOPASSWD: ALL
    ' /etc/sudoers
    
  14. 清理安裝包後退出 chroot 環境

    apt-get clean
    rm -rf /var/lib/apt/lists/*
    
    sync
    
  15. 解除安裝 proc、sysfs 和 /dev

    ./ch-mount.sh -u $TARGET_ROOTFS_DIR
    
  16. 打包系統進行儲存

    DATE=$(date +%Y%m%d)
    echo -e "\033[47;36m Run tar pack ubuntu-base-$TARGET-$ARCH-$DATE.tar.gz \033[0m"
    sudo tar zcf ubuntu-base-$TARGET-$ARCH-$DATE.tar.gz $TARGET_ROOTFS_DIR
    

注意: 看我之前的筆記,你將會發現上面指令碼執行的流程和手動操作的環節是一樣的。所以這裡已經可以將系統打包成映象後下載測試,建議各位小夥伴都測試一下,加深對系統移植的理解。
測試完成後,便會發現有很多問題,比如硬體環境基本不能使用,介面起不來等各種問題。不要慌,接下來便開始處理這些不相容的問題,操作方式也很簡單,第一篇筆記已經介紹到了,這裡就不在贅述了,看操作。

六、平臺適配

  1. 環境準備

    # 透過選擇設定 SOC 和 TARGET 變數的值
    if [ ! $SOC ]; then
        echo "---------------------------------------------------------"
        echo "please enter soc number:"
        echo "請輸入要構建CPU的序號:"
        echo "[0] Exit Menu"
        echo "[1] rk3566/rk3568"
        echo "[2] rk3588/rk3588s"
        echo "---------------------------------------------------------"
        read input
    
        case $input in
            0)
                exit;;
            1)
                SOC=rk356x
                ;;
            2)
                SOC=rk3588
                ;;
            *)
                echo 'input soc number error, exit !'
                exit;;
        esac
        echo -e "\033[47;36m set SOC=$SOC...... \033[0m"
    fi
    
    if [ ! $TARGET ]; then
        echo "---------------------------------------------------------"
        echo "please enter TARGET version number:"
        echo "請輸入要構建的根檔案系統版本:"
        echo "[0] Exit Menu"
        echo "[1] gnome"
        echo "[2] xfce"
        echo "[3] lite"
        echo "[4] gnome-full"
        echo "[5] xfce-full"
        echo "---------------------------------------------------------"
        read input
    
        case $input in
            0)
                exit;;
            1)
                TARGET=gnome
                ;;
            2)
                TARGET=xfce
                ;;
            3)
                TARGET=lite
                ;;
            4)
                TARGET=gnome-full
                ;;
            5)
                TARGET=xfce-full
                ;;
            *)
                echo -e "\033[47;36m input TARGET version number error, exit ! \033[0m"
                exit;;
        esac
        echo -e "\033[47;36m set TARGET=$TARGET...... \033[0m"
    fi
    
    # 設定 MALI 和 ISP 以及 MIRROR 變數的值
    install_packages() {
        case $SOC in
            rk3399|rk3399pro)
            MALI=midgard-t86x-r18p0
            ISP=rkisp
            ;;
            rk3328|rk3528)
            MALI=utgard-450
            ISP=rkisp
            ;;
            rk356x|rk3566|rk3568)
            MALI=bifrost-g52-g13p0
            ISP=rkaiq_rk3568
            MIRROR=carp-rk356x
            ;;
            rk3588|rk3588s)
            ISP=rkaiq_rk3588
            MALI=valhall-g610-g13p0
            MIRROR=carp-rk3588
            ;;
        esac
    }
    
    # 設定 ARCH 變數的值,預設為 arm64
    case "${ARCH:-$1}" in
        arm|arm32|armhf)
            ARCH=armhf
            ;;
        *)
            ARCH=arm64
            ;;
    esac
    
    echo -e "\033[47;36m Building for $ARCH \033[0m"
    
    # 設定 VERSION 變數
    if [ ! $VERSION ]; then
        VERSION="release"
    fi
    
    echo -e "\033[47;36m Building for $VERSION \033[0m"
    
    # 判斷檔案是否存在
    if [ ! -e ubuntu-base-"$TARGET"-$ARCH-*.tar.gz ]; then
        echo "\033[41;36m Run mk-base-ubuntu.sh first \033[0m"
        exit -1
    fi
    
    # 錯誤時執行此函式
    finish() {
        sudo umount $TARGET_ROOTFS_DIR/dev
        exit -1
    }
    trap finish ERR
    
    # 將檔案 ubuntu-base-$TARGET-$ARCH-*.tar.gz,之前的操作壓縮時,檔案便是 TARGET_ROOTFS_DIR,所以不用指定目錄
    echo -e "\033[47;36m Extract image \033[0m"
    sudo rm -rf $TARGET_ROOTFS_DIR
    sudo tar -xpf ubuntu-base-$TARGET-$ARCH-*.tar.gz
    

    這裡的操作沒啥好說的,主要將之前打包的系統再次解壓出來,並配置一些變數

  2. 複製相關的 deb 包

    # 將檔案 ubuntu-base-$TARGET-$ARCH-*.tar.gz,之前的操作壓縮時,檔案便是 TARGET_ROOTFS_DIR,所以不用指定目錄
    echo -e "\033[47;36m Extract image \033[0m"
    sudo rm -rf $TARGET_ROOTFS_DIR
    sudo tar -xpf ubuntu-base-$TARGET-$ARCH-*.tar.gz
    
    # 將 所有的 deb 檔案複製到指定目錄
    # packages folder
    sudo mkdir -p $TARGET_ROOTFS_DIR/packages
    sudo cp -rpf packages/$ARCH/* $TARGET_ROOTFS_DIR/packages
    
    # 根據 SOC 複製 GPU/CAMERA 對應的 deb 包
    #GPU/CAMERA packages folder
    install_packages
    sudo mkdir -p $TARGET_ROOTFS_DIR/packages/install_packages
    sudo cp -rpf packages/$ARCH/libmali/libmali-*$MALI*-x11*.deb $TARGET_ROOTFS_DIR/packages/install_packages
    sudo cp -rpf packages/$ARCH/${ISP:0:5}/camera_engine_$ISP*.deb $TARGET_ROOTFS_DIR/packages/install_packages
    
    #linux kernel deb
    if [ -e ../linux-headers* ]; then
        Image_Deb=$(basename ../linux-headers*)
        sudo mkdir -p $TARGET_ROOTFS_DIR/boot/kerneldeb
        sudo touch $TARGET_ROOTFS_DIR/boot/build-host
        sudo cp -vrpf ../${Image_Deb} $TARGET_ROOTFS_DIR/boot/kerneldeb
        sudo cp -vrpf ../${Image_Deb/headers/image} $TARGET_ROOTFS_DIR/boot/kerneldeb
    fi
    
    # overlay folder
    sudo cp -rpf overlay/* $TARGET_ROOTFS_DIR/
    
    # overlay-firmware folder
    sudo cp -rpf overlay-firmware/* $TARGET_ROOTFS_DIR/
    
    # overlay-debug folder
    # adb, video, camera  test file
    if [ "$VERSION" == "debug" ]; then
        sudo cp -rpf overlay-debug/* $TARGET_ROOTFS_DIR/
    fi
    ## hack the serial
    sudo cp -f overlay/usr/lib/systemd/system/serial-getty@.service $TARGET_ROOTFS_DIR/lib/systemd/system/serial-getty@.service
    
    # adb
    if [[ "$ARCH" == "armhf" && "$VERSION" == "debug" ]]; then
        sudo cp -f overlay-debug/usr/local/share/adb/adbd-32 $TARGET_ROOTFS_DIR/usr/bin/adbd
    elif [[ "$ARCH" == "arm64" && "$VERSION" == "debug" ]]; then
        sudo cp -f overlay-debug/usr/local/share/adb/adbd-64 $TARGET_ROOTFS_DIR/usr/bin/adbd
    fi
    
    echo -e "\033[47;36m Change root.....................\033[0m"
    if [ "$ARCH" == "armhf" ]; then
        sudo cp /usr/bin/qemu-arm-static $TARGET_ROOTFS_DIR/usr/bin/
    elif [ "$ARCH" == "arm64"  ]; then
        sudo cp /usr/bin/qemu-aarch64-static $TARGET_ROOTFS_DIR/usr/bin/
    fi
    
  3. 進入 chroot 環境

    sudo mount -o bind /dev $TARGET_ROOTFS_DIR/dev
    
    # 使用 stat 命令獲取指定檔案或目錄的使用者 ID,並將其儲存在變數 ID 中, 預設情況下是 0
    ID=$(stat --format %u $TARGET_ROOTFS_DIR)
    
    cat << EOF | sudo chroot $TARGET_ROOTFS_DIR
    
    # 修復程式所有者
    # Fixup owners
    if [ "$ID" -ne 0 ]; then
        find / -user $ID -exec chown -h 0:0 {} \;
    fi
    for u in \$(ls /home/); do
        chown -h -R \$u:\$u /home/\$u
    done
    
    # 根據 $MIRROR 變數的值配置 Embedfire 的軟體源
    if [ $MIRROR ]; then
    	mkdir -p /etc/apt/keyrings
    	curl -fsSL https://Embedfire.github.io/keyfile | gpg --dearmor -o /etc/apt/keyrings/embedfire.gpg
    	chmod a+r /etc/apt/keyrings/embedfire.gpg
    	echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/embedfire.gpg] https://cloud.embedfire.com/mirrors/ebf-debian carp-lbc main" | tee /etc/apt/sources.list.d/embedfire-lbc.list > /dev/null
    	echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/embedfire.gpg] https://cloud.embedfire.com/mirrors/ebf-debian $MIRROR main" | tee /etc/apt/sources.list.d/embedfire-$MIRROR.list > /dev/null
    fi
    
    export LC_ALL=C.UTF-8
    
    apt-get update
    apt-get upgrade -y
    
    chmod o+x /usr/lib/dbus-1.0/dbus-daemon-launch-helper
    chmod +x /etc/rc.local
    
    export APT_INSTALL="apt-get install -fy --allow-downgrades"
    
    
  4. 配置桌面

    echo -e "\033[47;36m ---------- LubanCat -------- \033[0m"
    \${APT_INSTALL} fire-config u-boot-tools logrotate
    if [[ "$TARGET" == "gnome" || "$TARGET" == "gnome-full" ]]; then
        \${APT_INSTALL} gdisk fire-config-gui
        #Desktop background picture
        ln -sf /usr/share/xfce4/backdrops/lubancat-wallpaper.png /usr/share/backgrounds/warty-final-ubuntu.png
    elif [[ "$TARGET" == "xfce" || "$TARGET" == "xfce-full" ]]; then
        \apt-get remove -y gnome-bluetooth
        \${APT_INSTALL} bluez bluez-tools fire-config-gui
        #Desktop background picture
        ln -sf /usr/share/xfce4/backdrops/lubancat-wallpaper.png /usr/share/xfce4/backdrops/xubuntu-wallpaper.png
    elif [ "$TARGET" == "lite" ]; then
        \${APT_INSTALL} bluez bluez-tools
    fi
    
  5. 安裝平臺工具包

    apt install -fy --allow-downgrades /packages/install_packages/*.deb
    
    apt install -fy --allow-downgrades /boot/kerneldeb/* || true
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ----- power management ----- \033[0m"
        \${APT_INSTALL} pm-utils triggerhappy bsdmainutils
        cp /etc/Powermanager/triggerhappy.service  /lib/systemd/system/triggerhappy.service
    fi
    
    echo -e "\033[47;36m ----------- RGA  ----------- \033[0m"
    \${APT_INSTALL} /packages/rga2/*.deb
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------ Setup Video---------- \033[0m"
        \${APT_INSTALL} gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-tools gstreamer1.0-alsa gstreamer1.0-plugins-base-apps qtmultimedia5-examples
        \${APT_INSTALL} /packages/mpp/*
        \${APT_INSTALL} /packages/gst-rkmpp/*.deb
        \${APT_INSTALL} /packages/gstreamer/*.deb
        # \${APT_INSTALL} /packages/gst-plugins-base1.0/*.deb
        # \${APT_INSTALL} /packages/gst-plugins-bad1.0/*.deb
        # \${APT_INSTALL} /packages/gst-plugins-good1.0/*.deb	
    fi
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ----- Install Camera ----- - \033[0m"
        \${APT_INSTALL} cheese v4l-utils
        \${APT_INSTALL} /packages/libv4l/*.deb
    elif [ "$TARGET" == "lite" ]; then
        echo -e "\033[47;36m ----- Install Camera ----- - \033[0m"
        \${APT_INSTALL} v4l-utils
        \${APT_INSTALL} /packages/mpp/*
    fi
    
    if [[ "$TARGET" == "gnome" || "$TARGET" == "gnome-full" ]]; then
        echo -e "\033[47;36m ----- Install Xserver------- \033[0m"
        \${APT_INSTALL} /packages/xserver/xserver-xorg-*.deb
        apt-mark hold xserver-xorg-core xserver-xorg-legacy
    elif [[ "$TARGET" == "xfce" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ----- Install Xserver------- \033[0m"
        \${APT_INSTALL} /packages/xserver/*.deb
        apt-mark hold xserver-common xserver-xorg-core xserver-xorg-legacy
    fi
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------ update chromium ----- \033[0m"
        \${APT_INSTALL} /packages/chromium/*.deb
        # echo -e "\033[47;36m --------- firefox-esr ------ \033[0m"
        # \${APT_INSTALL} /packages/firefox/*.deb
    fi
    
    echo -e "\033[47;36m ------- Install libdrm ------ \033[0m"
    \${APT_INSTALL} /packages/libdrm/*.deb
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------ libdrm-cursor -------- \033[0m"
        \${APT_INSTALL} /packages/libdrm-cursor/*.deb
        # Only preload libdrm-cursor for X
        sed -i "/libdrm-cursor.so/d" /etc/ld.so.preload
        sed -i "1aexport LD_PRELOAD=libdrm-cursor.so.1" /usr/bin/X
    fi
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        if [ "$VERSION" == "debug" ]; then
            echo -e "\033[47;36m ------ Install glmark2 ------ \033[0m"
            \${APT_INSTALL} glmark2-es2
        fi
    fi
    
    if [ -e "/usr/lib/aarch64-linux-gnu" ] ; then
    echo -e "\033[47;36m ------- move rknpu2 --------- \033[0m"
    mv /packages/rknpu2/*.tar  /
    fi
    
    echo -e "\033[47;36m ----- Install rktoolkit ----- \033[0m"
    \${APT_INSTALL} /packages/rktoolkit/*.deb
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------ Install ffmpeg ------- \033[0m"
        \${APT_INSTALL} ffmpeg
        \${APT_INSTALL} /packages/ffmpeg/*.deb
    fi
    
    if [[ "$TARGET" == "gnome" ||  "$TARGET" == "xfce" || "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------- Install mpv --------- \033[0m"
        \apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y /packages/mpv/*.deb
    fi
    
    if [[ "$TARGET" == "gnome-full" || "$TARGET" == "xfce-full" ]]; then
        echo -e "\033[47;36m ------ Install scratch ------- \033[0m"
        \${APT_INSTALL} /packages/embedfire/scratch_*.deb
    fi
    

    是不是發現這個環節也是挺簡單的,需要對平臺資源的移植的裁剪時,直接更改這裡的操作即可。

  6. 自定義指令碼

    echo -e "\033[47;36m ------- Custom Script ------- \033[0m"
    systemctl mask systemd-networkd-wait-online.service
    systemctl mask NetworkManager-wait-online.service
    systemctl disable hostapd
    rm /lib/systemd/system/wpa_supplicant@.service
    
  7. 清除後退出 chroot 環境

    echo -e "\033[47;36m  ---------- Clean ----------- \033[0m"
    if [ -e "/usr/lib/arm-linux-gnueabihf/dri" ] ;
    then
            cd /usr/lib/arm-linux-gnueabihf/dri/
            cp kms_swrast_dri.so swrast_dri.so /
            rm /usr/lib/arm-linux-gnueabihf/dri/*.so
            mv /*.so /usr/lib/arm-linux-gnueabihf/dri/
    elif [ -e "/usr/lib/aarch64-linux-gnu/dri" ];
    then
            cd /usr/lib/aarch64-linux-gnu/dri/
            cp kms_swrast_dri.so swrast_dri.so /
            rm /usr/lib/aarch64-linux-gnu/dri/*.so
            mv /*.so /usr/lib/aarch64-linux-gnu/dri/
            rm /etc/profile.d/qt.sh
    fi
    rm -rf /home/$(whoami)
    rm -rf /var/lib/apt/lists/*
    rm -rf /var/cache/
    rm -rf /packages/
    rm -rf /boot/*
    

注意: 關於上面提到平臺相關的 deb 是怎麼來的,在文章的開頭變介紹了,這裡就不過多描述。可以多參看一下 buildroot 的操作過程,熟悉後,基本可以輕鬆瞭解整個環節

七、映象打包

#!/bin/bash -e

TARGET_ROOTFS_DIR=./binary
MOUNTPOINT=./rootfs
ROOTFSIMAGE=ubuntu-$IMAGE_VERSION-rootfs.img

echo Making rootfs!

if [ -e ${ROOTFSIMAGE} ]; then
	rm ${ROOTFSIMAGE}
fi
if [ -e ${MOUNTPOINT} ]; then
	rm -r ${MOUNTPOINT}
fi

sudo ./post-build.sh $TARGET_ROOTFS_DIR

# Create directories
mkdir ${MOUNTPOINT}
dd if=/dev/zero of=${ROOTFSIMAGE} bs=1M count=0 seek=7000

finish() {
	sudo umount ${MOUNTPOINT} || true
	echo -e "[ MAKE ROOTFS FAILED. ]"
	exit -1
}

echo Format rootfs to ext4
mkfs.ext4 ${ROOTFSIMAGE}

echo Mount rootfs to ${MOUNTPOINT}
sudo mount  ${ROOTFSIMAGE} ${MOUNTPOINT}
trap finish ERR

echo Copy rootfs to ${MOUNTPOINT}
sudo cp -rfp ${TARGET_ROOTFS_DIR}/*  ${MOUNTPOINT}

echo Umount rootfs
sudo umount ${MOUNTPOINT}

echo Rootfs Image: ${ROOTFSIMAGE}

e2fsck -p -f ${ROOTFSIMAGE}
resize2fs -M ${ROOTFSIMAGE}

將會發現整個打包的過程也比較簡單,前面也有筆記進行介紹。

八、總結

到此我們對於 ARM 環境中安裝系統的操作基本結束了,看到這裡都沒什麼問題的小夥伴也徹底掌握了移植的流程和移植過程中的問題處理。剩下的就是時間問題。

給大家的建議也很簡單,在學習的時候,一定要多練習,有時候腦子是明白了,一操作感覺又啥都不會,在練習的過程中,可以幫助自己理解。

這裡我們再次感謝野火的無私奉獻,他們的指令碼,幫助我們快速學習 ubuntu 環境的安裝,大大省去了自己編寫指令碼的過程,特別像我們這樣對編寫 shell 指令碼熟練不是很高的小夥伴,話的時間會更久。

最後便可以學習 android 和 鴻蒙系統的安裝,由於我也在學習的過程中,還要自己的工作要處理,所以後面的筆記出的會慢一些。也歡迎大家一起加入學習的隊伍中來,相互分型,共同加快學習的速度。

相關文章