├── VERSION ├── board ├── walnutpi-1b │ ├── debian12 │ │ ├── pip │ │ ├── wpi-desktop │ │ ├── apt-desktop │ │ ├── wpi-base │ │ └── apt-base │ ├── ubuntu22 │ │ ├── pip │ │ ├── apt-desktop │ │ ├── wpi-desktop │ │ ├── wpi-base │ │ └── apt-base │ ├── ubuntu24 │ │ ├── pip │ │ ├── apt-desktop │ │ ├── wpi-desktop │ │ ├── wpi-base │ │ └── apt-base │ ├── debian12_burn │ │ ├── apt-del │ │ ├── wpi-base │ │ └── apt-base │ ├── config.txt │ ├── board.conf │ └── boot.cmd └── walnutpi-2b │ ├── ubuntu24 │ ├── pip │ ├── wpi-desktop │ ├── apt-desktop │ ├── wpi-base │ └── apt-base │ ├── debian12 │ ├── pip │ ├── wpi-desktop │ ├── apt-desktop │ ├── wpi-base │ └── apt-base │ ├── boot │ ├── bl31.bin │ ├── scp.bin │ └── splash.bin │ ├── debian11 │ ├── pip │ ├── wpi-desktop │ ├── apt-desktop │ ├── wpi-base │ └── apt-base │ ├── debian12_burn │ ├── apt-del │ ├── wpi-base │ └── apt-base │ ├── config.txt │ └── board.conf ├── docker-build.sh ├── docker-pack-all.sh ├── docker-build-kernel.sh ├── docker-build-rootfs.sh ├── docker-pack-rootfs.sh ├── docker-build-bootloader.sh ├── update-info ├── scripts ├── build_rootfs-tmp.sh ├── pack_rootfs_tar.sh ├── option.sh ├── compile_kernel.sh ├── compile_Syterkit.sh ├── path.sh ├── compile_uboot.sh ├── menu.sh ├── pack_boot_deb.sh ├── common.sh ├── build_image.sh ├── build_rootfs.sh ├── build_kernel.sh ├── gen_rootfs.sh ├── pack_kernel_deb.sh └── pack_all_img.sh ├── .gitignore ├── dockerfile ├── README.md ├── __run_as_docker.sh ├── pack-rootfs.sh └── pack-all.sh /VERSION: -------------------------------------------------------------------------------- 1 | 2.4 -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12/pip: -------------------------------------------------------------------------------- 1 | jedi 2 | numpy 3 | paho-mqtt==1.6.1 4 | pyinstaller -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu22/pip: -------------------------------------------------------------------------------- 1 | jedi 2 | numpy 3 | paho-mqtt==1.6.1 4 | pyinstaller -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu24/pip: -------------------------------------------------------------------------------- 1 | jedi 2 | numpy 3 | paho-mqtt==1.6.1 4 | pyinstaller -------------------------------------------------------------------------------- /board/walnutpi-2b/ubuntu24/pip: -------------------------------------------------------------------------------- 1 | jedi 2 | numpy 3 | paho-mqtt==1.6.1 4 | pyinstaller -------------------------------------------------------------------------------- /board/walnutpi-2b/ubuntu24/wpi-desktop: -------------------------------------------------------------------------------- 1 | conf-ubuntu-autologin 2 | wpi-lightdm 3 | -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu22/apt-desktop: -------------------------------------------------------------------------------- 1 | ubuntu-desktop 2 | language-pack-gnome-zh-hans 3 | -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu24/apt-desktop: -------------------------------------------------------------------------------- 1 | ubuntu-desktop 2 | language-pack-gnome-zh-hans 3 | lightdm 4 | -------------------------------------------------------------------------------- /board/walnutpi-2b/ubuntu24/apt-desktop: -------------------------------------------------------------------------------- 1 | ubuntu-desktop 2 | lightdm 3 | language-pack-gnome-zh-hans 4 | -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12/pip: -------------------------------------------------------------------------------- 1 | jedi 2 | numpy 3 | paho-mqtt==1.6.1 4 | pyinstaller 5 | opencv-contrib-python 6 | -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12_burn/apt-del: -------------------------------------------------------------------------------- 1 | # 在构建镜像时需要使用,但构建完卸载掉以缩小镜像体积 2 | python3 3 | python3-pip 4 | python-dev-is-python3 -------------------------------------------------------------------------------- /board/walnutpi-2b/boot/bl31.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/walnutpi/walnutpi-build/HEAD/board/walnutpi-2b/boot/bl31.bin -------------------------------------------------------------------------------- /board/walnutpi-2b/boot/scp.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/walnutpi/walnutpi-build/HEAD/board/walnutpi-2b/boot/scp.bin -------------------------------------------------------------------------------- /board/walnutpi-2b/debian11/pip: -------------------------------------------------------------------------------- 1 | # jedi 2 | # numpy 3 | # paho-mqtt==1.6.1 4 | # pyinstaller 5 | # opencv-contrib-python 6 | -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12_burn/apt-del: -------------------------------------------------------------------------------- 1 | # 在构建镜像时需要使用,但构建完卸载掉以缩小镜像体积 2 | python3 3 | python3-pip 4 | python-dev-is-python3 -------------------------------------------------------------------------------- /board/walnutpi-2b/boot/splash.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/walnutpi/walnutpi-build/HEAD/board/walnutpi-2b/boot/splash.bin -------------------------------------------------------------------------------- /docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/build.sh" "$@" -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12/wpi-desktop: -------------------------------------------------------------------------------- 1 | wpi-xfce4 2 | 3 | wpi-chromium 4 | conf-google-pinyin 5 | 6 | 7 | realvnc-vnc-viewer 8 | set-vnc 9 | 10 | walnutpi1b-desktop -------------------------------------------------------------------------------- /board/walnutpi-2b/debian11/wpi-desktop: -------------------------------------------------------------------------------- 1 | wpi-xfce4 2 | service-restart-lightdm 3 | 4 | wpi-chromium 5 | conf-google-pinyin 6 | 7 | 8 | # realvnc-vnc-viewer 9 | set-vnc 10 | -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12/wpi-desktop: -------------------------------------------------------------------------------- 1 | wpi-xfce4 2 | service-restart-lightdm 3 | 4 | wpi-chromium 5 | conf-google-pinyin 6 | 7 | 8 | # realvnc-vnc-viewer 9 | set-vnc 10 | -------------------------------------------------------------------------------- /docker-pack-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/pack-all.sh" "$@" -------------------------------------------------------------------------------- /docker-build-kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/build-kernel.sh" "$@" -------------------------------------------------------------------------------- /docker-build-rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/build-rootfs.sh" "$@" -------------------------------------------------------------------------------- /docker-pack-rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/pack-rootfs.sh" "$@" -------------------------------------------------------------------------------- /docker-build-bootloader.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 3 | ${PATH_PROJECT_DIR}/__run_as_docker.sh "${PATH_PROJECT_DIR}/build-bootloader.sh" "$@" -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu22/wpi-desktop: -------------------------------------------------------------------------------- 1 | # wpi-xfce4 2 | conf-ubuntu-autologin 3 | 4 | # wpi-chromium 5 | # conf-google-pinyin 6 | 7 | # realvnc-vnc-viewer 8 | # set-vnc 9 | 10 | # walnutpi1b-desktop -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu24/wpi-desktop: -------------------------------------------------------------------------------- 1 | # wpi-xfce4 2 | conf-ubuntu-autologin 3 | 4 | # wpi-chromium 5 | # conf-google-pinyin 6 | 7 | # realvnc-vnc-viewer 8 | # set-vnc 9 | 10 | # walnutpi1b-desktop -------------------------------------------------------------------------------- /update-info: -------------------------------------------------------------------------------- 1 | # v1.2 2 | ## Core update 3 | - modify use sudo no passwd necessary 4 | - config.txt add env `console_uart` `console_display` `display_bootinfo` 5 | - add `python3-pyqt5` and settings 6 | - desktop system add software `qt-designed` 7 | - server system add a xorg console 8 | 9 | 10 | 11 | # V1.1 12 | ## Core update 13 | - command `set-vnc`: setting the vnc server 14 | 15 | 16 | 17 | # V1.0 18 | first release 19 | -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12/apt-desktop: -------------------------------------------------------------------------------- 1 | 2 | xfce4 3 | xfce4-notifyd 4 | xfce4-screenshooter 5 | xfce4-terminal 6 | xfce4-power-manager 7 | xfce4-pulseaudio-plugin 8 | xfce4-taskmanager 9 | x11vnc 10 | 11 | menulibre 12 | dmz-cursor-theme 13 | blueman 14 | network-manager-gnome 15 | 16 | mousepad 17 | thonny 18 | geany 19 | ristretto 20 | vlc 21 | galculator 22 | 23 | chromium 24 | chromium-driver 25 | chromium-l10n 26 | 27 | fcitx 28 | fcitx-googlepinyin 29 | 30 | libreoffice 31 | libreoffice-l10n-zh-cn 32 | 33 | qttools5-dev-tools 34 | 35 | -------------------------------------------------------------------------------- /scripts/build_rootfs-tmp.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | add_file_to_tmp_rootfs() { 4 | local source_file=$1 5 | local dest_path=$2 6 | if [[ -f "$source_file" ]]; then 7 | if [[ -d "$dest_path" ]]; then 8 | rm -r "$dest_path" 9 | fi 10 | mkdir -p "$dest_path" 11 | run_status "copy $(basename $source_file) to $dest_path" cp "$source_file" "$dest_path" 12 | fi 13 | } 14 | 15 | add_emmc_burn_file(){ 16 | local source_file=$1 17 | add_file_to_tmp_rootfs ${source_file} "${TMP_rootfs_build}/opt/burn" 18 | } 19 | -------------------------------------------------------------------------------- /scripts/pack_rootfs_tar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 参数说明: 4 | # $1 - TMP_rootfs_build: 临时构建rootfs的目录 5 | # $2 - OUTFILE_rootfs_tar: 输出的rootfs tar压缩包文件路径 6 | pack_rootfs_tar() { 7 | local TMP_rootfs_build=$1 8 | local OUTFILE_rootfs_tar=$2 9 | echo "TMP_rootfs_build: $TMP_rootfs_build" 10 | echo "OUTFILE_rootfs_tar: $OUTFILE_rootfs_tar" 11 | cd ${TMP_rootfs_build} 12 | if [ -f "$OUTFILE_rootfs_tar" ]; then 13 | rm $OUTFILE_rootfs_tar 14 | fi 15 | run_status "create tar" tar -c -I 'xz -T0' -f $OUTFILE_rootfs_tar ./ 16 | } -------------------------------------------------------------------------------- /board/walnutpi-2b/debian11/apt-desktop: -------------------------------------------------------------------------------- 1 | 2 | xfce4 3 | xfce4-notifyd 4 | xfce4-screenshooter 5 | xfce4-terminal 6 | xfce4-power-manager 7 | xfce4-pulseaudio-plugin 8 | xfce4-taskmanager 9 | x11vnc 10 | 11 | menulibre 12 | dmz-cursor-theme 13 | blueman 14 | network-manager-gnome 15 | 16 | # mousepad 17 | # thonny 18 | # geany 19 | ristretto 20 | vlc 21 | galculator 22 | 23 | chromium 24 | chromium-driver 25 | chromium-l10n 26 | 27 | fcitx 28 | fcitx-googlepinyin 29 | 30 | # libreoffice 31 | # libreoffice-l10n-zh-cn 32 | 33 | # qttools5-dev-tools 34 | 35 | -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12/apt-desktop: -------------------------------------------------------------------------------- 1 | 2 | xfce4 3 | xfce4-notifyd 4 | xfce4-screenshooter 5 | xfce4-terminal 6 | xfce4-power-manager 7 | xfce4-pulseaudio-plugin 8 | xfce4-taskmanager 9 | x11vnc 10 | 11 | menulibre 12 | dmz-cursor-theme 13 | blueman 14 | network-manager-gnome 15 | 16 | mousepad 17 | thonny 18 | geany 19 | ristretto 20 | vlc 21 | galculator 22 | 23 | chromium 24 | chromium-driver 25 | chromium-l10n 26 | 27 | fcitx 28 | fcitx-googlepinyin 29 | 30 | libreoffice 31 | libreoffice-l10n-zh-cn 32 | 33 | qttools5-dev-tools 34 | 35 | glmark2-x11 36 | -------------------------------------------------------------------------------- /board/walnutpi-2b/ubuntu24/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | # wpi-lightdm 5 | gpioc 6 | blinka 7 | # walnutpi-lib 8 | conf-t527-audio 9 | conf-w2-eth 10 | conf-qtenv 11 | enable-ssh-root 12 | disable-wifi-random 13 | 14 | set-emmc 15 | set-device 16 | set-language 17 | set-lcd 18 | set-flash 19 | set-nvme 20 | pyuic 21 | # python3-sudo 22 | 23 | bluez 24 | hcitools 25 | initramfs-tools-hook 26 | plymouth-themes-walnutpi 27 | 28 | service-disable-fbcon 29 | service-resize-part 30 | service-aw869-bluetooth 31 | 32 | 33 | fix-ubuntu-networkd-wait 34 | map-device -------------------------------------------------------------------------------- /board/walnutpi-2b/config.txt: -------------------------------------------------------------------------------- 1 | version=1.2 2 | 3 | ## config screen 4 | screen=hdmi 5 | 6 | fdtfile=sun55i-t527-walnutpi-2b 7 | 8 | ## enable the console with screen 9 | console_display=enable 10 | console_uart=uart0 11 | 12 | ## show the bootinfo to the screen 13 | display_bootinfo=enable 14 | 15 | ## force hdmi fb hotplug 16 | hdmi_force_hotplug=1 17 | 18 | ## loglevel 19 | printk_level=3 20 | 21 | overlay_prefix=sun55i-t527 22 | 23 | # 开机后运行set-device指令管理overlays 24 | overlays= i2c1 i2c2 uart2 spidev1_0 spidev1_1 25 | 26 | 27 | #------------------------------------------------# 28 | rootfstype=ext4 29 | -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | wpi-lightdm 5 | walnutpi-lib 6 | 7 | conf-h616-audio 8 | conf-qtenv 9 | enable-ssh-root 10 | disable-wifi-random 11 | 12 | set-emmc 13 | set-device 14 | set-language 15 | set-lcd 16 | pyuic 17 | # python3-sudo 18 | 19 | bluez 20 | hcitools 21 | initramfs-tools-hook 22 | plymouth-themes-walnutpi 23 | 24 | service-disable-fbcon 25 | service-h616-mac-detect 26 | service-resize-part 27 | service-aw859-bluetooth 28 | service-boot-script 29 | service-h616-conf-thermal-trip 30 | service-w1b-dis-mmc2 31 | 32 | map-device 33 | -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu22/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | # wpi-lightdm 5 | walnutpi-lib 6 | conf-h616-audio 7 | conf-h616-eth0 8 | conf-qtenv 9 | enable-ssh-root 10 | disable-wifi-random 11 | 12 | set-emmc 13 | set-device 14 | set-language 15 | set-lcd 16 | pyuic 17 | # python3-sudo 18 | 19 | bluez 20 | hcitools 21 | initramfs-tools-hook 22 | plymouth-themes-walnutpi 23 | 24 | service-disable-fbcon 25 | service-h616-mac-detect 26 | service-resize-part 27 | service-aw859-bluetooth 28 | service-h616-conf-thermal-trip 29 | service-w1b-dis-mmc2 30 | 31 | fix-ubuntu-networkd-wait 32 | map-device -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu24/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | # wpi-lightdm 5 | # walnutpi-lib 6 | conf-h616-audio 7 | conf-h616-eth0 8 | conf-qtenv 9 | enable-ssh-root 10 | disable-wifi-random 11 | 12 | set-emmc 13 | set-device 14 | set-language 15 | set-lcd 16 | pyuic 17 | # python3-sudo 18 | 19 | bluez 20 | hcitools 21 | initramfs-tools-hook 22 | plymouth-themes-walnutpi 23 | 24 | service-disable-fbcon 25 | service-h616-mac-detect 26 | service-resize-part 27 | service-aw859-bluetooth 28 | service-h616-conf-thermal-trip 29 | service-w1b-dis-mmc2 30 | 31 | fix-ubuntu-networkd-wait 32 | map-device -------------------------------------------------------------------------------- /board/walnutpi-2b/debian11/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | wpi-lightdm 5 | 6 | # walnutpi.npu 7 | # walnutpi.lib 8 | 9 | # gpioc 10 | # blinka 11 | 12 | 13 | conf-t527-audio 14 | conf-qtenv 15 | enable-ssh-root 16 | disable-wifi-random 17 | conf-iptables-as-legacy 18 | 19 | set-emmc 20 | set-device 21 | set-language 22 | set-lcd 23 | set-flash 24 | set-nvme 25 | pyuic 26 | 27 | # bluez 28 | hcitools 29 | initramfs-tools-hook 30 | plymouth-themes-walnutpi 31 | 32 | service-disable-fbcon 33 | service-resize-part 34 | service-aw869-bluetooth 35 | service-boot-script 36 | service-w2b-dis-eth-led 37 | 38 | map-device -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12_burn/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | wpi-lightdm 5 | # walnutpi-lib 6 | gpioc 7 | 8 | conf-h616-audio 9 | conf-qtenv 10 | enable-ssh-root 11 | disable-wifi-random 12 | 13 | set-emmc 14 | set-device 15 | set-language 16 | set-lcd 17 | pyuic 18 | # python3-sudo 19 | 20 | bluez 21 | hcitools 22 | initramfs-tools-hook 23 | plymouth-themes-walnutpi 24 | 25 | service-disable-fbcon 26 | # service-h616-mac-detect 27 | # service-resize-part 28 | service-aw859-bluetooth 29 | service-boot-script 30 | service-h616-conf-thermal-trip 31 | service-w1b-dis-mmc2 32 | 33 | map-device 34 | 35 | 36 | emmc-burner -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12_burn/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | # wpi-lightdm 5 | gpioc 6 | # blinka 7 | 8 | 9 | conf-t527-audio 10 | # conf-qtenv 11 | enable-ssh-root 12 | # disable-wifi-random 13 | conf-iptables-as-legacy 14 | 15 | set-emmc 16 | set-device 17 | set-language 18 | set-lcd 19 | # set-flash 20 | # set-nvme 21 | # pyuic 22 | # # python3-sudo 23 | 24 | # bluez 25 | # hcitools 26 | # initramfs-tools-hook 27 | # plymouth-themes-walnutpi 28 | 29 | service-disable-fbcon 30 | # service-resize-part 31 | # service-aw869-bluetooth 32 | service-boot-script 33 | # service-aw-eth-mac 34 | 35 | # map-device 36 | 37 | emmc-burner -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12/wpi-base: -------------------------------------------------------------------------------- 1 | wpi-user 2 | wpi-host-name 3 | wpi-welcome-info 4 | wpi-lightdm 5 | 6 | walnutpi.npu 7 | walnutpi.lib 8 | 9 | mesa-xorg-g57-debian12 10 | 11 | gpioc 12 | blinka 13 | 14 | 15 | conf-t527-audio 16 | conf-qtenv 17 | enable-ssh-root 18 | disable-wifi-random 19 | conf-iptables-as-legacy 20 | 21 | set-emmc 22 | set-device 23 | set-language 24 | set-lcd 25 | set-flash 26 | set-nvme 27 | pyuic 28 | # python3-sudo 29 | 30 | bluez 31 | hcitools 32 | initramfs-tools-hook 33 | plymouth-themes-walnutpi 34 | 35 | service-disable-fbcon 36 | service-resize-part 37 | service-aw869-bluetooth 38 | service-boot-script 39 | service-w2b-dis-eth-led 40 | 41 | map-device -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Don't add files that are generated in specific 3 | # subdirectories here. Add them in the ".gitignore" file 4 | # in that subdirectory instead. 5 | # 6 | # NOTE! Please use 'git ls-files -i --exclude-standard' 7 | # command after changing this file, to see if there are 8 | # any tracked files which get ignored after the change. 9 | # 10 | # Normal rules 11 | # 12 | 13 | *.bak 14 | *.swp 15 | *.tar.gz 16 | *.o.cmd 17 | *.gz.cmd 18 | 19 | 20 | .config 21 | .config.old 22 | .tmp 23 | .vscode 24 | output 25 | 26 | toolchains/libexec/ 27 | 28 | *.changes 29 | *.buildinfo 30 | 31 | external/cache/.gpg 32 | external/cache/hash 33 | external/cache/rootfs 34 | source/ 35 | walnut1b.img 36 | toolchain/ 37 | *.log 38 | debug*/ 39 | boot.scr 40 | 41 | -------------------------------------------------------------------------------- /scripts/option.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | OPT_user_no_choose="no_choose" 6 | OPT_NO="no" 7 | OPT_YES="yes" 8 | OPT_part_image="image" 9 | OPT_part_bootloader="bootloader" 10 | OPT_part_kernel="kernel" 11 | OPT_part_rootfs="rootfs" 12 | OPT_part_pack_rootfs="pack_rootfs" 13 | OPT_part_pack_image="pack_image" 14 | OPT_part_emmc_burn_rootfs="rootfs_burn_emmc" 15 | OPT_part_pack_emmc_burn="pack_burn_emmc" 16 | OPT_os_debian11="debian11" 17 | OPT_os_debian12="debian12" 18 | OPT_os_debian12_burn="debian12_burn" 19 | OPT_os_ubuntu22="ubuntu22" 20 | OPT_os_ubuntu24="ubuntu24" 21 | OPT_rootfs_server="server" 22 | OPT_rootfs_desktop="desktop" 23 | OPT_skip_boot="skip-boot" 24 | OPT_skip_kernel="skip-kernel" 25 | 26 | FLAG_SCRIPT_get_need="get_need" 27 | FLAG_SCRIPT_NEED_board="need_board" -------------------------------------------------------------------------------- /board/walnutpi-1b/config.txt: -------------------------------------------------------------------------------- 1 | version=1.1 2 | 3 | ## config screen 4 | screen=hdmi 5 | 6 | 7 | bootlogo=false 8 | overlay_prefix=sun50i-h616 9 | fdtfile=sun50i-h616-walnutpi-1b 10 | fdtfile_emmc=sun50i-h616-walnutpi-1b-emmc 11 | 12 | ## enable the console with screen 13 | console_display=enable 14 | console_uart=uart0 15 | 16 | ## show the bootinfo to the screen 17 | display_bootinfo=enable 18 | 19 | 20 | ## loglevel 21 | printk_level=3 22 | 23 | ## Specify HDMI output resolution (eg. extraargs=video=HDMI-A-1:800x480-24@60) 24 | #extraargs=video=HDMI-A-1:1024x600-24@60 25 | 26 | 27 | #spi : spidev0_0 spidev1_0 spidev1_1 spidev1_2 28 | #i2c : i2c1 i2c2 i2c4 29 | #uart : uart2 uart4 30 | overlays=spi1 i2c1 i2c2 uart2 31 | 32 | 33 | #------------------------------------------------# 34 | rootfstype=ext4 35 | -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | 52 | 53 | u-boot-tools 54 | initramfs-tools 55 | device-tree-compiler 56 | 57 | dbus-x11 58 | xorg 59 | xserver-xorg-input-evdev 60 | xinput-calibrator 61 | xserver-xorg-input-synaptics 62 | xfwm4 63 | lightdm 64 | 65 | plymouth-themes -------------------------------------------------------------------------------- /board/walnutpi-2b/debian11/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | # btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | # python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | mtd-utils 52 | pciutils 53 | dosfstools 54 | 55 | u-boot-tools 56 | initramfs-tools 57 | device-tree-compiler 58 | 59 | dbus-x11 60 | xorg 61 | xserver-xorg-input-evdev 62 | xinput-calibrator 63 | xserver-xorg-input-synaptics 64 | xfwm4 65 | lightdm 66 | 67 | # plymouth-themes -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | mtd-utils 52 | pciutils 53 | dosfstools 54 | 55 | u-boot-tools 56 | initramfs-tools 57 | device-tree-compiler 58 | 59 | dbus-x11 60 | xorg 61 | xserver-xorg-input-evdev 62 | xinput-calibrator 63 | xserver-xorg-input-synaptics 64 | xfwm4 65 | lightdm 66 | 67 | glmark2-drm 68 | 69 | # plymouth-themes -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu24/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | 52 | 53 | u-boot-tools 54 | initramfs-tools 55 | device-tree-compiler 56 | 57 | # dbus-x11 58 | # xorg 59 | # xserver-xorg-input-evdev 60 | # xinput-calibrator 61 | # xserver-xorg-input-synaptics 62 | # xfwm4 63 | 64 | netplan.io 65 | inetutils-ping 66 | plymouth-themes 67 | 68 | language-pack-zh-hans 69 | -------------------------------------------------------------------------------- /board/walnutpi-1b/ubuntu22/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | 52 | 53 | u-boot-tools 54 | initramfs-tools 55 | device-tree-compiler 56 | 57 | # dbus-x11 58 | # xorg 59 | # xserver-xorg-input-evdev 60 | # xinput-calibrator 61 | # xserver-xorg-input-synaptics 62 | # xfwm4 63 | # lightdm 64 | 65 | netplan.io 66 | inetutils-ping 67 | plymouth-themes 68 | 69 | language-pack-zh-hans 70 | -------------------------------------------------------------------------------- /board/walnutpi-2b/ubuntu24/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | iw 10 | wireless-tools 11 | ir-keytable 12 | evtest 13 | rfkill 14 | bluez 15 | ntp 16 | ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | fdisk 26 | tree 27 | btop 28 | bc 29 | 30 | fbterm 31 | locales 32 | fonts-wqy-zenhei 33 | 34 | vim 35 | gcc 36 | git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | # python3-pyqt5* 42 | 43 | i2c-tools 44 | usbutils 45 | 46 | toilet 47 | nfs-common 48 | fbset 49 | libts-bin 50 | alsa-utils 51 | mtd-utils 52 | pciutils 53 | dosfstools 54 | 55 | u-boot-tools 56 | initramfs-tools 57 | device-tree-compiler 58 | 59 | # dbus-x11 60 | # xorg 61 | # xserver-xorg-input-evdev 62 | # xinput-calibrator 63 | # xserver-xorg-input-synaptics 64 | # xfwm4 65 | # lightdm 66 | 67 | netplan.io 68 | inetutils-ping 69 | plymouth-themes 70 | 71 | language-pack-zh-hans -------------------------------------------------------------------------------- /board/walnutpi-1b/debian12_burn/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | # iw 10 | # wireless-tools 11 | # ir-keytable 12 | # evtest 13 | # rfkill 14 | # bluez 15 | # ntp 16 | # ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | # fdisk 26 | # tree 27 | # btop 28 | bc 29 | 30 | # fbterm 31 | # locales 32 | # fonts-wqy-zenhei 33 | 34 | # vim 35 | gcc 36 | # git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | # python3-pyqt5* 42 | 43 | # i2c-tools 44 | # usbutils 45 | 46 | # toilet 47 | # nfs-common 48 | # fbset 49 | # libts-bin 50 | # alsa-utils 51 | # mtd-utils 52 | # pciutils 53 | # dosfstools 54 | 55 | u-boot-tools 56 | initramfs-tools 57 | device-tree-compiler 58 | 59 | # dbus-x11 60 | # xorg 61 | # xserver-xorg-input-evdev 62 | # xinput-calibrator 63 | # xserver-xorg-input-synaptics 64 | # xfwm4 65 | # lightdm 66 | 67 | # # plymouth-themes 68 | 69 | libfreetype6-dev -------------------------------------------------------------------------------- /board/walnutpi-2b/debian12_burn/apt-base: -------------------------------------------------------------------------------- 1 | 2 | libc6-dev 3 | bison 4 | flex 5 | libssl-dev 6 | 7 | network-manager 8 | net-tools 9 | # iw 10 | # wireless-tools 11 | # ir-keytable 12 | # evtest 13 | # rfkill 14 | # bluez 15 | # ntp 16 | # ntpdate 17 | 18 | ssh 19 | sudo 20 | bash-completion 21 | systemd-timesyncd 22 | parted 23 | wget 24 | curl 25 | # fdisk 26 | # tree 27 | # btop 28 | bc 29 | 30 | # fbterm 31 | # locales 32 | # fonts-wqy-zenhei 33 | 34 | # vim 35 | gcc 36 | # git 37 | make 38 | python3 39 | python3-pip 40 | python-dev-is-python3 41 | # python3-pyqt5* 42 | 43 | # i2c-tools 44 | # usbutils 45 | 46 | # toilet 47 | # nfs-common 48 | # fbset 49 | # libts-bin 50 | # alsa-utils 51 | # mtd-utils 52 | # pciutils 53 | # dosfstools 54 | 55 | u-boot-tools 56 | initramfs-tools 57 | device-tree-compiler 58 | 59 | # dbus-x11 60 | # xorg 61 | # xserver-xorg-input-evdev 62 | # xinput-calibrator 63 | # xserver-xorg-input-synaptics 64 | # xfwm4 65 | # lightdm 66 | 67 | # # plymouth-themes 68 | 69 | libfreetype6-dev -------------------------------------------------------------------------------- /board/walnutpi-1b/board.conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BOARD_NAME="WalnutPi-1b" 3 | BOARD_MODEL="walnutpi-1b" 4 | CHIP_ARCH="arm64" 5 | 6 | # 使用指定下载的gcc 7 | # TOOLCHAIN_DOWN_URL="https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz" 8 | # TOOLCHAIN_FILE_NAME="gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu" 9 | # CROSS_COMPILE="aarch64-none-linux-gnu-" 10 | 11 | # 使用本机自带的gcc,不存在则现场apt安装 12 | TOOLCHAIN_NAME_IN_APT="gcc-aarch64-linux-gnu" 13 | CROSS_COMPILE="aarch64-linux-gnu-" 14 | 15 | BOOTLOADER_NAME="u-boot" 16 | 17 | ATF_GIT="https://github.com/ARM-software/arm-trusted-firmware.git" 18 | ATF_PLAT="sun50i_h616" 19 | ATF_BRANCH="lts-v2.10.2" 20 | 21 | UBOOT_GIT="https://github.com/walnutpi/u-boot.git" 22 | UBOOT_BRANCH="v2024.01" 23 | UBOOT_CONFIG="walnutpi_1b_defconfig" 24 | UBOOT_BIN_NAME="u-boot-sunxi-with-spl.bin" 25 | 26 | LINUX_GIT="https://github.com/walnutpi/linux.git" 27 | LINUX_BRANCH="6.1.31" 28 | LINUX_CONFIG="walnutpi1b_defconfig" 29 | MODULES_ENABLE="sprdwl_ng sprdbt_tty" 30 | FIRMWARE_GIT="https://github.com/walnutpi/firmware.git" 31 | -------------------------------------------------------------------------------- /scripts/compile_kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 参数说明: 3 | # $1 - SOURCE_kernel: 内核源码路径 4 | # $2 - LINUX_CONFIG: 内核配置文件名 5 | # $3 - USE_CROSS_COMPILE: 交叉编译前缀 6 | # $4 - CHIP_ARCH: 芯片架构 7 | compile_kernel() { 8 | local SOURCE_kernel=$1 9 | local LINUX_CONFIG=$2 10 | local USE_CROSS_COMPILE=$3 11 | local CHIP_ARCH=$4 12 | # 输出所有参数 13 | echo "SOURCE_kernel=$SOURCE_kernel" 14 | echo "LINUX_CONFIG=$LINUX_CONFIG" 15 | echo "USE_CROSS_COMPILE=$USE_CROSS_COMPILE" 16 | echo "CHIP_ARCH=$CHIP_ARCH" 17 | 18 | cd $SOURCE_kernel 19 | if [ ! -f .scmversion ]; then 20 | touch .scmversion 21 | fi 22 | thread_count=$(grep -c ^processor /proc/cpuinfo) 23 | make $LINUX_CONFIG CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 24 | make -j$thread_count CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 25 | 26 | if [ -d bsp/modules/gpu ]; then 27 | export srctree=$(pwd) 28 | make -j$thread_count CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} -C bsp/modules/gpu M=bsp/modules/gpu 29 | fi 30 | exit_if_last_error 31 | echo "kernel compile success" 32 | } 33 | -------------------------------------------------------------------------------- /dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM ubuntu:22.04 3 | 4 | # 以无交互的方式安装软件 5 | ENV DEBIAN_FRONTEND=noninteractive 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y \ 9 | gcc-aarch64-linux-gnu \ 10 | gcc-arm-none-eabi \ 11 | cmake \ 12 | debian-archive-keyring \ 13 | curl \ 14 | whiptail \ 15 | bc \ 16 | qemu-user-static \ 17 | debootstrap \ 18 | kpartx \ 19 | git \ 20 | bison \ 21 | flex \ 22 | swig \ 23 | libssl-dev \ 24 | device-tree-compiler \ 25 | u-boot-tools \ 26 | make \ 27 | python3 \ 28 | python3-dev \ 29 | python3-pip \ 30 | sudo \ 31 | libpam-runtime \ 32 | dosfstools \ 33 | parted \ 34 | build-essential \ 35 | xz-utils && \ 36 | apt-get clean && rm -rf /var/lib/apt/lists/* 37 | 38 | # 创建用户 pi 密码为 pi 39 | RUN useradd -m -s /bin/bash pi && \ 40 | echo "pi:pi" | chpasswd 41 | 42 | # pi 用户运行sudo不需要输入密码 43 | RUN mkdir -p /etc/sudoers.d 44 | RUN echo "pi ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/pi && \ 45 | chmod 0440 /etc/sudoers.d/pi 46 | 47 | # 以解除 pip 安装的限制 48 | RUN LIB_DIR="/usr/lib" && \ 49 | FILE_NAME="EXTERNALLY-MANAGED" && \ 50 | find $LIB_DIR -type f -name "$FILE_NAME" -delete 51 | 52 | RUN pip3 install setuptools 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # walnutpi-build 2 | 为核桃派构建系统镜像,我们发布的所有镜像都是用这个做出来的。有问题可以加qq群`677173708` 3 | - 在ubuntu22.04上运行,或使用docker运行 4 | - 运行时要从github下载东西,请确保网络畅通 5 | 6 | ## 构建镜像 7 | 运行本脚本前先安装好两个软件 8 | ```shell 9 | sudo apt install whiptail bc 10 | ``` 11 | 12 | clone项目到本地 13 | ```shell 14 | git clone -b main --depth 1 https://github.com/walnutpi/walnutpi-build.git 15 | ``` 16 | 17 | 运行构建脚本 18 | ```shell 19 | cd walnutpi-build 20 | sudo ./build.sh 21 | 22 | # 如果本机有安装docker,建议使用docker-build.sh 23 | # sudo ./docker-build.sh 24 | ``` 25 | 26 | 在命令行出来的界面里,按`Esc`退出,`上下方向键`选择,按`回车`确认 27 | 28 | 1. 选择板子,按回车确认,目前支持 29 | - walnutpi-1b 30 | - walnutpi-2b 31 | 2. 选择系统版本,目前主要维护 debian12,其他系统版本都处于测试阶段 32 | 3. 选择系统类型,目前支持 33 | - server: 无桌面。 34 | - desktop: 在server版本基础上安装了xfce4桌面,预装了用于编程办公的桌面应用。 35 | 36 | 37 | ## 修改配置 38 | 在board文件夹下是各个板子的配置文件 39 | ### 修改系统的预装软件 40 | 以walnut2b,debian12为例,配置文件位于 **board/walnutpi-2b/debian12** 下,有5个文件:apt-base, apt-desktop, pip, wpi-base, wpi-desktop 41 | 42 | apt-base 和 apt-desktop 文件用于设置构建系统时会安装的软件,apt-base是server版和desktop版本系统都会安装的软件,apt-desktop 43 | 44 | pip 文件用于设置构建系统时会安装的python库 45 | 46 | wpi-base 和 wpi-desktop 文件也是用于设置构建系统时会安装的软件,但不同的是这些软件会从 apt.walnutpi.con 下载,这些包的内容都是我们制作的系统配置或是我们制作的库,我们将其存放在一个项目中 -> [wpi-update-server](https://github.com/walnutpi/wpi-update-server) 47 | 48 | -------------------------------------------------------------------------------- /scripts/compile_Syterkit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 编译 Syterkit 4 | # 参数说明: 5 | # $1: PATH_SOURCE - 源码路径 6 | # $2: SYTERKIT_GIT - Syterkit Git 仓库地址 7 | # $3: SYTERKIT_BRANCH - Syterkit 分支名 8 | # $4: SYTERKIT_BOARD_FILE - Syterkit 板级配置文件路径 9 | # $5: SYTERKIT_OUT_BIN - Syterkit 输出的二进制文件名 10 | # $6: OUTFILE_boot_bin - 最终输出的 boot 二进制文件路径 11 | compile_syterkit() { 12 | local PATH_SOURCE=$1 13 | local SYTERKIT_GIT=$2 14 | local SYTERKIT_BRANCH=$3 15 | local SYTERKIT_BOARD_FILE=$4 16 | local SYTERKIT_OUT_BIN=$5 17 | local OUTFILE_boot_bin=$6 18 | 19 | echo "PATH_SOURCE: $PATH_SOURCE" 20 | echo "SYTERKIT_GIT: $SYTERKIT_GIT" 21 | echo "SYTERKIT_BRANCH: $SYTERKIT_BRANCH" 22 | echo "SYTERKIT_BOARD_FILE: $SYTERKIT_BOARD_FILE" 23 | echo "SYTERKIT_OUT_BIN: $SYTERKIT_OUT_BIN" 24 | echo "OUTFILE_boot_bin: $OUTFILE_boot_bin" 25 | 26 | cd $PATH_SOURCE 27 | local dirname="${PATH_SOURCE}/$(basename "$SYTERKIT_GIT" .git)-$SYTERKIT_BRANCH" 28 | clone_branch $SYTERKIT_GIT $SYTERKIT_BRANCH $dirname 29 | cd $dirname 30 | local workspace_name="build" 31 | create_dir $workspace_name 32 | cd $workspace_name 33 | run_as_user cmake -DCMAKE_BOARD_FILE=$SYTERKIT_BOARD_FILE .. 34 | exit_if_last_error 35 | run_as_user make 36 | exit_if_last_error 37 | cp $SYTERKIT_OUT_BIN $OUTFILE_boot_bin 38 | } -------------------------------------------------------------------------------- /board/walnutpi-2b/board.conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BOARD_NAME="WalnutPi-2b" 3 | BOARD_MODEL="walnutpi-2b" 4 | CHIP_ARCH="arm64" 5 | 6 | # 使用指定下载的gcc 7 | # TOOLCHAIN_DOWN_URL="https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz" 8 | # TOOLCHAIN_FILE_NAME="gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu" 9 | # CROSS_COMPILE="aarch64-none-linux-gnu-" 10 | 11 | # 使用本机自带的gcc,不存在则现场apt安装 12 | TOOLCHAIN_NAME_IN_APT="gcc-aarch64-linux-gnu" 13 | CROSS_COMPILE="aarch64-linux-gnu-" 14 | 15 | BOOTLOADER_NAME="syterkit" 16 | 17 | SYTERKIT_GIT="https://github.com/walnutpi/SyterKit.git" 18 | SYTERKIT_BRANCH="main" 19 | SYTERKIT_BOARD_FILE="walnutpi-2b.cmake" 20 | SYTERKIT_OUT_BIN="board/walnutpi-2b/extlinux_boot/extlinux_boot_bin_card.bin" 21 | 22 | 23 | # ATF_GIT="https://github.com/ARM-software/arm-trusted-firmware.git" 24 | # ATF_PLAT="sun50i_h616" 25 | # ATF_BRANCH="lts-v2.10.2" 26 | 27 | # UBOOT_GIT="https://github.com/walnutpi/u-boot.git" 28 | # UBOOT_BRANCH="v2024.01" 29 | # UBOOT_CONFIG="walnutpi_1b_defconfig" 30 | # UBOOT_BIN_NAME="u-boot-sunxi-with-spl.bin" 31 | 32 | LINUX_GIT="https://github.com/walnutpi/linux.git" 33 | LINUX_BRANCH="5.15.147" 34 | LINUX_CONFIG="walnutpi2b_defconfig" 35 | MODULES_ENABLE="aic8800_bsp aic8800_btlpm aic8800_fdrv " 36 | FIRMWARE_GIT="https://github.com/walnutpi/firmware.git" 37 | -------------------------------------------------------------------------------- /__run_as_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOCKER_IMAGE_NAME=walnutpi-build:1.1 4 | CONTAINER_NAME="walnutpi-build-$(date +%s)" 5 | 6 | echo_red() { 7 | echo -e -n "\r\033[31m$1\033[0m" 8 | } 9 | echo_green() { 10 | echo -e -n "\r\033[32m$1\033[0m" 11 | } 12 | echo_blue() { 13 | echo -e -n "\r\033[36m$1\033[0m" 14 | } 15 | 16 | echo_green "[创建镜像] \t" 17 | if docker images --format "{{.Repository}}:{{.Tag}}" | grep -q "^${DOCKER_IMAGE_NAME}$"; then 18 | echo "'$DOCKER_IMAGE_NAME' 已存在" 19 | else 20 | echo "'$DOCKER_IMAGE_NAME' 不存在,开始构建..." 21 | docker build -t $DOCKER_IMAGE_NAME . 22 | fi 23 | 24 | # 判断是否传入参数 25 | if [ $# -eq 0 ]; then 26 | # 没有传入参数,进入交互模式 27 | echo_green "[进入容器]\t" 28 | echo "启动交互式容器..." 29 | 30 | docker run --name "$CONTAINER_NAME" \ 31 | --privileged \ 32 | --network host \ 33 | -v /etc/hosts:/etc/hosts:ro \ 34 | -v /etc/resolv.conf:/etc/resolv.conf:ro \ 35 | -v /etc/localtime:/etc/localtime:ro \ 36 | -v "$(pwd):$(pwd)" \ 37 | -w "$(pwd)" \ 38 | -it --rm "$DOCKER_IMAGE_NAME" bash 39 | else 40 | # 传入了参数,将所有参数作为命令执行 41 | RUN_COMMAND="$@" 42 | echo_green "[运行]\t" 43 | echo "$RUN_COMMAND" 44 | 45 | docker run --name "$CONTAINER_NAME" \ 46 | --privileged \ 47 | --network host \ 48 | -v /etc/hosts:/etc/hosts:ro \ 49 | -v /etc/resolv.conf:/etc/resolv.conf:ro \ 50 | -v /etc/localtime:/etc/localtime:ro \ 51 | -v "$(pwd):$(pwd)" \ 52 | -w "$(pwd)" \ 53 | -it --rm "$DOCKER_IMAGE_NAME" bash -c "$RUN_COMMAND" 54 | fi -------------------------------------------------------------------------------- /pack-rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 获取文件所在路径 3 | 4 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 5 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | source "${SCRIPT_DIR}/scripts/common.sh" 7 | source "${SCRIPT_DIR}/scripts/path.sh" 8 | source "${SCRIPT_DIR}/scripts/option.sh" 9 | source "${SCRIPT_DIR}/scripts/menu.sh" 10 | source "${SCRIPT_DIR}/scripts/gen_rootfs.sh" 11 | source "${SCRIPT_DIR}/scripts/pack_rootfs_tar.sh" 12 | 13 | # $1 为板级配置文件夹的路径 14 | # $2 为系统版本 15 | # $3 为rootfs类型 16 | main() { 17 | local ENTER_board_name="${PATH_board}/${1}" 18 | local ENTER_os_ver=$2 19 | local ENTER_rootfs_type=$3 20 | 21 | echo "board_name: $ENTER_board_name" 22 | echo "os_ver: $ENTER_os_ver" 23 | echo "rootfs_type: $ENTER_rootfs_type" 24 | 25 | source $ENTER_board_name/board.conf 26 | PATH_OUTPUT_BOARD=${PATH_OUTPUT}/${ENTER_board_name##*/} 27 | 28 | OUTFILE_rootfs_tar="${PATH_OUTPUT_BOARD}/rootfs_${ENTER_os_ver}_${ENTER_rootfs_type}.tar.gz" 29 | TMP_rootfs_build=${PATH_TMP}/rootfs-build/${BOARD_MODEL}_${ENTER_os_ver}_${ENTER_rootfs_type} 30 | 31 | pack_rootfs_tar $TMP_rootfs_build $OUTFILE_rootfs_tar 32 | } 33 | 34 | # 如果传入参数个数小于3个,则弹出选择窗口 35 | if [ $# -lt 3 ]; then 36 | ENTER_board_name=$(basename $(MENU_choose_board $PATH_board)) 37 | ENTER_os_ver=$(MENU_choose_os) 38 | if [ $ENTER_os_ver == $OPT_os_debian12_burn ]; then 39 | ENTER_rootfs_type=$OPT_rootfs_server 40 | else 41 | ENTER_rootfs_type=$(MENU_choose_rootfs_type) 42 | fi 43 | else 44 | ENTER_board_name=$1 45 | ENTER_os_ver=$2 46 | ENTER_rootfs_type=$3 47 | fi 48 | 49 | [[ -z ${ENTER_board_name} ]] && exit 50 | [[ -z ${ENTER_os_ver} ]] && exit 51 | [[ -z ${ENTER_rootfs_type} ]] && exit 52 | main $ENTER_board_name $ENTER_os_ver $ENTER_rootfs_type 53 | -------------------------------------------------------------------------------- /pack-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 获取文件所在路径 3 | 4 | PATH_PROJECT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" 5 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | source "${SCRIPT_DIR}/scripts/common.sh" 7 | source "${SCRIPT_DIR}/scripts/path.sh" 8 | source "${SCRIPT_DIR}/scripts/option.sh" 9 | source "${SCRIPT_DIR}/scripts/menu.sh" 10 | source "${SCRIPT_DIR}/scripts/pack_all_img.sh" 11 | 12 | # $1 为板级配置文件夹的路径 13 | # $2 为系统版本 14 | # $3 为rootfs类型 15 | # $4 为镜像文件路径 16 | main() { 17 | local ENTER_board_name="${PATH_board}/${1}" 18 | local ENTER_os_ver=$2 19 | local ENTER_rootfs_type=$3 20 | local ENTER_img_file=$4 21 | 22 | source $ENTER_board_name/board.conf 23 | PATH_OUTPUT_BOARD=${PATH_OUTPUT}/${ENTER_board_name##*/} 24 | source "${SCRIPT_DIR}/scripts/path.sh" 25 | pack_all_img "$OUTDIR_boot_package" "$OUTDIR_kernel_package" "$OUTFILE_rootfs_tar" "$PATH_SOURCE" "$BOARD_MODEL" "$FILE_apt_del" "$ENTER_os_ver" "$ENTER_rootfs_type" "$IMAGE_FLAG_NO_SCREEN_DISPLAY" "$BOOTLOADER_NAME" "$OUTFILE_boot_bin" "$LINUX_GIT" "$LINUX_BRANCH" "$PATH_PROJECT_DIR" "$ENTER_img_file" 26 | } 27 | 28 | # 如果传入参数个数小于3个,则弹出选择窗口 29 | if [ $# -lt 3 ]; then 30 | ENTER_board_name=$(basename $(MENU_choose_board $PATH_board)) 31 | ENTER_os_ver=$(MENU_choose_os) 32 | if [ $ENTER_os_ver == $OPT_os_debian12_burn ]; then 33 | ENTER_rootfs_type=$OPT_rootfs_server 34 | ENTER_img_file="$(MENU_choose_img_file)" 35 | if [ ! -z $ENTER_img_file ]; then 36 | ENTER_img_file="$PATH_OUTPUT/$(MENU_choose_img_file)" 37 | fi 38 | else 39 | ENTER_rootfs_type=$(MENU_choose_rootfs_type) 40 | fi 41 | else 42 | ENTER_board_name=$1 43 | ENTER_os_ver=$2 44 | ENTER_rootfs_type=$3 45 | ENTER_img_file=$4 46 | fi 47 | 48 | [[ -z ${ENTER_board_name} ]] && exit 49 | [[ -z ${ENTER_os_ver} ]] && exit 50 | [[ -z ${ENTER_rootfs_type} ]] && exit 51 | main $ENTER_board_name $ENTER_os_ver $ENTER_rootfs_type $ENTER_img_file 52 | -------------------------------------------------------------------------------- /scripts/path.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATH_board="${PATH_PROJECT_DIR}/board" 4 | PATH_SOURCE="${PATH_PROJECT_DIR}/source" 5 | PATH_OUTPUT="${PATH_PROJECT_DIR}/output" 6 | PATH_TMP="${PATH_PROJECT_DIR}/.tmp" 7 | PATH_LOG="${PATH_PROJECT_DIR}/log" 8 | PATH_TOOLCHAIN="${PATH_PROJECT_DIR}/toolchain" 9 | create_dir $PATH_SOURCE 10 | create_dir $PATH_OUTPUT 11 | create_dir $PATH_TMP 12 | create_dir $PATH_LOG 13 | create_dir $PATH_TOOLCHAIN 14 | 15 | # LOG_START_TIME=$(date +%m-%d_%H:%M) #在build.sh内定义 16 | LOG_MONTH_DIR="${PATH_LOG}/$(date +%Y-%m)" 17 | LOG_FILE="${LOG_MONTH_DIR}/${LOG_START_TIME}.log" 18 | create_dir $LOG_MONTH_DIR 19 | 20 | FLAG_DIR="${PATH_TMP}/FLAGS" 21 | FLAG_DIR_NO_FIRST="${FLAG_DIR}/not_first" 22 | 23 | # 编译bootloader相关 24 | OUTDIR_boot_package=${PATH_OUTPUT_BOARD}/boot 25 | OUTFILE_boot_bin=${OUTDIR_boot_package}/boot.bin 26 | PATH_save_boot_files="${ENTER_board_name}/boot" 27 | 28 | # 内核编译相关 29 | OUTDIR_kernel_package=${PATH_OUTPUT_BOARD}/kernel 30 | 31 | # 生成rootfs相关 32 | OUTFILE_rootfs_tar="${PATH_OUTPUT_BOARD}/rootfs_${ENTER_os_ver}_${ENTER_rootfs_type}.tar.gz" 33 | TMP_rootfs_build=${PATH_TMP}/${BOARD_MODEL}_${ENTER_os_ver}_${ENTER_rootfs_type} 34 | FILE_base_rootfs=${TMP_rootfs_build}_base_software.tar 35 | FILE_apt_base="${ENTER_board_name}/${ENTER_os_ver}/apt-base" 36 | FILE_apt_del="${ENTER_board_name}/${ENTER_os_ver}/apt-del" 37 | FILE_apt_desktop="${ENTER_board_name}/${ENTER_os_ver}/apt-desktop" 38 | FILE_apt_base_board="${ENTER_board_name}/${ENTER_os_ver}/wpi-base" 39 | FILE_apt_desktop_board="${ENTER_board_name}/${ENTER_os_ver}/wpi-desktop" 40 | FILE_pip_list="${ENTER_board_name}/${ENTER_os_ver}/pip" 41 | PLACE_sf_list="${TMP_rootfs_build}/etc/release-apt" 42 | 43 | # 打包镜像相关 44 | TMP_IMG_DISK1="${PATH_TMP}/PART1-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 45 | TMP_IMG_DISK2="${PATH_TMP}/PART2-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 46 | TMP_mount_disk1="${PATH_TMP}/MOUNT-PART1-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 47 | TMP_mount_disk2="${PATH_TMP}/MOUNT-PART2-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 48 | OUT_IMG_FILE="${PATH_OUTPUT}/V${VERSION_APT}_$(date +%m-%d)_${ENTER_rootfs_type}_${BOARD_NAME}_${LINUX_BRANCH}_${ENTER_os_ver}" 49 | -------------------------------------------------------------------------------- /scripts/compile_uboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 编译 ARM Trusted Firmware 4 | # 参数说明: 5 | # $1: PATH_SOURCE - 源码路径 6 | # $2: ATF_GIT - ATF Git 仓库地址 7 | # $3: ATF_BRANCH - ATF 分支名 8 | # $4: ATF_PLAT - ATF 平台配置 9 | # $5: USE_CROSS_COMPILE - 交叉编译前缀 10 | compile_atf() { 11 | local PATH_SOURCE=$1 12 | local ATF_GIT=$2 13 | local ATF_BRANCH=$3 14 | local ATF_PLAT=$4 15 | local USE_CROSS_COMPILE=$5 16 | 17 | # 输出所有传入参数的值 18 | echo " PATH_SOURCE: $PATH_SOURCE" 19 | echo " ATF_GIT: $ATF_GIT" 20 | echo " ATF_BRANCH: $ATF_BRANCH" 21 | echo " ATF_PLAT: $ATF_PLAT" 22 | echo " USE_CROSS_COMPILE: $USE_CROSS_COMPILE" 23 | 24 | cd $PATH_SOURCE 25 | echo $ATF_GIT 26 | local dirname="${PATH_SOURCE}/$(basename "$ATF_GIT" .git)" 27 | # 如果dirname路径不存在才clone 28 | if [ ! -d $dirname ]; then 29 | git clone $ATF_GIT 30 | fi 31 | cd $dirname 32 | git checkout $ATF_BRANCH 33 | run_as_user make PLAT=$ATF_PLAT DEBUG=1 bl31 CROSS_COMPILE=$USE_CROSS_COMPILE 34 | exit_if_last_error 35 | } 36 | 37 | # 编译 U-Boot 38 | # $1: PATH_SOURCE - 源码路径 39 | # $2: UBOOT_GIT - U-Boot Git 仓库地址 40 | # $3: UBOOT_BRANCH - U-Boot 分支名 41 | # $4: UBOOT_CONFIG - U-Boot 配置 42 | # $5: USE_CROSS_COMPILE - 交叉编译前缀 43 | # $6: UBOOT_BIN_NAME - U-Boot 二进制文件名 44 | # $7: OUTFILE_boot_bin - 输出的 boot 二进制文件路径 45 | # $8: ATF_PLAT - ATF 平台配置 (可选) 46 | compile_uboot() { 47 | local PATH_SOURCE=$1 48 | local UBOOT_GIT=$2 49 | local UBOOT_BRANCH=$3 50 | local UBOOT_CONFIG=$4 51 | local USE_CROSS_COMPILE=$5 52 | local UBOOT_BIN_NAME=$6 53 | local OUTFILE_boot_bin=$7 54 | local ATF_PLAT=$8 55 | # 输出所有传入参数的值 56 | 57 | echo " PATH_SOURCE: $PATH_SOURCE" 58 | echo " UBOOT_GIT: $UBOOT_GIT" 59 | echo " UBOOT_BRANCH: $UBOOT_BRANCH" 60 | echo " UBOOT_CONFIG: $UBOOT_CONFIG" 61 | echo " USE_CROSS_COMPILE: $USE_CROSS_COMPILE" 62 | echo " UBOOT_BIN_NAME: $UBOOT_BIN_NAME" 63 | echo " OUTFILE_boot_bin: $OUTFILE_boot_bin" 64 | echo " ATF_PLAT: $ATF_PLAT" 65 | 66 | 67 | cd $PATH_SOURCE 68 | 69 | local dirname="${PATH_SOURCE}/$(basename "$UBOOT_GIT" .git)-$UBOOT_BRANCH" 70 | clone_branch $UBOOT_GIT $UBOOT_BRANCH $dirname 71 | cd $dirname 72 | 73 | run_as_user make $UBOOT_CONFIG 74 | 75 | # 如果提供了ATF_PLAT,则使用BL31参数编译,否则直接使用CROSS_COMPILE编译 76 | if [ -n "$ATF_PLAT" ]; then 77 | run_as_user make BL31=../arm-trusted-firmware/build/$ATF_PLAT/debug/bl31.bin \ 78 | CROSS_COMPILE=$USE_CROSS_COMPILE 79 | else 80 | run_as_user make CROSS_COMPILE=$USE_CROSS_COMPILE 81 | fi 82 | 83 | exit_if_last_error 84 | cp $UBOOT_BIN_NAME $OUTFILE_boot_bin 85 | } -------------------------------------------------------------------------------- /scripts/menu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | menustr="walnutpi-build" 4 | backtitle="Walnut Pi building script" 5 | 6 | 7 | # 继续你的脚本逻辑 8 | show_menu() { 9 | local title="$1" 10 | shift 11 | local options=("$@") 12 | TTY_X=$(($(stty size | awk '{print $2}')-6)) # determine terminal width 13 | TTY_Y=$(($(stty size | awk '{print $1}')-6)) # determine terminal height 14 | TTY_Y_WINDOW=$((TTY_Y - 8)) 15 | if [ "$TTY_X" -le 0 ] || [ "$TTY_Y" -le 0 ] || [ "$TTY_Y_WINDOW" -le 0 ]; then 16 | echo -e "Error: Your terminal is too small \n" 17 | exit 1 18 | fi 19 | whiptail --title "${title}" --backtitle "${backtitle}" --notags \ 20 | --menu "${menustr}" "${TTY_Y}" "${TTY_X}" ${TTY_Y_WINDOW} \ 21 | --cancel-button Exit --ok-button Select "${options[@]}" \ 22 | 3>&1 1>&2 2>&3 23 | 24 | } 25 | 26 | MENU_choose_board() { 27 | # 获取路径下所有文件夹名作为选项 28 | local path_board_list=$1 29 | dirs=$(find ${path_board_list} -mindepth 1 -maxdepth 1 -type d) 30 | local options=() 31 | for dir in $dirs; do 32 | dirname=$(basename "$dir") 33 | options+=("$dir" "$dirname") 34 | done 35 | local titlestr="Choose Board" 36 | show_menu "${titlestr}" "${options[@]}" 37 | } 38 | 39 | MENU_sikp_boot(){ 40 | local titlestr="recompile the bootloader ?" 41 | local options=( 42 | "$OPT_NO" "no" 43 | "$OPT_YES" "yes" 44 | ) 45 | show_menu "${titlestr}" "${options[@]}" 46 | } 47 | 48 | MENU_sikp_kernel(){ 49 | local titlestr="recompile the KERNEL ?" 50 | local options=( 51 | "$OPT_NO" "no" 52 | "$OPT_YES" "yes" 53 | ) 54 | show_menu "${titlestr}" "${options[@]}" 55 | } 56 | 57 | 58 | MENU_choose_os() { 59 | # 只测试了bookworm的软件兼容性问题,有些库不确定能不能在旧版debian上运行 60 | titlestr="Choose an os version" 61 | local options=( 62 | ${OPT_os_debian12} "debian 12(bookworm)" 63 | ${OPT_os_debian11} "debian 11(bullseye)" 64 | ${OPT_os_ubuntu22} "ubuntu 22.04(Jammy Jellyfish)" 65 | ${OPT_os_ubuntu24} "ubuntu 24.04(Noble Numbat)" 66 | ${OPT_os_debian12_burn} "emmc burner(debian 12)" 67 | ) 68 | show_menu "${titlestr}" "${options[@]}" 69 | } 70 | 71 | MENU_choose_rootfs_type() { 72 | titlestr="Server or Graphics" 73 | options+=("$OPT_rootfs_server" "server") 74 | options+=("$OPT_rootfs_desktop" "desktop") 75 | show_menu "${titlestr}" "${options[@]}" 76 | } 77 | 78 | MENU_choose_img_file() { 79 | titlestr="choose an img file" 80 | for file in $PATH_OUTPUT/*.img; do 81 | local creation_time=$(stat -c %Y "$file") 82 | options+=("$creation_time:$file") 83 | done 84 | 85 | IFS=$'\n' sorted_options=($(for item in "${options[@]}"; do echo "$item"; done | sort -r | cut -d: -f2)) 86 | unset IFS 87 | 88 | options=() 89 | for file in "${sorted_options[@]}"; do 90 | local name=$(basename "$file") 91 | options+=("$name" "$name") 92 | done 93 | 94 | show_menu "${titlestr}" "${options[@]}" 95 | } 96 | -------------------------------------------------------------------------------- /board/walnutpi-1b/boot.cmd: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE 2 | 3 | if mmc dev 1; then 4 | mmc dev 0 5 | gpio clear 71 6 | else 7 | gpio clear 77 8 | fi 9 | 10 | # default values 11 | setenv load_addr "0x45000000" 12 | setenv overlay_error "false" 13 | setenv rootdev "/dev/mmcblk1p2" 14 | setenv rootfstype "ext4" 15 | setenv console "both" 16 | setenv docker_optimizations "on" 17 | setenv bootlogo "false" 18 | 19 | # Print boot source 20 | itest.b *0x10028 == 0x00 && echo "U-boot loaded from SD" 21 | itest.b *0x10028 == 0x02 && echo "U-boot loaded from eMMC or secondary SD" 22 | itest.b *0x10028 == 0x03 && echo "U-boot loaded from SPI" 23 | 24 | echo "Boot script loaded from ${devtype}" 25 | 26 | if test -e ${devtype} ${devnum} ${prefix}config.txt; then 27 | load ${devtype} ${devnum} ${load_addr} ${prefix}config.txt 28 | env import -t ${load_addr} ${filesize} 29 | fi 30 | if test "${display_bootinfo}" = "enable"; then setenv consoleargs_diplay "console=tty0"; fi 31 | 32 | if test "${console_uart}" = "uart0"; then setenv consoleargs "console=ttyS0,115200"; fi 33 | if test "${console_uart}" = "uart1"; then setenv consoleargs "console=ttyS1,115200"; fi 34 | if test "${console_uart}" = "uart2"; then setenv consoleargs "console=ttyS2,115200"; fi 35 | if test "${console_uart}" = "uart3"; then setenv consoleargs "console=ttyS3,115200"; fi 36 | if test "${console_uart}" = "uart4"; then setenv consoleargs "console=ttyS4,115200"; fi 37 | if test "${console_uart}" = "null"; then setenv consoleargs "console=/dev/null"; fi 38 | 39 | if test "${bootlogo}" = "true"; then 40 | setenv consoleargs "splash plymouth.ignore-serial-consoles ${consoleargs}" 41 | else 42 | setenv consoleargs "splash=verbose ${consoleargs}" 43 | fi 44 | 45 | # get PARTUUID of first partition on SD/eMMC it was loaded from 46 | # mmc 0 is always mapped to device u-boot (2016.09+) was loaded from 47 | if test "${devtype}" = "mmc"; then part uuid mmc 0:1 partuuid; fi 48 | 49 | setenv bootargs "root=${rootdev} rootwait rw rootfstype=${rootfstype} net.ifnames=0 ${consoleargs} ${consoleargs_diplay}, consoleblank=0 loglevel=${printk_level} ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}" 50 | 51 | if test "${docker_optimizations}" = "on"; then setenv bootargs "${bootargs} cgroup_enable=memory swapaccount=1"; fi 52 | 53 | if mmc dev 1; then 54 | echo "board has emmc" 55 | mmc dev 0 56 | load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}${fdtfile_emmc}.dtb 57 | else 58 | echo "board not emmc" 59 | load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}${fdtfile}.dtb 60 | fi 61 | 62 | 63 | fdt addr ${fdt_addr_r} 64 | fdt resize 65536 65 | for overlay_file in ${overlays}; do 66 | if load ${devtype} ${devnum} ${load_addr} ${prefix}overlays/${overlay_prefix}-${overlay_file}.dtbo; then 67 | echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo" 68 | fdt apply ${load_addr} || setenv overlay_error "true" 69 | fi 70 | done 71 | for overlay_file in ${user_overlays}; do 72 | if load ${devtype} ${devnum} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then 73 | echo "Applying user provided DT overlay ${overlay_file}.dtbo" 74 | fdt apply ${load_addr} || setenv overlay_error "true" 75 | fi 76 | done 77 | if test "${overlay_error}" = "true"; then 78 | echo "Error applying DT overlays, restoring original DT" 79 | load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}${fdtfile}.dtb 80 | else 81 | if load ${devtype} ${devnum} ${load_addr} ${prefix}overlays/${overlay_prefix}-fixup.scr; then 82 | echo "Applying kernel provided DT fixup script (${overlay_prefix}-fixup.scr)" 83 | source ${load_addr} 84 | fi 85 | if test -e ${devtype} ${devnum} ${prefix}fixup.scr; then 86 | load ${devtype} ${devnum} ${load_addr} ${prefix}fixup.scr 87 | echo "Applying user provided fixup script (fixup.scr)" 88 | source ${load_addr} 89 | fi 90 | fi 91 | 92 | load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}Image 93 | 94 | if test ${bootlogo} = true; then 95 | if test -e ${devtype} ${devnum} ${prefix}uInitrd; then 96 | load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd 97 | booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} 98 | else 99 | booti ${kernel_addr_r} - ${fdt_addr_r} 100 | fi 101 | else 102 | booti ${kernel_addr_r} - ${fdt_addr_r} 103 | fi 104 | 105 | 106 | # Recompile with: 107 | # mkimage -C none -A arm -T script -d boot.cmd boot.scr -------------------------------------------------------------------------------- /scripts/pack_boot_deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 获取文件所在路径 3 | 4 | _pack_as_boot_deb(){ 5 | local path_package=$1 6 | local part_name=$2 7 | local package_desc=$3 8 | local BOARD_NAME=$4 9 | local SYTERKIT_BRANCH=$5 10 | local UBOOT_BRANCH=$6 11 | local ENTER_board_name=$7 12 | local OUTDIR_boot_package=$8 13 | local CHIP_ARCH=$9 14 | 15 | local package_name="$part_name-${BOARD_NAME}-${SYTERKIT_BRANCH}${UBOOT_BRANCH}" 16 | local control_file=$path_package/DEBIAN/control 17 | 18 | if [ ! -d $path_package/DEBIAN ];then 19 | mkdir -p $path_package/DEBIAN 20 | fi 21 | 22 | # 读取版本信息 23 | source ${ENTER_board_name}/config.txt 24 | local deb_version="$version" 25 | 26 | cd $path_package 27 | local size=$(du -sk --exclude=DEBIAN . | cut -f1) 28 | 29 | cat << EOF > $control_file 30 | Package: ${package_name} 31 | Description: ${package_desc} 32 | Maintainer: walnutpi-build 33 | Version: ${deb_version} 34 | Section: free 35 | Priority: optional 36 | Installed-Size: ${size} 37 | Architecture: ${CHIP_ARCH} 38 | EOF 39 | local DEB_PACKAGE_NAME="${package_name}_${deb_version}_${CHIP_ARCH}.deb" 40 | echo "创建deb包 ${DEB_PACKAGE_NAME}" 41 | dpkg-deb -Zgzip -b "$path_package" "${OUTDIR_boot_package}/${DEB_PACKAGE_NAME}" 42 | } 43 | 44 | # 打包config.txt文件 45 | # $1: PATH_TMP - 临时目录路径 46 | # $2: ENTER_board_name - 板子配置目录路径 47 | # $3: OUTDIR_boot_package - 输出目录 48 | # $4: CHIP_ARCH - 芯片架构 49 | pack_config_txt() { 50 | local PATH_TMP=$1 51 | local ENTER_board_name=$2 52 | local OUTDIR_boot_package=$3 53 | local CHIP_ARCH=$4 54 | 55 | local path_tmp_package_configtxt="${PATH_TMP}/boot-configtxt-$(basename ${ENTER_board_name})" 56 | if [ -d $path_tmp_package_configtxt ]; then 57 | rm -r $path_tmp_package_configtxt 58 | fi 59 | mkdir -p $path_tmp_package_configtxt 60 | 61 | local path_board_tmp_boot="/tmp-boot/boot-configtxt" 62 | local path_tmp_boot=${path_tmp_package_configtxt}${path_board_tmp_boot} 63 | mkdir -p $path_tmp_boot 64 | 65 | cp ${ENTER_board_name}/config.txt $path_tmp_boot 66 | 67 | local postinst_file=$path_tmp_package_configtxt/DEBIAN/postinst 68 | if [ ! -d $path_tmp_package_configtxt/DEBIAN ];then 69 | mkdir $path_tmp_package_configtxt/DEBIAN 70 | fi 71 | 72 | cat << EOF > $postinst_file 73 | #!/bin/sh 74 | case "\$1" in 75 | configure) 76 | old_version="\$2" 77 | new_version="\$3" 78 | echo "Updating from version \$old_version to version \$new_version" 79 | 80 | cp -r $path_board_tmp_boot/* /boot/ 81 | set-device 82 | 83 | BLOCK_DEVICE=\$(findmnt "/" -o SOURCE -n) 84 | ROOTFS_PARTUUID=\$(blkid -s PARTUUID -o value \$BLOCK_DEVICE) 85 | if [ -z "\$ROOTFS_PARTUUID" ]; then 86 | echo "无法解析出uuid" 87 | exit 88 | fi 89 | echo "rootdev=PARTUUID=\${ROOTFS_PARTUUID}" | sudo tee -a /boot/config.txt 90 | 91 | ;; 92 | abort-upgrade|abort-remove|abort-deconfigure) 93 | # 回滚操作 94 | ;; 95 | 96 | esac 97 | exit 0 98 | EOF 99 | 100 | chmod 755 $postinst_file 101 | 102 | source ${ENTER_board_name}/config.txt 103 | local BOARD_NAME_VAR="$BOARD_NAME" 104 | local SYTERKIT_BRANCH_VAR="$SYTERKIT_BRANCH" 105 | local UBOOT_BRANCH_VAR="$UBOOT_BRANCH" 106 | 107 | _pack_as_boot_deb $path_tmp_package_configtxt "configtxt" "config.txt for boot" \ 108 | "$BOARD_NAME_VAR" "$SYTERKIT_BRANCH_VAR" "$UBOOT_BRANCH_VAR" \ 109 | "$ENTER_board_name" "$OUTDIR_boot_package" "$CHIP_ARCH" 110 | } 111 | 112 | 113 | pack_boot_bin() { 114 | local PATH_TMP=$1 115 | local ENTER_board_name=$2 116 | local OUTFILE_boot_bin=$3 117 | local PATH_save_boot_files=$4 118 | local OUTDIR_boot_package=$5 119 | local CHIP_ARCH=$6 120 | 121 | local path_tmp_package_configtxt="${PATH_TMP}/boot-bin-$(basename ${ENTER_board_name})" 122 | if [ -d $path_tmp_package_configtxt ]; then 123 | rm -r $path_tmp_package_configtxt 124 | fi 125 | mkdir -p $path_tmp_package_configtxt 126 | 127 | local path_board_tmp_boot="/tmp-boot/boot" 128 | local path_tmp_boot=${path_tmp_package_configtxt}${path_board_tmp_boot} 129 | mkdir -p $path_tmp_boot 130 | 131 | # 复制文件(如果存在) 132 | [ -f "${ENTER_board_name}/boot.cmd" ] && cp ${ENTER_board_name}/boot.cmd $path_tmp_boot 133 | [ -f "${ENTER_board_name}/boot.scr" ] && cp ${ENTER_board_name}/boot.scr $path_tmp_boot 134 | [ -f "${OUTFILE_boot_bin}" ] && cp ${OUTFILE_boot_bin} $path_tmp_boot 135 | 136 | # 装入本项目保存的bin文件 137 | if [ -d $PATH_save_boot_files ]; then 138 | cp -r $PATH_save_boot_files/* $path_tmp_boot 139 | fi 140 | 141 | local postinst_file=$path_tmp_package_configtxt/DEBIAN/postinst 142 | mkdir -p $path_tmp_package_configtxt/DEBIAN 143 | 144 | cat << EOF > $postinst_file 145 | #!/bin/sh 146 | case "\$1" in 147 | configure) 148 | old_version="\$2" 149 | new_version="\$3" 150 | echo "Updating from version \$old_version to version \$new_version" 151 | cp -r $path_board_tmp_boot/* /boot/ 152 | 153 | BLOCK_DEVICE=\$(findmnt "/boot" -o SOURCE -n) 154 | echo "BLOCK_DEVICE=\$BLOCK_DEVICE" 155 | BASE_DEVICE=\$(echo "\$BLOCK_DEVICE" | sed -E 's/p[0-9]+\$//') 156 | if [ -z "\$BASE_DEVICE" ]; then 157 | echo "无法解析出块设备路径" 158 | exit 159 | fi 160 | dd_command="dd if=/boot/boot.bin of=\$BASE_DEVICE bs=1K seek=8 conv=notrunc" 161 | echo "\$dd_command" 162 | eval \$dd_command 163 | ;; 164 | abort-upgrade|abort-remove|abort-deconfigure) 165 | # 回滚操作 166 | ;; 167 | *) 168 | exit 1 169 | ;; 170 | esac 171 | 172 | exit 0 173 | EOF 174 | chmod 755 $postinst_file 175 | 176 | # 从config.txt中读取BOARD_NAME, SYTERKIT_BRANCH, UBOOT_BRANCH 177 | source ${ENTER_board_name}/config.txt 178 | local BOARD_NAME_VAR="$BOARD_NAME" 179 | local SYTERKIT_BRANCH_VAR="$SYTERKIT_BRANCH" 180 | local UBOOT_BRANCH_VAR="$UBOOT_BRANCH" 181 | 182 | _pack_as_boot_deb $path_tmp_package_configtxt "bootbin" "the boot bin" \ 183 | "$BOARD_NAME_VAR" "$SYTERKIT_BRANCH_VAR" "$UBOOT_BRANCH_VAR" \ 184 | "$ENTER_board_name" "$OUTDIR_boot_package" "$CHIP_ARCH" 185 | } 186 | 187 | # 打包boot相关的deb包 188 | # 参数说明: 189 | # $1: PATH_TMP - 临时目录路径 190 | # $2: ENTER_board_name - 板子配置目录路径 191 | # $3: OUTFILE_boot_bin - boot.bin文件路径 192 | # $4: PATH_save_boot_files - 保存的boot文件目录 193 | # $5: OUTDIR_boot_package - 输出目录 194 | # $6: CHIP_ARCH - 芯片架构 195 | pack_boot_deb(){ 196 | local PATH_TMP=$1 197 | local ENTER_board_name=$2 198 | local OUTFILE_boot_bin=$3 199 | local PATH_save_boot_files=$4 200 | local OUTDIR_boot_package=$5 201 | local CHIP_ARCH=$6 202 | 203 | pack_config_txt "$PATH_TMP" "$ENTER_board_name" "$OUTDIR_boot_package" "$CHIP_ARCH" 204 | pack_boot_bin "$PATH_TMP" "$ENTER_board_name" "$OUTFILE_boot_bin" "$PATH_save_boot_files" "$OUTDIR_boot_package" "$CHIP_ARCH" 205 | } -------------------------------------------------------------------------------- /scripts/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 获取sudo运行脚本前是什么用户,然后以那个用户的权限执行指令 4 | run_as_user() { 5 | local original_user=$(who am i | awk '{print $1}') 6 | if [ -z $original_user ]; then 7 | bash -c "$*" 8 | else 9 | sudo -u $original_user bash -c "$*" 10 | fi 11 | } 12 | exit_if_last_error() { 13 | if [[ $? -ne 0 ]]; then 14 | echo "上一条命令执行失败,脚本将退出。" 15 | exit 1 16 | fi 17 | } 18 | 19 | run_as_silent() { 20 | $@ >/dev/null 2>&1 21 | } 22 | 23 | run_slient_when_successfuly() { 24 | local output 25 | output=$("$@" 2>&1) 26 | local exit_status=$? 27 | if [ $exit_status -ne 0 ]; then 28 | echo "$output" 29 | fi 30 | } 31 | 32 | create_dir() { 33 | local directory_path=$1 34 | if [ ! -d "$directory_path" ]; then 35 | mkdir -p "$directory_path" 36 | fi 37 | } 38 | 39 | # 需要定义一个LOG_FILE变量指向log文件 40 | log_record() { 41 | # echo "$(date +%Y-%m-%d_%H:%M:%S) $*" >> $LOG_FILE 42 | echo -e "[$(date +%M:%S)]$@" >>$LOG_FILE 43 | } 44 | 45 | run_status() { 46 | local message=$1 47 | shift 48 | local max_retries=5 49 | local retry_delay=5 50 | local retries=0 51 | local start_time=$(date +%s) 52 | 53 | while [ $retries -lt $max_retries ]; do 54 | echo -e -n "...\t$message" 55 | local output 56 | output=$("$@" 2>&1) 57 | local exit_status=$? 58 | log_record $output 59 | if [ $exit_status -ne 0 ]; then 60 | echo -e "\r\033[31m[error]\033[0m" 61 | echo -e "$output" 62 | echo -e "Retrying in $retry_delay seconds..." 63 | sleep $retry_delay 64 | retry_delay=$((retry_delay + 5)) 65 | ((retries++)) 66 | log_record "[error]\t${message}" 67 | else 68 | local end_time=$(date +%s) 69 | local duration=$((end_time - start_time)) 70 | echo -e "\r\033[32m[ok]\033[0m\t${message}\t${duration}s" 71 | log_record "[ok]\t${message}\t${duration}s" 72 | break 73 | fi 74 | done 75 | 76 | if [ $retries -eq $max_retries ]; then 77 | echo -e "\r\033[31m[error]\033[0m\t$message - Maximum retries reached." 78 | exit $exit_status 79 | fi 80 | } 81 | 82 | run_status_no_retry() { 83 | local message=$1 84 | shift 85 | local start_time=$(date +%s) 86 | 87 | echo -e -n "...\t$message" 88 | local output 89 | output=$("$@" 2>&1) 90 | local exit_status=$? 91 | if [ $exit_status -ne 0 ]; then 92 | echo -e "\r\033[31m[error]\033[0m" 93 | echo -e "$output" 94 | else 95 | local end_time=$(date +%s) 96 | local duration=$((end_time - start_time)) 97 | echo -e "\r\033[32m[ok]\033[0m\t${message}\t${duration}s" 98 | fi 99 | 100 | } 101 | 102 | mount_chroot() { 103 | local target=$1 104 | mount -t proc chproc "${target}"/proc 105 | mount -t sysfs chsys "${target}"/sys 106 | mount -t devtmpfs chdev "${target}"/dev || mount --bind /dev "${target}"/dev 107 | mount -t devpts chpts "${target}"/dev/pts 108 | } 109 | 110 | umount_chroot() { 111 | local target=$1 112 | while grep -Eq "${target}.*(dev|proc|sys)" /proc/mounts; do 113 | umount -l --recursive "${target}"/dev >/dev/null 2>&1 114 | umount -l "${target}"/proc >/dev/null 2>&1 115 | umount -l "${target}"/sys >/dev/null 2>&1 116 | sleep 5 117 | done 118 | } 119 | 120 | # 卸载指定挂载点 121 | unmount_point() { 122 | local mount_point=$1 123 | if mountpoint -q "$mount_point"; then 124 | echo "Unmounting $mount_point" 125 | while mountpoint -q "$mount_point"; do 126 | umount "$mount_point" 127 | sleep 1 128 | done 129 | fi 130 | } 131 | 132 | clone_url() { 133 | local git_url="$1" 134 | local dir_name=$(basename "$git_url" .git) 135 | 136 | if [ -d "$dir_name" ]; then 137 | cd "$dir_name" 138 | run_as_user git config --global --add safe.directory $(pwd) 139 | echo "pull : $git_url" 140 | run_as_user git pull 141 | else 142 | echo "clone : $git_url" 143 | run_as_user git clone $git_url 144 | fi 145 | } 146 | clone_branch() { 147 | local git_url="$1" 148 | local branch="$2" 149 | 150 | local dir_name=$(basename "$git_url" .git) 151 | [[ -n $3 ]] && dir_name=$3 152 | 153 | if [ -d "$dir_name" ]; then 154 | cd "$dir_name" 155 | run_as_user git config --global --add safe.directory $(pwd) 156 | echo "pull : $git_url" 157 | run_as_user git pull 158 | else 159 | echo "clone : $git_url" 160 | run_as_user git clone -b $branch --depth 1 $git_url $dir_name 161 | fi 162 | } 163 | 164 | cp_file_if_exsit() { 165 | local file_path_source=$1 166 | local file_path_desc=$2 167 | if [ -f $file_path_source ]; then 168 | cp $file_path_source $file_path_desc 169 | fi 170 | } 171 | replace_in_file() { 172 | local file_path=$1 173 | local search_string=$2 174 | local replace_string=$3 175 | 176 | if [ ! -f "$file_path" ]; then 177 | echo "文件 $file_path 不存在。" 178 | return 1 179 | fi 180 | 181 | # 使用sed进行替换 182 | sed -i "s/$search_string/$replace_string/g" "$file_path" 183 | exit_if_last_error "替换字符串失败: $search_string -> $replace_string 在文件 $file_path" 184 | } 185 | 186 | # 生成deb包需要的postinst文件,功能是在安装时复制指定的文件到指定路径 187 | _gen_postinst_cp_file() { 188 | local path_package=$1 189 | local source_path=$2 190 | local target_path=$3 191 | postinst_file=$path_package/DEBIAN/postinst 192 | if [ ! -d $path_package/DEBIAN ]; then 193 | mkdir $path_package/DEBIAN 194 | fi 195 | cat <$postinst_file 196 | #!/bin/sh 197 | set -e 198 | case "\$1" in 199 | configure) 200 | old_version="\$2" 201 | new_version="\$3" 202 | echo "Updating from version $old_version to version $new_version" 203 | 204 | cp -r $source_path/* $target_path 205 | 206 | ;; 207 | abort-upgrade|abort-remove|abort-deconfigure) 208 | # 回滚操作 209 | ;; 210 | *) 211 | exit 1 212 | ;; 213 | esac 214 | 215 | EOF 216 | chmod 755 $postinst_file 217 | } 218 | 219 | # 获取linux版本号,如5.15.147 6.1.9 220 | # 参数说明: 221 | # $1 - src_dir: Linux 源码项目的位置 222 | get_linux_version() { 223 | local src_dir=$1 224 | 225 | if [[ ! -d "$src_dir" ]]; then 226 | echo "目录不存在: $src_dir" 227 | return 1 228 | fi 229 | 230 | local makefile="$src_dir/Makefile" 231 | if [[ ! -f "$makefile" ]]; then 232 | echo "在目录中找不到 Makefile: $src_dir" 233 | return 1 234 | fi 235 | 236 | local version=$(grep -E '^VERSION = ' "$makefile" | cut -d ' ' -f 3) 237 | local patchlevel=$(grep -E '^PATCHLEVEL = ' "$makefile" | cut -d ' ' -f 3) 238 | local sublevel=$(grep -E '^SUBLEVEL = ' "$makefile" | cut -d ' ' -f 3) 239 | local extraversion=$(grep -E '^EXTRAVERSION = ' "$makefile" | cut -d ' ' -f 3) 240 | echo "$version.$patchlevel.$sublevel$extraversion" 241 | } 242 | 243 | # 安全删除临时目录函数,防止误删系统关键目录 244 | safe_remove_tmp_dir() { 245 | local dir_path=$1 246 | 247 | if [ -z "$dir_path" ] || [ "$dir_path" = "/" ]; then 248 | echo "错误: 尝试删除无效路径: $dir_path" 249 | return 1 250 | fi 251 | if [[ "$dir_path" != *"/tmp/"* && "$dir_path" != *".tmp/"* && "$dir_path" != *"/tmp."* ]]; then 252 | echo "错误: 尝试删除非临时目录: $dir_path" 253 | return 1 254 | fi 255 | if [ -d "$dir_path" ]; then 256 | echo "删除临时目录: $dir_path" 257 | rm -r "$dir_path" 258 | return 0 259 | else 260 | echo "目录不存在,无需删除: $dir_path" 261 | return 0 262 | fi 263 | } 264 | 265 | 266 | -------------------------------------------------------------------------------- /scripts/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IMAGE_FLAG_NO_SCREEN_DISPLAY=$OPT_NO 4 | IMAGE_FLAG_DISK_RAED_ONLY=$OPT_NO 5 | 6 | 7 | PART1_SIZE=150 8 | PART2_SIZE=0 9 | 10 | 11 | exit_if_file_no_exsit() { 12 | if [ ! -f "$1" ]; then 13 | echo $1 "no exist" 14 | exit 1 15 | fi 16 | } 17 | 18 | # 检查所需文件是不是都生成了 19 | check_resource() { 20 | if [ ! -d "$OUTDIR_boot_package" ]; then 21 | echo $OUTDIR_boot_package "no exist" 22 | exit 23 | fi 24 | if [ ! -d "$OUTDIR_kernel_package" ]; then 25 | echo $OUTDIR_kernel_package "no exist" 26 | exit 27 | fi 28 | if [ ! -f "$OUTFILE_rootfs_tar" ]; then 29 | echo $OUTFILE_rootfs_tar "no exist" 30 | exit 31 | fi 32 | } 33 | 34 | 35 | 36 | build_image() { 37 | # 如果$1不为空 38 | NEW_IMG_FILE_NAME=$1 39 | 40 | cleanup() { 41 | local LOOP_DEVICE=$1 42 | echo "Cleaning up..." 43 | cd $PATH_PROJECT_DIR 44 | unmount_point "$TMP_mount_disk2/boot" 45 | unmount_point "$TMP_IMG_DISK2" 46 | unmount_point "$TMP_mount_disk1" 47 | unmount_point "$TMP_mount_disk2" 48 | 49 | if [ ! -z "$LOOP_DEVICE" ]; then 50 | if losetup -l > /dev/null 2>&1; then 51 | while losetup -l | grep -q "$LOOP_DEVICE"; do 52 | echo "Releasing loop device $LOOP_DEVICE" 53 | kpartx -dv "$LOOP_DEVICE" 54 | losetup -d "$LOOP_DEVICE" 55 | sleep 1 56 | done 57 | fi 58 | fi 59 | } 60 | 61 | trap 'cleanup "$LOOP_DEVICE"; exit' SIGINT 62 | check_resource 63 | # 使用安全函数删除临时目录 64 | if [ -n "$TMP_IMG_DISK2" ] && [ "$TMP_IMG_DISK2" != "/" ]; then 65 | safe_remove_tmp_dir "$TMP_IMG_DISK2" 66 | else 67 | echo "警告: TMP_IMG_DISK2变量未正确设置,跳过清理操作" 68 | echo "TMP_IMG_DISK2 = $TMP_IMG_DISK2" 69 | fi 70 | 71 | if [ -n "$TMP_mount_disk1" ] && [ "$TMP_mount_disk1" != "/" ]; then 72 | safe_remove_tmp_dir "$TMP_mount_disk1" 73 | else 74 | echo "警告: TMP_mount_disk1变量未正确设置,跳过清理操作" 75 | echo "TMP_mount_disk1 = $TMP_mount_disk1" 76 | fi 77 | 78 | if [ -n "$TMP_mount_disk2" ] && [ "$TMP_mount_disk2" != "/" ]; then 79 | safe_remove_tmp_dir "$TMP_mount_disk2" 80 | else 81 | echo "警告: TMP_mount_disk2变量未正确设置,跳过清理操作" 82 | echo "TMP_mount_disk2 = $TMP_mount_disk2" 83 | fi 84 | 85 | mkdir -p $TMP_IMG_DISK2 86 | mkdir -p $TMP_IMG_DISK2/boot 87 | mkdir -p $TMP_mount_disk1 88 | mkdir -p $TMP_mount_disk2 89 | 90 | cd ${PATH_SOURCE}/wpi-update 91 | echo -n "$BOARD_MODEL" > /tmp/walnutpi-board_model 92 | VERSION_APT=$(echo $(./wpi-update -s | tail -n 1 )) 93 | reload_env 94 | if [ -f "$OUT_IMG_FILE" ]; then 95 | rm ${OUT_IMG_FILE} 96 | fi 97 | # 创建img文件 98 | if [ -f "$TMP_IMG_DISK1" ];then 99 | rm ${TMP_IMG_DISK1} 100 | fi 101 | run_status "create part1 file" dd if=/dev/zero of=$TMP_IMG_DISK1 bs=1M count=$PART1_SIZE 102 | 103 | # 格式化文件TMP_IMG_DISK1为fat32,并挂载到路径 ${TMP_IMG_DISK2}/boot 104 | run_status "format part1 file" mkfs.fat -F 32 -n "boot" $TMP_IMG_DISK1 105 | run_status "mount part1 file" mount -o loop $TMP_IMG_DISK1 ${TMP_IMG_DISK2}/boot 106 | 107 | 108 | run_status "add rootfs" tar xf $OUTFILE_rootfs_tar -C $TMP_IMG_DISK2 -I 'xz -T0' 109 | 110 | # 安装boot相关的deb包 111 | cp ${OUTDIR_boot_package}/*.deb ${TMP_IMG_DISK2}/opt/ 112 | cd ${TMP_IMG_DISK2}/opt/ 113 | deb_packages=(*.deb) 114 | total=${#deb_packages[@]} 115 | for (( i=0; i<$total; i++ )); do 116 | deb_package=${deb_packages[$i]} 117 | run_status "boot package [$((i+1))/${total}] : ${deb_package} " chroot ${TMP_IMG_DISK2} /bin/bash -c "dpkg -i /opt/${deb_package}" 118 | rm ${TMP_IMG_DISK2}/opt/${deb_package} 119 | done 120 | 121 | # 安装kernel产生的的deb包,先安装生成时间早的 122 | cd ${OUTDIR_kernel_package}/ 123 | deb_packages=($(ls -t *.deb | tac)) 124 | cp ${OUTDIR_kernel_package}/*.deb ${TMP_IMG_DISK2}/opt/ 125 | cd ${TMP_IMG_DISK2}/opt/ 126 | total=${#deb_packages[@]} 127 | for (( i=0; i<$total; i++ )); do 128 | deb_package=${deb_packages[$i]} 129 | run_status "kernel package [$((i+1))/${total}] : ${deb_package} " chroot ${TMP_IMG_DISK2} /bin/bash -c "dpkg -i /opt/${deb_package}" 130 | rm ${TMP_IMG_DISK2}/opt/${deb_package} 131 | done 132 | 133 | run_status "run set-lcd hdmi install " chroot ${TMP_IMG_DISK2} /bin/bash -c "set-lcd hdmi install" 134 | if [ -f ${FILE_apt_del} ]; then 135 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_apt_del}) 136 | total=${#packages[@]} 137 | for (( i=0; i<${total}; i++ )); do 138 | package=${packages[$i]} 139 | run_status "apt remove [$((i+1))/${total}] : $package " chroot $TMP_IMG_DISK2 /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' remove -y ${package}" 140 | done 141 | fi 142 | 143 | # 如果是ubuntu24,则禁用gdm3改为lightdm 144 | if [ "$ENTER_os_ver" == "$OPT_os_ubuntu24" ];then 145 | if [[ "${ENTER_rootfs_type}" == "desktop" ]]; then 146 | echo "切换lightdm为默认桌面环境" 147 | run_status "remove gdm3 " chroot ${TMP_IMG_DISK2} /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' remove -y gdm3" 148 | chroot $TMP_IMG_DISK2 /bin/bash -c "dpkg-reconfigure lightdm" 149 | fi 150 | fi 151 | 152 | local ROOTFS_SIZE=$(du -sm $TMP_IMG_DISK2 | cut -f1) 153 | local PART2_SIZE=$(echo "scale=0; ($ROOTFS_SIZE * 1.024 + 10)/1" | bc) 154 | 155 | echo "PART1_SIZE=${PART1_SIZE}MB" 156 | echo "PART2_SIZE=${PART2_SIZE}MB" 157 | 158 | # 创建img文件 159 | IMG_SIZE=$((PART1_SIZE + PART2_SIZE + 2 )) 160 | run_status "create img file: $OUT_IMG_FILE $IMG_SIZE MB" dd if=/dev/zero of=$OUT_IMG_FILE bs=1M count=$IMG_SIZE 161 | 162 | # 创建分区 163 | echo "创建分区" 164 | parted $OUT_IMG_FILE --script mklabel msdos 165 | parted $OUT_IMG_FILE --script mkpart primary fat32 1M $((PART1_SIZE + 1))M 166 | parted $OUT_IMG_FILE --script mkpart primary ext4 $((PART1_SIZE + 1))M 100% 167 | parted $OUT_IMG_FILE set 1 boot on 168 | 169 | LOOP_DEVICE=$(sudo losetup -f) 170 | 171 | losetup $LOOP_DEVICE $OUT_IMG_FILE 172 | kpartx -av $LOOP_DEVICE 173 | 174 | # 挂载镜像文件 175 | MAPPER_DEVICE=$(echo $LOOP_DEVICE | sed 's/\/dev\///' | sed 's/\//p/') 176 | MAPPER_DEVICE1="/dev/mapper/${MAPPER_DEVICE}p1" 177 | MAPPER_DEVICE2="/dev/mapper/${MAPPER_DEVICE}p2" 178 | echo "MAPPER_DEVICE=${MAPPER_DEVICE}" 179 | 180 | # echo "开始格式化" 181 | run_status "format part 1" mkfs.vfat $MAPPER_DEVICE1 182 | run_status "format part 2" mkfs.ext4 $MAPPER_DEVICE2 183 | 184 | 185 | BOOT_UUID=$(blkid -s UUID -o value $MAPPER_DEVICE1) 186 | BOOT_PARTUUID=$(blkid -s PARTUUID -o value $MAPPER_DEVICE1) 187 | ROOTFS_UUID=$(blkid -s UUID -o value $MAPPER_DEVICE2) 188 | ROOTFS_PARTUUID=$(blkid -s PARTUUID -o value $MAPPER_DEVICE2) 189 | 190 | # 挂载两个分区 191 | mount $MAPPER_DEVICE1 $TMP_mount_disk1 192 | mount $MAPPER_DEVICE2 $TMP_mount_disk2 193 | if [ ! -d $TMP_mount_disk2/boot ]; then 194 | mkdir -p $TMP_mount_disk2/boot 195 | fi 196 | mount $MAPPER_DEVICE1 $TMP_mount_disk2/boot 197 | 198 | # 导入文件 199 | run_status "add $BOOTLOADER_NAME" dd if=$OUTFILE_boot_bin of=$OUT_IMG_FILE bs=1K seek=8 conv=notrunc 200 | # 使用tar将 TMP_IMG_DISK2 路径下的文件全部原封不动的导到TMP_mount_disk2下 201 | echo "move the rootfs files into the image" 202 | tar -cf - -C "$TMP_IMG_DISK2" . | tar -xf - -C "$TMP_mount_disk2" 203 | # run_status "add rootfs" tar -cf - -C "$TMP_IMG_DISK2" . | tar -xf - -C "$TMP_mount_disk2" 204 | 205 | # 写入uuid 206 | echo "rootdev=PARTUUID=${ROOTFS_PARTUUID}" | sudo tee -a ${TMP_mount_disk1}/config.txt 207 | if [ $IMAGE_FLAG_NO_SCREEN_DISPLAY == $OPT_NO ];then 208 | echo "PARTUUID=${ROOTFS_PARTUUID} / ext4 defaults,acl,noatime,commit=600,errors=remount-ro 0 1" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 209 | else 210 | echo "PARTUUID=${ROOTFS_PARTUUID} / ext4 ro,defaults,acl,noatime,commit=600,errors=remount-ro 0 1" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 211 | 212 | fi 213 | echo "PARTUUID=${BOOT_PARTUUID} /boot vfat defaults 0 0" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 214 | 215 | if [ $IMAGE_FLAG_NO_SCREEN_DISPLAY != $OPT_NO ];then 216 | 217 | config_file="${TMP_mount_disk1}/config.txt" 218 | run_status "config.txt : console_display=disable" sed -i 's/console_display=enable/console_display=disable/g' "$config_file" 219 | run_status "config.txt : display_bootinfo=disable" sed -i 's/display_bootinfo=enable/display_bootinfo=disable/g' "$config_file" 220 | fi 221 | 222 | SOURCE_kernel="${PATH_SOURCE}/$(basename "$LINUX_GIT" .git)-$LINUX_BRANCH" 223 | kernel_version=$(get_linux_version $SOURCE_kernel) 224 | # run_status_no_retry "generate initramfs" chroot $TMP_mount_disk2 /bin/bash -c "DEBIAN_FRONTEND=noninteractive update-initramfs -uv -k $kernel_version" 225 | echo ""generate initramfs"" 226 | run_as_silent chroot $TMP_mount_disk2 /bin/bash -c "DEBIAN_FRONTEND=noninteractive update-initramfs -uv -k $kernel_version" 227 | 228 | trap - SIGINT EXIT 229 | cleanup "$LOOP_DEVICE" 230 | 231 | current_hour=$(date +"%H") 232 | current_minute=$(date +"%M") 233 | formatted_hour=$(printf "%02d" "$current_hour") 234 | formatted_minute=$(printf "%02d" "$current_minute") 235 | 236 | if [ -z "$NEW_IMG_FILE_NAME" ]; then 237 | NEW_IMG_FILE_NAME="${OUT_IMG_FILE}--${formatted_hour}_${formatted_minute}.img" 238 | else 239 | NEW_IMG_FILE_NAME="${PATH_OUTPUT}/${NEW_IMG_FILE_NAME}--${formatted_hour}_${formatted_minute}.img" 240 | fi 241 | mv $OUT_IMG_FILE $NEW_IMG_FILE_NAME 242 | 243 | echo -e "\noutputfile:\n\n\t\033[32m$(du -h ${NEW_IMG_FILE_NAME})\033[0m\n\n" 244 | 245 | } 246 | 247 | -------------------------------------------------------------------------------- /scripts/build_rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | APT_SOURCES_WALNUTPI="deb [trusted=yes] http://apt.walnutpi.com/debian/ bookworm main" 5 | APT_DOMAIN="apt.walnutpi.com" 6 | DEBIAN_BASE_URL="http://mirrors.tuna.tsinghua.edu.cn/debian/" 7 | UBUNTU22_BASE_URL="https://mirror.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/22.04/release/ubuntu-base-22.04.4-base-arm64.tar.gz" 8 | UBUNTU24_BASE_URL="https://mirror.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/24.04/release/ubuntu-base-24.04.2-base-arm64.tar.gz" 9 | 10 | download_ubuntu_base() { 11 | local base_url=$1 12 | local tmp_file_name=$2 13 | local tmp_dir=$3 14 | wget $base_url -O $tmp_file_name 15 | run_status "unzip rootfs" tar -xvf $tmp_file_name -C $TMP_rootfs_build 16 | 17 | # base默认没写dns服务器 18 | local FILE="${TMP_rootfs_build}/etc/resolv.conf" 19 | local LINE="nameserver 8.8.8.8" 20 | grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE" 21 | } 22 | 23 | download_debian_base() { 24 | local base_url=$1 25 | local debian_name=$2 26 | local tmp_dir=$3 27 | 28 | debootstrap --foreign --verbose --arch=${CHIP_ARCH} bookworm ${tmp_dir} $base_url 29 | exit_if_last_error 30 | 31 | # 完成rootfs的初始化 32 | cd ${tmp_dir} 33 | mount_chroot $tmp_dir 34 | LC_ALL=C LANGUAGE=C LANG=C chroot ${tmp_dir} /debootstrap/debootstrap --second-stage –verbose 35 | exit_if_last_error 36 | run_slient_when_successfuly chroot $tmp_dir /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 37 | umount_chroot $tmp_dir 38 | } 39 | 40 | generate_tmp_rootfs() { 41 | cleanup() { 42 | echo "Cleaning up..." 43 | if [[ -d $TMP_rootfs_build ]]; then 44 | run_status "umount $TMP_rootfs_build" umount_chroot $TMP_rootfs_build 45 | fi 46 | exit 1 47 | } 48 | trap cleanup SIGINT 49 | # set -e 50 | if [[ -d $TMP_rootfs_build ]]; then 51 | run_as_silent umount_chroot $TMP_rootfs_build 52 | rm -r ${TMP_rootfs_build} 53 | fi 54 | mkdir ${TMP_rootfs_build} 55 | 56 | echo -e "\n\n------\t build rootfs \t------" 57 | 58 | # 为节省编译时间,第一次编译时会构建一个基本rootfs,并安装base的软件,后续不再从头构建,直接从压缩包中解压出rootfs 59 | if [[ -f $FILE_base_rootfs ]]; then 60 | run_status "unzip last rootfs" tar -xvf $FILE_base_rootfs -C $TMP_rootfs_build 61 | else 62 | 63 | run_as_silent mkdir ${TMP_rootfs_build} -p 64 | case "${ENTER_os_ver}" in 65 | "${OPT_os_debian12}" | "$OPT_os_debian12_burn") 66 | download_debian_base $DEBIAN_BASE_URL "bookworm" $TMP_rootfs_build 67 | ;; 68 | 69 | "${OPT_os_ubuntu22}" ) 70 | download_ubuntu_base $UBUNTU22_BASE_URL $FILE_base_rootfs $TMP_rootfs_build 71 | ;; 72 | 73 | "${OPT_os_ubuntu24}" ) 74 | download_ubuntu_base $UBUNTU24_BASE_URL $FILE_base_rootfs $TMP_rootfs_build 75 | ;; 76 | 77 | esac 78 | cp /usr/bin/qemu-aarch64-static ${TMP_rootfs_build}/usr/bin/ 79 | chmod +x ${TMP_rootfs_build}/usr/bin/qemu-aarch64-static 80 | 81 | cd $TMP_rootfs_build 82 | tar -czf $FILE_base_rootfs ./ 83 | 84 | 85 | fi 86 | 87 | cp /usr/bin/qemu-aarch64-static ${TMP_rootfs_build}/usr/bin/ 88 | chmod +x ${TMP_rootfs_build}/usr/bin/qemu-aarch64-static 89 | 90 | # 用这个文件作为安装过的软件的列表,在重复构建时节省时间 91 | if [[ ! -f $PLACE_sf_list ]]; then 92 | touch $PLACE_sf_list 93 | fi 94 | 95 | 96 | # apt安装通用软件 97 | # cd $TMP_rootfs_build 98 | mount_chroot $TMP_rootfs_build 99 | 100 | run_status "apt update" chroot ${TMP_rootfs_build} /bin/bash -c "apt-get update" 101 | 102 | # 获取要本脚本的软件安装列表 103 | mapfile -t packages_build < <(grep -vE '^#|^$' ${FILE_apt_base}) 104 | if [[ ${ENTER_rootfs_type} == "desktop" ]]; then 105 | mapfile -t desktop_packages < <(grep -vE '^#|^$' ${FILE_apt_desktop}) 106 | packages_build=("${packages_build[@]}" "${desktop_packages[@]}") 107 | fi 108 | 109 | # 获取rootfs内的软件安装列表 110 | mapfile -t packages_rootfs < <(grep -vE '^#|^$' ${PLACE_sf_list}) 111 | # echo ${packages_build[@]} 112 | packages_install=() 113 | packages_remove=() 114 | # 找出需要安装的包 115 | for pkg in "${packages_build[@]}"; do 116 | if ! [[ " ${packages_rootfs[@]} " =~ " ${pkg} " ]]; then 117 | packages_install+=("$pkg") 118 | fi 119 | done 120 | # 找出需要移除的包 121 | for pkg in "${packages_rootfs[@]}"; do 122 | if ! [[ " ${packages_build[@]} " =~ " ${pkg} " ]]; then 123 | packages_remove+=("$pkg") 124 | fi 125 | done 126 | 127 | # 安装packages_install中的包,卸载packages_remove中的包 128 | total=${#packages_install[@]} 129 | for (( i=0; i<${total}; i++ )); do 130 | package=${packages_install[$i]} 131 | run_status "apt install [$((i+1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y ${package}" 132 | done 133 | total=${#packages_remove[@]} 134 | for (( i=0; i<${total}; i++ )); do 135 | package=${packages_remove[$i]} 136 | run_status "apt remove [$((i+1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get remove -y ${package}" 137 | done 138 | run_slient_when_successfuly chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 139 | 140 | # 将安装过的软件名称,都写进文件内 141 | if [[ -f $PLACE_sf_list ]]; then 142 | rm $PLACE_sf_list 143 | fi 144 | touch $PLACE_sf_list 145 | for package in "${packages_build[@]}"; do 146 | echo "$package" >> $PLACE_sf_list 147 | done 148 | 149 | umount_chroot $TMP_rootfs_build 150 | # 如果本次对保存的rootfs的apt软件有增删,则重设压缩包 151 | if [ ${#packages_install[@]} -gt 0 ] || [ ${#packages_remove[@]} -gt 0 ]; then 152 | rm -r $FILE_base_rootfs 153 | cd ${TMP_rootfs_build} 154 | run_status "create the tar to save now rootfs" tar -czf $FILE_base_rootfs ./ 155 | fi 156 | 157 | cd ${PATH_SOURCE} 158 | run_status "download wpi-update" clone_url "https://github.com/walnutpi/wpi-update.git" 159 | cd ${PATH_SOURCE}/wpi-update 160 | # run_status "get wpi-update version" 161 | touch /tmp/walnutpi-board_model 162 | touch ${TMP_rootfs_build}/tmp/walnutpi-board_model 163 | echo -n "$BOARD_MODEL" > /tmp/walnutpi-board_model 164 | echo -n "$BOARD_MODEL" > ${TMP_rootfs_build}/tmp/walnutpi-board_model 165 | VERSION_APT=$(echo $(./wpi-update -s | tail -n 1 )) 166 | 167 | # 创建release文件 168 | relseas_file="${TMP_rootfs_build}/etc/WalnutPi-release" 169 | touch $relseas_file 170 | echo "version=${VERSION_APT}" >> $relseas_file 171 | echo "date=$(date "+%Y-%m-%d %H:%M")" >> $relseas_file 172 | echo "os_type=${ENTER_rootfs_type}" >> $relseas_file 173 | echo "" >> $relseas_file 174 | 175 | # echo "kernel_git=$LINUX_GIT" >> $relseas_file 176 | # echo "kernel_version=$LINUX_BRANCH" >> $relseas_file 177 | # echo "kernel_config=$LINUX_CONFIG" >> $relseas_file 178 | # echo "toolchain=$TOOLCHAIN_FILE_NAME" >> $relseas_file 179 | 180 | cat $relseas_file 181 | 182 | 183 | # pip 安装指定软件 184 | LIB_DIR="${TMP_rootfs_build}/usr/lib" 185 | FILE_NAME="EXTERNALLY-MANAGED" 186 | find $LIB_DIR -type f -name "$FILE_NAME" -delete 187 | 188 | if [ -f $FILE_pip_list ]; then 189 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_pip_list}) 190 | total=${#packages[@]} 191 | for (( i=0; i<${total}; i++ )); do 192 | package=${packages[$i]} 193 | # echo "pip3 [$((i+1))/${total}] : $package" 194 | run_status "pip3 [$((i+1))/${total}] : $package" chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive pip3 --no-cache-dir install ${package}" 195 | done 196 | fi 197 | 198 | 199 | 200 | # firmware 201 | cd ${PATH_SOURCE} 202 | firm_dir=$(basename "${FIRMWARE_GIT}" .git) 203 | 204 | if [ -n "${FIRMWARE_GIT}" ]; then 205 | if [[ ! -d "firmware" ]]; then 206 | run_status "download firmware" git clone "${FIRMWARE_GIT}" 207 | fi 208 | FIRMWARE_PATH="${TMP_rootfs_build}/lib/firmware" 209 | if [ ! -d $FIRMWARE_PATH ]; then 210 | mkdir -p $FIRMWARE_PATH 211 | fi 212 | cp -r ${firm_dir}/* $FIRMWARE_PATH 213 | fi 214 | 215 | # 若主机通过hosts文件修改了apt域名指向,则在rootfs内也做相同的修改 216 | if grep -q "$APT_DOMAIN" /etc/hosts; then 217 | LINE=$(grep "$APT_DOMAIN" /etc/hosts) 218 | echo "$LINE" >> "$TMP_rootfs_build/etc/hosts" 219 | fi 220 | # run_status "change hosts" chroot $TMP_rootfs_build /bin/bash -c "service network-manager restart" 221 | 222 | # wpi-update 223 | cp wpi-update/wpi-update ${TMP_rootfs_build}/usr/bin 224 | run_status "run wpi-update" chroot ${TMP_rootfs_build} /bin/bash -c "wpi-update" 225 | 226 | 227 | MODULES_LIST=$(echo ${MODULES_ENABLE} | tr ' ' '\n') 228 | echo "$MODULES_LIST" > ${TMP_rootfs_build}/etc/modules 229 | 230 | 231 | # apt安装各板指定软件 232 | mount_chroot $TMP_rootfs_build 233 | # 插入walnutpi的apt源 234 | echo $APT_SOURCES_WALNUTPI >> ${TMP_rootfs_build}/etc/apt/sources.list.d/walnutpi.list 235 | run_status "apt update" chroot ${TMP_rootfs_build} /bin/bash -c "apt-get update" 236 | 237 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_apt_base_board}) 238 | if [[ ${ENTER_rootfs_type} == "desktop" ]]; then 239 | mapfile -t desktop_packages < <(grep -vE '^#|^$' ${FILE_apt_desktop_board}) 240 | packages=("${packages[@]}" "${desktop_packages[@]}") 241 | fi 242 | total=${#packages[@]} 243 | for (( i=0; i<${total}; i++ )); do 244 | package=${packages[$i]} 245 | run_status "apt [$((i+1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' install -y ${package}" 246 | done 247 | 248 | # 删除插入hosts文件的内容 249 | if grep -q "$APT_DOMAIN" "$TMP_rootfs_build/etc/hosts"; then 250 | sed -i "/$APT_DOMAIN/d" "$TMP_rootfs_build/etc/hosts" 251 | fi 252 | 253 | # 去除残余 254 | run_slient_when_successfuly chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 255 | # sed -i '$ d' ${TMP_rootfs_build}/etc/apt/sources.list 256 | rm ${TMP_rootfs_build}/etc/apt/sources.list.d/walnutpi.list 257 | 258 | 259 | cd $TMP_rootfs_build 260 | umount_chroot $TMP_rootfs_build 261 | trap - SIGINT EXIT 262 | } 263 | add_file_to_tmp_rootfs() { 264 | local source_file=$1 265 | local dest_path=$2 266 | if [[ -f "$source_file" ]]; then 267 | if [[ -d "$dest_path" ]]; then 268 | rm -r "$dest_path" 269 | fi 270 | mkdir -p "$dest_path" 271 | run_status "copy $(basename $source_file) to $dest_path" cp "$source_file" "$dest_path" 272 | fi 273 | } 274 | 275 | add_emmc_burn_file(){ 276 | local source_file=$1 277 | add_file_to_tmp_rootfs ${source_file} "${TMP_rootfs_build}/opt/burn" 278 | } 279 | 280 | pack_rootfs() { 281 | cd ${TMP_rootfs_build} 282 | if [ -f "$OUTFILE_rootfs_tar" ]; then 283 | rm $OUTFILE_rootfs_tar 284 | fi 285 | run_status "create tar" tar -c -I 'xz -T0' -f $OUTFILE_rootfs_tar ./ 286 | } -------------------------------------------------------------------------------- /scripts/build_kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PACKAGE_IMAGE_NAME=linux-image-${BOARD_MODEL}-${LINUX_BRANCH} 4 | DEB_IMAGE_NAME=${PACKAGE_IMAGE_NAME}_1.0.0_all.deb 5 | 6 | 7 | 8 | # 获取linux版本号,如5.15.147 6.1.9 9 | get_linux_version() { 10 | # $1 是传入的 Linux 源码项目的位置 11 | local src_dir=$1 12 | 13 | if [[ ! -d "$src_dir" ]]; then 14 | echo "目录不存在: $src_dir" 15 | return 1 16 | fi 17 | 18 | local makefile="$src_dir/Makefile" 19 | if [[ ! -f "$makefile" ]]; then 20 | echo "在目录中找不到 Makefile: $src_dir" 21 | return 1 22 | fi 23 | 24 | local version=$(grep -E '^VERSION = ' $makefile | cut -d ' ' -f 3) 25 | local patchlevel=$(grep -E '^PATCHLEVEL = ' $makefile | cut -d ' ' -f 3) 26 | local sublevel=$(grep -E '^SUBLEVEL = ' $makefile | cut -d ' ' -f 3) 27 | local extraversion=$(grep -E '^EXTRAVERSION = ' $makefile | cut -d ' ' -f 3) 28 | echo "$version.$patchlevel.$sublevel$extraversion" 29 | } 30 | 31 | 32 | 33 | is_enabled() { 34 | grep -q "^$1=y" include/config/auto.conf 35 | } 36 | 37 | 38 | 39 | 40 | compile_kernel() { 41 | 42 | cd $SOURCE_kernel 43 | if [ ! -f .scmversion ]; then 44 | run_as_user touch .scmversion 45 | fi 46 | 47 | 48 | thread_count=$(grep -c ^processor /proc/cpuinfo) 49 | run_as_user make $LINUX_CONFIG CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 50 | run_as_user make -j$thread_count CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 51 | 52 | exit_if_last_error 53 | 54 | echo "kernel compile success" 55 | } 56 | 57 | 58 | 59 | _gen_tmp_package_dir(){ 60 | local name=$1 61 | local TMP_KERNEL_DEB="${PATH_TMP}/${name}-${LINUX_CONFIG}_${LINUX_BRANCH}" 62 | if [[ -d $TMP_KERNEL_DEB ]]; then 63 | rm -r $TMP_KERNEL_DEB 64 | fi 65 | echo $TMP_KERNEL_DEB 66 | } 67 | 68 | # 填写control文件,生成deb包到输出路径 69 | _pack_as_kernel_deb(){ 70 | local path_package=$1 71 | local part_name=$2 72 | local package_desc=$3 73 | 74 | local package_name="$part_name-${BOARD_NAME}-${LINUX_BRANCH}" 75 | control_file=$path_package/DEBIAN/control 76 | 77 | if [ ! -d $path_package/DEBIAN ];then 78 | mkdir -p $path_package/DEBIAN 79 | fi 80 | 81 | # 从本build项目第一次提交时间起,linux项目共发生了几次提交,将提交数作为deb包的版本号 82 | cd $PATH_PROJECT_DIR 83 | git config --global --add safe.directory $PATH_PROJECT_DIR 84 | build_commit_time=$(git log --reverse --pretty=format:"%ad" --date=format:'%Y-%m-%d' | head -n 1) 85 | cd $SOURCE_kernel 86 | git_log=$(git log --since="$build_commit_time" --oneline) 87 | commit_count=$(echo "$git_log" | wc -l) 88 | deb_version="1.$commit_count.0" 89 | 90 | cd $path_package 91 | size=$(du -sk --exclude=DEBIAN . | cut -f1) 92 | 93 | 94 | cat << EOF > $control_file 95 | Package: ${package_name} 96 | Description: ${package_desc} 97 | Maintainer: walnutpi-build 98 | Version: ${deb_version} 99 | Section: free 100 | Priority: optional 101 | Installed-Size: ${size} 102 | Architecture: ${CHIP_ARCH} 103 | EOF 104 | DEB_IMAGE_NAME="${package_name}_${deb_version}_${CHIP_ARCH}.deb" 105 | run_status "创建deb包 ${DEB_IMAGE_NAME} " dpkg -b "$path_package" "${OUTDIR_kernel_package}/${DEB_IMAGE_NAME}" 106 | 107 | } 108 | 109 | pack_kernel_Image() { 110 | part_name="kernel-image" 111 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir $part_name) 112 | 113 | local path_board_tmp_boot="/tmp-boot/Image" 114 | local path_tmp_boot=${TMP_KERNEL_DEB}${path_board_tmp_boot} 115 | create_dir $path_tmp_boot 116 | 117 | cp ${SOURCE_kernel}/.config $path_tmp_boot/config-$(get_linux_version ./) 118 | cd $SOURCE_kernel 119 | run_status "export Image" cp ${SOURCE_kernel}/arch/${CHIP_ARCH}/boot/Image $path_tmp_boot 120 | 121 | _gen_postinst_cp_file $TMP_KERNEL_DEB $path_board_tmp_boot /boot/ 122 | _pack_as_kernel_deb $TMP_KERNEL_DEB $part_name "linux kernel image file" 123 | 124 | } 125 | pack_kernel_dtb() { 126 | part_name="kernel-dtb" 127 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir $part_name) 128 | 129 | local path_board_tmp_boot="/tmp-boot/dtb" 130 | local path_tmp_boot=${TMP_KERNEL_DEB}${path_board_tmp_boot} 131 | create_dir $path_tmp_boot 132 | 133 | cd $SOURCE_kernel 134 | run_status "export device-tree" make dtbs_install INSTALL_DTBS_PATH="$path_tmp_boot" ARCH=${CHIP_ARCH} 135 | 136 | # 设备树导出后,会产生一个类似allwinner/.dtb的路径,把里面的dtb提取到外面 137 | folder_name=$(ls -d $path_tmp_boot/*/ | head -n 1) 138 | cp -r $folder_name* $path_tmp_boot 139 | rm -r $folder_name 140 | 141 | _gen_postinst_cp_file $TMP_KERNEL_DEB $path_board_tmp_boot /boot/ 142 | echo "set-device" >> $TMP_KERNEL_DEB/DEBIAN/postinst 143 | echo "echo \"ok\"" >> $TMP_KERNEL_DEB/DEBIAN/postinst 144 | _pack_as_kernel_deb $TMP_KERNEL_DEB $part_name "linux kernel dtb files" 145 | } 146 | 147 | 148 | pack_kernel_modules() { 149 | part_name="kernel-modules" 150 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir $part_name) 151 | 152 | cd $SOURCE_kernel 153 | run_status "export modules" make modules_install INSTALL_MOD_PATH="$TMP_KERNEL_DEB" ARCH=${CHIP_ARCH} 154 | 155 | for dir in $TMP_KERNEL_DEB/lib/modules/*/ 156 | do 157 | # 这个build文件夹指向源码绝对位置,要删掉 158 | if [ -d "${dir}build" ]; then 159 | rm -rf "${dir}build" 160 | fi 161 | # 这个source文件夹指向源码绝对位置,要删掉 162 | if [ -d "${dir}source" ]; then 163 | rm -rf "${dir}source" 164 | fi 165 | done 166 | local postinst_file="$TMP_KERNEL_DEB/DEBIAN/postinst" 167 | if [ ! -d $TMP_KERNEL_DEB/DEBIAN ];then 168 | mkdir $TMP_KERNEL_DEB/DEBIAN 169 | fi 170 | cat << EOF > $postinst_file 171 | #!/bin/sh 172 | case "\$1" in 173 | configure) 174 | echo "update modules" 175 | depmod 176 | ;; 177 | abort-upgrade|abort-remove|abort-deconfigure) 178 | # 回滚操作 179 | ;; 180 | 181 | esac 182 | exit 0 183 | EOF 184 | chmod 755 $postinst_file 185 | 186 | _pack_as_kernel_deb $TMP_KERNEL_DEB $part_name "linux kernel modules" 187 | 188 | } 189 | 190 | # 进入linux项目源码路径下调用 191 | # 调用前运行先clean 192 | # 将linux-headers相关文件生成到参数1指定路径 193 | generate_kernel_headers() { 194 | local tmpdir=$1 195 | local arch=$2 196 | local version=$(get_linux_version ./) 197 | 198 | local destdir=$tmpdir/usr/src/linux-headers-$version 199 | create_dir $destdir 200 | if [ -d debian ];then 201 | rm -rf debian 202 | fi 203 | create_dir debian 204 | 205 | configobj=CONFIG_OBJTOOL 206 | 207 | # Collect source files 208 | ( 209 | find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl -o -name \*.mk 210 | find arch/*/include include scripts -type f -o -type l 211 | find security/*/include -type f 212 | find arch/$arch -name module.lds -o -name Kbuild.platforms -o -name Platform 213 | find $(find arch/$arch -name include -o -name scripts -o -name tools -type d) -type f 214 | ) > debian/hdrsrcfiles 215 | 216 | { 217 | # This affects arch/x86 218 | if is_enabled $configobj; then 219 | # echo tools/objtool/objtool 220 | find tools/objtool -type f -executable 221 | fi 222 | 223 | find arch/$arch/include Module.symvers include scripts -type f 224 | 225 | if is_enabled CONFIG_GCC_PLUGINS; then 226 | find scripts/gcc-plugins -name \*.so -o -name gcc-common.h 227 | fi 228 | find tools/ -name "*e_byteshift.h" 229 | } > debian/hdrobjfiles 230 | 231 | 232 | # 检测以scrpt开头的文件,删除那些被写进.gitignore的 233 | process_file() { 234 | local input_file="$1" 235 | local temp_file=$(mktemp) 236 | 237 | while IFS= read -r line; do 238 | if [[ $line == scripts* ]]; then 239 | if ! git check-ignore -q "$line"; then 240 | echo "$line" >> "$temp_file" 241 | fi 242 | else 243 | echo "$line" >> "$temp_file" 244 | fi 245 | done < "$input_file" 246 | 247 | cat "$temp_file" > "$input_file" 248 | } 249 | 250 | process_file debian/hdrsrcfiles 251 | process_file debian/hdrobjfiles 252 | echo "scripts/module.lds" >> debian/hdrsrcfiles 253 | 254 | tar -c -f - -C ./ -T debian/hdrsrcfiles | tar -xf - -C $destdir 255 | tar -c -f - -T debian/hdrobjfiles | tar -xf - -C $destdir 256 | 257 | # copy .config manually to be where it's expected to be 258 | create_dir $tmpdir/DEBIAN 259 | [[ ! -f $tmpdir/DEBIAN/postinst ]] && touch $tmpdir/DEBIAN/postinst 260 | relseas_file="/etc/WalnutPi-release" 261 | 262 | cat << EOF > $tmpdir/DEBIAN/postinst 263 | #!/bin/bash 264 | cd /usr/src/linux-headers-$version 265 | 266 | echo "Compiling headers - please wait ..." 267 | yes "" | make ARCH=$arch clean 268 | NCPU=\$(grep -c 'processor' /proc/cpuinfo) 269 | find -type f -exec touch {} + 270 | yes "" | make ARCH=$arch oldconfig 271 | make -j\$NCPU ARCH=$arch -s scripts 272 | make -j\$NCPU ARCH=$arch -s M=scripts/mod/ 273 | echo "Compiling end" 274 | 275 | function replace_or_append() { 276 | local file_path="$relseas_file" 277 | local search_string="\$1" 278 | local replace_string="\$2" 279 | 280 | if grep -q "^\$search_string" "\$file_path"; then 281 | sed -i "/^\$search_string/c\\\\\$replace_string" "\$file_path" 282 | else 283 | echo "\$replace_string" >> "\$file_path" 284 | fi 285 | } 286 | replace_or_append "kernel_git" "kernel_git=$LINUX_GIT" 287 | replace_or_append "kernel_branch" "kernel_branch=$LINUX_BRANCH" 288 | replace_or_append "kernel_config" "kernel_config=$LINUX_CONFIG" 289 | replace_or_append "toolchain" "toolchain=$TOOLCHAIN_FILE_NAME$TOOLCHAIN_NAME_IN_APT" 290 | 291 | update-initramfs -uv -k $version 292 | 293 | EOF 294 | chmod +x $tmpdir/DEBIAN/postinst 295 | 296 | cat << EOF > $tmpdir/DEBIAN/postrm 297 | #!/bin/bash 298 | if [ "$1" = "remove" ] ; then 299 | if [ -d /usr/src/linux-headers-$version ]; then 300 | rm -r /usr/src/linux-headers-$version 301 | fi 302 | fi 303 | EOF 304 | chmod +x $tmpdir/DEBIAN/postrm 305 | 306 | # cat << EOF > $tmpdir/DEBIAN/preinst 307 | # #!/bin/bash 308 | # if [ -d /usr/src/linux-headers-$version ]; then 309 | # echo "remove old linux-headers" 310 | # rm -r /usr/src/linux-headers-$version 311 | # fi 312 | # exit 0 313 | # EOF 314 | # chmod +x $tmpdir/DEBIAN/preinst 315 | 316 | cp .config $destdir/.config 317 | create_dir $tmpdir/lib/modules/$version 318 | ln -s /usr/src/linux-headers-$version $tmpdir/lib/modules/$version/build 319 | 320 | 321 | } 322 | pack_kernel_headers() { 323 | part_name="kernel-headers" 324 | 325 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir $part_name) 326 | 327 | SOURCE_kernel_CLEAN="${SOURCE_kernel}-clean" 328 | if [ -d $SOURCE_kernel_CLEAN ]; then 329 | rm -r $SOURCE_kernel_CLEAN 330 | fi 331 | run_status "copy kernel" run_as_user cp -r $SOURCE_kernel $SOURCE_kernel_CLEAN 332 | 333 | cd $SOURCE_kernel_CLEAN 334 | run_status "make the kernel clean" run_as_user make clean CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 335 | 336 | cd $SOURCE_kernel_CLEAN 337 | local version=$(get_linux_version ./) 338 | local destdir=$TMP_KERNEL_DEB/usr/src/linux-headers-$version 339 | create_dir $destdir 340 | create_dir debian 341 | 342 | cd $SOURCE_kernel_CLEAN 343 | make clean CROSS_COMPILE=$USE_CROSS_COMPILE ARCH=${CHIP_ARCH} 344 | generate_kernel_headers $TMP_KERNEL_DEB $CHIP_ARCH 345 | 346 | _pack_as_kernel_deb $TMP_KERNEL_DEB $part_name "linux kernel header files" 347 | 348 | } 349 | 350 | build_kernel() { 351 | cd $PATH_SOURCE 352 | clone_branch $LINUX_GIT $LINUX_BRANCH $SOURCE_kernel 353 | git config --global --add safe.directory $SOURCE_kernel 354 | 355 | compile_kernel 356 | if [ -d $OUTDIR_kernel_package ]; then 357 | rm -r $OUTDIR_kernel_package 358 | fi 359 | create_dir $OUTDIR_kernel_package 360 | 361 | pack_kernel_Image 362 | pack_kernel_dtb 363 | pack_kernel_modules 364 | pack_kernel_headers 365 | 366 | } -------------------------------------------------------------------------------- /scripts/gen_rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | APT_SOURCES_WALNUTPI="deb [trusted=yes] http://apt.walnutpi.com/debian/ bookworm main" 4 | APT_DOMAIN="apt.walnutpi.com" 5 | DEBIAN_BASE_URL="http://mirrors.tuna.tsinghua.edu.cn/debian/" 6 | UBUNTU22_BASE_URL="https://mirror.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/22.04/release/ubuntu-base-22.04.4-base-arm64.tar.gz" 7 | UBUNTU24_BASE_URL="https://mirror.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/24.04/release/ubuntu-base-24.04.2-base-arm64.tar.gz" 8 | 9 | # 参数说明: 10 | # $1 - base_url: Ubuntu基础镜像的下载URL 11 | # $2 - tmp_file_name: 下载文件的临时名称 12 | # $3 - tmp_dir: 解压目标目录 13 | _download_ubuntu_base() { 14 | local base_url=$1 15 | local tmp_file_name=$2 16 | local tmp_dir=$3 17 | wget $base_url -O $tmp_file_name 18 | run_status "unzip rootfs" tar -xvf $tmp_file_name -C $tmp_dir 19 | 20 | # base默认没写dns服务器 21 | local FILE="${tmp_dir}/etc/resolv.conf" 22 | local LINE="nameserver 8.8.8.8" 23 | grep -qF -- "$LINE" "$FILE" || echo "$LINE" >>"$FILE" 24 | } 25 | # 参数说明: 26 | # $1 - base_url: Debian基础镜像的下载URL 27 | # $2 - debian_name: Debian版本名称 28 | # $3 - tmp_dir: 解压目标目录 29 | # $4 - chip_arch: 芯片架构 30 | _download_debian_base() { 31 | local base_url=$1 32 | local debian_name=$2 33 | local tmp_dir=$3 34 | local chip_arch=$4 35 | 36 | debootstrap --foreign --verbose --arch=${chip_arch} ${debian_name} ${tmp_dir} $base_url 37 | exit_if_last_error 38 | 39 | # 完成rootfs的初始化 40 | cd ${tmp_dir} 41 | mount_chroot $tmp_dir 42 | LC_ALL=C LANGUAGE=C LANG=C chroot ${tmp_dir} /debootstrap/debootstrap --second-stage –verbose 43 | exit_if_last_error 44 | run_slient_when_successfuly chroot $tmp_dir /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 45 | umount_chroot $tmp_dir 46 | } 47 | 48 | # 下载基础rootfs或解压已有rootfs 49 | # 参数说明: 50 | # $1 - FILE_base_rootfs: 基础rootfs压缩包文件路径 51 | # $2 - TMP_rootfs_build: 临时构建rootfs的目录 52 | # $3 - ENTER_os_ver: 操作系统版本选择 53 | _download_base_rootfs() { 54 | local FILE_base_rootfs=$1 55 | local TMP_rootfs_build=$2 56 | local ENTER_os_ver=$3 57 | 58 | if [[ -d $TMP_rootfs_build ]]; then 59 | run_as_silent umount_chroot $TMP_rootfs_build 60 | rm -r ${TMP_rootfs_build} 61 | fi 62 | mkdir ${TMP_rootfs_build} 63 | 64 | if [[ -f $FILE_base_rootfs ]]; then 65 | run_status "unzip last rootfs" tar -xvf $FILE_base_rootfs -C $TMP_rootfs_build 66 | else 67 | 68 | run_as_silent mkdir ${TMP_rootfs_build} -p 69 | case "${ENTER_os_ver}" in 70 | "${OPT_os_debian12}" | "$OPT_os_debian12_burn") 71 | _download_debian_base $DEBIAN_BASE_URL "bookworm" $TMP_rootfs_build arm64 72 | ;; 73 | "${OPT_os_debian11}") 74 | _download_debian_base $DEBIAN_BASE_URL "bullseye" $TMP_rootfs_build arm64 75 | ;; 76 | "${OPT_os_ubuntu22}") 77 | _download_ubuntu_base $UBUNTU22_BASE_URL $FILE_base_rootfs $TMP_rootfs_build 78 | ;; 79 | "${OPT_os_ubuntu24}") 80 | _download_ubuntu_base $UBUNTU24_BASE_URL $FILE_base_rootfs $TMP_rootfs_build 81 | ;; 82 | esac 83 | cd $TMP_rootfs_build 84 | tar -czf $FILE_base_rootfs ./ 85 | fi 86 | } 87 | # 参数说明: 88 | # $1 - TMP_rootfs_build: 临时构建rootfs的目录 89 | # $2 - FILE_apt_base: 基础软件包列表文件 90 | # $3 - FILE_apt_desktop: 桌面环境软件包列表文件 91 | # $4 - ENTER_rootfs_type: rootfs类型 (desktop 或其他) 92 | # $5 - PLACE_sf_list: 已安装软件包记录文件 93 | # $6 - FILE_base_rootfs: 基础rootfs压缩包文件路径 94 | _apt_install_base_rootfs() { 95 | local TMP_rootfs_build=$1 96 | local FILE_apt_base=$2 97 | local FILE_apt_desktop=$3 98 | local ENTER_rootfs_type=$4 99 | local PLACE_sf_list=$5 100 | local FILE_base_rootfs=$6 101 | 102 | # apt安装通用软件 103 | # cd $TMP_rootfs_build 104 | mount_chroot $TMP_rootfs_build 105 | 106 | run_status "apt update" chroot ${TMP_rootfs_build} /bin/bash -c "apt-get update" 107 | 108 | # 用这个文件作为安装过的软件的列表,在重复构建时节省时间 109 | if [[ ! -f $PLACE_sf_list ]]; then 110 | touch $PLACE_sf_list 111 | fi 112 | 113 | # 获取要本脚本的软件安装列表 114 | mapfile -t packages_build < <(grep -vE '^#|^$' ${FILE_apt_base}) 115 | if [[ ${ENTER_rootfs_type} == "desktop" ]]; then 116 | mapfile -t desktop_packages < <(grep -vE '^#|^$' ${FILE_apt_desktop}) 117 | packages_build=("${packages_build[@]}" "${desktop_packages[@]}") 118 | fi 119 | 120 | # 获取rootfs内的软件安装列表 121 | mapfile -t packages_rootfs < <(grep -vE '^#|^$' ${PLACE_sf_list}) 122 | # echo ${packages_build[@]} 123 | packages_install=() 124 | packages_remove=() 125 | # 找出需要安装的包 126 | for pkg in "${packages_build[@]}"; do 127 | if ! [[ " ${packages_rootfs[@]} " =~ " ${pkg} " ]]; then 128 | packages_install+=("$pkg") 129 | fi 130 | done 131 | # 找出需要移除的包 132 | for pkg in "${packages_rootfs[@]}"; do 133 | if ! [[ " ${packages_build[@]} " =~ " ${pkg} " ]]; then 134 | packages_remove+=("$pkg") 135 | fi 136 | done 137 | 138 | # 安装packages_install中的包,卸载packages_remove中的包 139 | total=${#packages_install[@]} 140 | for ((i = 0; i < ${total}; i++)); do 141 | package=${packages_install[$i]} 142 | run_status "apt install [$((i + 1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y ${package}" 143 | done 144 | total=${#packages_remove[@]} 145 | for ((i = 0; i < ${total}; i++)); do 146 | package=${packages_remove[$i]} 147 | run_status "apt remove [$((i + 1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get remove -y ${package}" 148 | done 149 | run_slient_when_successfuly chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 150 | 151 | # 将安装过的软件名称,都写进文件内 152 | if [[ -f $PLACE_sf_list ]]; then 153 | rm $PLACE_sf_list 154 | fi 155 | touch $PLACE_sf_list 156 | for package in "${packages_build[@]}"; do 157 | echo "$package" >>$PLACE_sf_list 158 | done 159 | umount_chroot $TMP_rootfs_build 160 | 161 | # 如果本次对保存的rootfs的apt软件有增删,则重设压缩包 162 | if [ ${#packages_install[@]} -gt 0 ] || [ ${#packages_remove[@]} -gt 0 ]; then 163 | rm -r $FILE_base_rootfs 164 | cd ${TMP_rootfs_build} 165 | run_status "create the tar to save now rootfs" tar -czf $FILE_base_rootfs ./ 166 | fi 167 | 168 | } 169 | 170 | # 参数说明: 171 | # $1 - TMP_rootfs_build: 临时构建rootfs的目录 172 | # $2 - FILE_pip_list: pip软件包列表文件 173 | _pip_install() { 174 | local TMP_rootfs_build=$1 175 | local FILE_pip_list=$2 176 | 177 | # pip 安装指定软件 178 | local LIB_DIR="${TMP_rootfs_build}/usr/lib" 179 | local FILE_NAME="EXTERNALLY-MANAGED" 180 | find $LIB_DIR -type f -name "$FILE_NAME" -delete 181 | 182 | if [ -f $FILE_pip_list ]; then 183 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_pip_list}) 184 | local total=${#packages[@]} 185 | for ((i = 0; i < ${total}; i++)); do 186 | local package=${packages[$i]} 187 | # echo "pip3 [$((i+1))/${total}] : $package" 188 | run_status "pip3 [$((i + 1))/${total}] : $package" chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive pip3 --no-cache-dir install ${package}" 189 | done 190 | fi 191 | } 192 | 193 | # 参数说明: 194 | # $1 - PATH_SOURCE: 源代码路径 195 | # $2 - FIRMWARE_GIT: 固件Git仓库地址 196 | # $3 - TMP_rootfs_build: 临时构建rootfs的目录 197 | _add_firmware() { 198 | local PATH_SOURCE=$1 199 | local FIRMWARE_GIT=$2 200 | local TMP_rootfs_build=$3 201 | 202 | cd ${PATH_SOURCE} 203 | local firm_dir=$(basename "${FIRMWARE_GIT}" .git) 204 | 205 | if [ -n "${FIRMWARE_GIT}" ]; then 206 | if [[ ! -d "firmware" ]]; then 207 | run_status "download firmware" git clone "${FIRMWARE_GIT}" 208 | fi 209 | local FIRMWARE_PATH="${TMP_rootfs_build}/lib/firmware" 210 | if [ ! -d $FIRMWARE_PATH ]; then 211 | mkdir -p $FIRMWARE_PATH 212 | fi 213 | cp -r ${firm_dir}/* $FIRMWARE_PATH 214 | fi 215 | } 216 | # 参数说明: 217 | # $1 - TMP_rootfs_build: 临时构建rootfs的目录 218 | # $2 - FILE_apt_base_board: 板级基础软件包列表文件 219 | # $3 - FILE_apt_desktop_board: 板级桌面环境软件包列表文件 220 | # $4 - ENTER_rootfs_type: rootfs类型 (desktop 或其他) 221 | _wpi_install() { 222 | local TMP_rootfs_build=$1 223 | local FILE_apt_base_board=$2 224 | local FILE_apt_desktop_board=$3 225 | local ENTER_rootfs_type=$4 226 | 227 | mount_chroot $TMP_rootfs_build 228 | # 插入walnutpi的apt源 229 | apt_source_list=${TMP_rootfs_build}/etc/apt/sources.list.d/walnutpi.list 230 | if [ -f $apt_source_list ]; then 231 | rm $apt_source_list 232 | fi 233 | echo $APT_SOURCES_WALNUTPI >>$apt_source_list 234 | run_status "apt update" chroot ${TMP_rootfs_build} /bin/bash -c "apt-get update" 235 | 236 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_apt_base_board}) 237 | if [[ ${ENTER_rootfs_type} == "desktop" ]]; then 238 | mapfile -t desktop_packages < <(grep -vE '^#|^$' ${FILE_apt_desktop_board}) 239 | packages=("${packages[@]}" "${desktop_packages[@]}") 240 | fi 241 | local total=${#packages[@]} 242 | for ((i = 0; i < ${total}; i++)); do 243 | local package=${packages[$i]} 244 | run_status "apt [$((i + 1))/${total}] : $package " chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' install -y ${package}" 245 | done 246 | 247 | # 删除插入hosts文件的内容 248 | if grep -q "$APT_DOMAIN" "$TMP_rootfs_build/etc/hosts"; then 249 | sed -i "/$APT_DOMAIN/d" "$TMP_rootfs_build/etc/hosts" 250 | fi 251 | 252 | # 去除残余 253 | run_slient_when_successfuly chroot $TMP_rootfs_build /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get clean" 254 | if [ -f $apt_source_list ]; then 255 | rm $apt_source_list 256 | fi 257 | umount_chroot $TMP_rootfs_build 258 | } 259 | # 参数说明: 260 | # $1 - TMP_rootfs_build: 临时构建rootfs的目录 261 | # $2 - FILE_base_rootfs: 基础rootfs压缩包文件路径 262 | # $3 - ENTER_os_ver: 操作系统版本选择 263 | # $4 - FILE_apt_base: 基础软件包列表文件 264 | # $5 - FILE_apt_desktop: 桌面环境软件包列表文件 265 | # $6 - ENTER_rootfs_type: rootfs类型 (desktop 或其他) 266 | # $7 - PLACE_sf_list: 已安装软件包记录文件 267 | # $8 - PATH_SOURCE: 源代码路径 268 | # $9 - FIRMWARE_GIT: 固件Git仓库地址 269 | # $10 - FILE_pip_list: pip软件包列表文件 270 | # $11 - FILE_apt_base_board: 板级基础软件包列表文件 271 | # $12 - FILE_apt_desktop_board: 板级桌面环境软件包列表文件 272 | # $13 - BOARD_MODEL: 开发板型号 273 | # $14 - MODULES_ENABLE: 需要启用的内核模块列表 274 | gen_rootfs() { 275 | local TMP_rootfs_build=$1 276 | local FILE_base_rootfs=$2 277 | local ENTER_os_ver=$3 278 | local FILE_apt_base=$4 279 | local FILE_apt_desktop=$5 280 | local ENTER_rootfs_type=$6 281 | local PLACE_sf_list=$7 282 | local PATH_SOURCE=$8 283 | local FIRMWARE_GIT=$9 284 | local FILE_pip_list=${10} 285 | local FILE_apt_base_board=${11} 286 | local FILE_apt_desktop_board=${12} 287 | local BOARD_MODEL=${13} 288 | local MODULES_ENABLE=${14} 289 | # 输出所有传入参数 290 | echo "TMP_rootfs_build=$TMP_rootfs_build" 291 | echo "FILE_base_rootfs=$FILE_base_rootfs" 292 | echo "ENTER_os_ver=$ENTER_os_ver" 293 | echo "FILE_apt_base=$FILE_apt_base" 294 | echo "FILE_apt_desktop=$FILE_apt_desktop" 295 | echo "ENTER_rootfs_type=$ENTER_rootfs_type" 296 | echo "PLACE_sf_list=$PLACE_sf_list" 297 | echo "PATH_SOURCE=$PATH_SOURCE" 298 | echo "FIRMWARE_GIT=$FIRMWARE_GIT" 299 | echo "FILE_pip_list=$FILE_pip_list" 300 | echo "FILE_apt_base_board=$FILE_apt_base_board" 301 | echo "FILE_apt_desktop_board=$FILE_apt_desktop_board" 302 | echo "BOARD_MODEL=$BOARD_MODEL" 303 | echo "MODULES_ENABLE=$MODULES_ENABLE" 304 | cleanup() { 305 | echo "Cleaning up..." 306 | if [[ -d $TMP_rootfs_build ]]; then 307 | run_status "umount $TMP_rootfs_build" umount_chroot $TMP_rootfs_build 308 | fi 309 | exit 1 310 | } 311 | trap cleanup SIGINT 312 | 313 | echo -e "\n\n------\t build rootfs \t------" 314 | 315 | # 准备基础rootfs 316 | _download_base_rootfs $FILE_base_rootfs $TMP_rootfs_build $ENTER_os_ver 317 | cp /usr/bin/qemu-aarch64-static ${TMP_rootfs_build}/usr/bin/ 318 | chmod +x ${TMP_rootfs_build}/usr/bin/qemu-aarch64-static 319 | 320 | _apt_install_base_rootfs $TMP_rootfs_build $FILE_apt_base $FILE_apt_desktop $ENTER_rootfs_type $PLACE_sf_list $FILE_base_rootfs 321 | 322 | # 若主机通过hosts文件修改了apt域名指向,则在rootfs内也做相同的修改 323 | if grep -q "$APT_DOMAIN" /etc/hosts; then 324 | LINE=$(grep "$APT_DOMAIN" /etc/hosts) 325 | echo "$LINE" >>"$TMP_rootfs_build/etc/hosts" 326 | fi 327 | 328 | # wpi-update 329 | cd ${PATH_SOURCE} 330 | run_status "download wpi-update" clone_url "https://github.com/walnutpi/wpi-update.git" 331 | cp wpi-update/wpi-update ${TMP_rootfs_build}/usr/bin 332 | 333 | cd ${PATH_SOURCE}/wpi-update 334 | touch /tmp/walnutpi-board_model 335 | touch ${TMP_rootfs_build}/tmp/walnutpi-board_model 336 | echo -n "$BOARD_MODEL" >/tmp/walnutpi-board_model 337 | echo -n "$BOARD_MODEL" >${TMP_rootfs_build}/tmp/walnutpi-board_model 338 | VERSION_APT=$(echo $(./wpi-update -s | tail -n 1)) 339 | 340 | # 创建release文件 341 | relseas_file="${TMP_rootfs_build}/etc/WalnutPi-release" 342 | # 如果存在文件relseas_file则删除 343 | if [ -f $relseas_file ]; then 344 | rm $relseas_file 345 | fi 346 | touch $relseas_file 347 | echo "version=${VERSION_APT}" >>$relseas_file 348 | echo "date=$(date "+%Y-%m-%d %H:%M")" >>$relseas_file 349 | echo "os_type=${ENTER_rootfs_type}" >>$relseas_file 350 | echo "" >>$relseas_file 351 | cat $relseas_file 352 | run_status "run wpi-update" chroot ${TMP_rootfs_build} /bin/bash -c "wpi-update" 353 | 354 | 355 | _pip_install "$TMP_rootfs_build" "$FILE_pip_list" 356 | _add_firmware "$PATH_SOURCE" "$FIRMWARE_GIT" "$TMP_rootfs_build" 357 | 358 | _wpi_install $TMP_rootfs_build $FILE_apt_base_board $FILE_apt_desktop_board $ENTER_rootfs_type $APT_DOMAIN 359 | 360 | # 设置要开机加载的驱动模块 361 | MODULES_LIST=$(echo ${MODULES_ENABLE} | tr ' ' '\n') 362 | echo "$MODULES_LIST" >${TMP_rootfs_build}/etc/modules 363 | 364 | cd $TMP_rootfs_build 365 | trap - SIGINT EXIT 366 | } 367 | -------------------------------------------------------------------------------- /scripts/pack_kernel_deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 生成临时包目录 4 | # 参数说明: 5 | # $1 - name: 包名称 6 | # $2 - PATH_TMP: 临时路径 7 | # $3 - LINUX_CONFIG: 内核配置 8 | # $4 - LINUX_BRANCH: 内核分支 9 | _gen_tmp_package_dir() { 10 | local name=$1 11 | local PATH_TMP=$2 12 | local LINUX_CONFIG=$3 13 | local LINUX_BRANCH=$4 14 | 15 | local TMP_KERNEL_DEB="${PATH_TMP}/${name}-${LINUX_CONFIG}_${LINUX_BRANCH}" 16 | if [[ -d $TMP_KERNEL_DEB ]]; then 17 | rm -r "$TMP_KERNEL_DEB" 18 | fi 19 | echo "$TMP_KERNEL_DEB" 20 | } 21 | 22 | # 填写control文件,生成deb包到输出路径 23 | # 参数说明: 24 | # $1 - path_package: 包路径 25 | # $2 - part_name: 部件名称 26 | # $3 - package_desc: 包描述 27 | # $4 - BOARD_MODEL: 板级模型 28 | # $5 - LINUX_BRANCH: 内核分支 29 | # $6 - CHIP_ARCH: 芯片架构 30 | # $7 - PATH_PROJECT_DIR: 项目路径 31 | # $8 - SOURCE_kernel: 内核源码路径 32 | # $9 - OUTDIR_kernel_package: 内核包输出目录 33 | _pack_as_kernel_deb() { 34 | local path_package=$1 35 | local part_name=$2 36 | local package_desc=$3 37 | local BOARD_MODEL=$4 38 | local LINUX_BRANCH=$5 39 | local CHIP_ARCH=$6 40 | local PATH_PROJECT_DIR=$7 41 | local SOURCE_kernel=$8 42 | local OUTDIR_kernel_package=$9 43 | 44 | local PACKAGE_IMAGE_NAME="linux-image-${BOARD_MODEL}-${LINUX_BRANCH}" 45 | local DEB_IMAGE_NAME="${PACKAGE_IMAGE_NAME}_1.0.0_all.deb" 46 | 47 | local package_name="$part_name-${BOARD_MODEL}-${LINUX_BRANCH}" 48 | local control_file="$path_package/DEBIAN/control" 49 | 50 | if [ ! -d "$path_package/DEBIAN" ]; then 51 | mkdir -p "$path_package/DEBIAN" 52 | fi 53 | 54 | # 从本build项目第一次提交时间起,linux项目共发生了几次提交,将提交数作为deb包的版本号 55 | cd "$PATH_PROJECT_DIR" 56 | git config --global --add safe.directory "$PATH_PROJECT_DIR" 57 | local build_commit_time=$(git log --reverse --pretty=format:"%ad" --date=format:'%Y-%m-%d' | head -n 1) 58 | cd "$SOURCE_kernel" 59 | git config --global --add safe.directory "$SOURCE_kernel" 60 | local git_log=$(git log --since="$build_commit_time" --oneline) 61 | local commit_count=$(echo "$git_log" | wc -l) 62 | local deb_version="1.$commit_count.0" 63 | echo "deb_version: $deb_version" 64 | cd "$path_package" 65 | local size=$(du -sk --exclude=DEBIAN . | cut -f1) 66 | 67 | cat <"$control_file" 68 | Package: ${package_name} 69 | Description: ${package_desc} 70 | Maintainer: walnutpi-build 71 | Version: ${deb_version} 72 | Section: free 73 | Priority: optional 74 | Installed-Size: ${size} 75 | Architecture: ${CHIP_ARCH} 76 | EOF 77 | local DEB_IMAGE_NAME="${package_name}_${deb_version}_${CHIP_ARCH}.deb" 78 | run_status "创建deb包 ${DEB_IMAGE_NAME}" dpkg-deb -Zgzip -b "$path_package" "${OUTDIR_kernel_package}/${DEB_IMAGE_NAME}" 79 | } 80 | 81 | # 打包内核镜像 82 | # 参数说明: 83 | # $1 - PATH_PROJECT_DIR: 项目所在绝对路径 84 | # $2 - SOURCE_kernel: 内核源码路径 85 | # $3 - CHIP_ARCH: 芯片架构 86 | # $4 - PATH_TMP: 临时路径 87 | # $5 - LINUX_CONFIG: 内核配置 88 | # $6 - LINUX_BRANCH: 内核分支 89 | # $7 - BOARD_NAME: 板子名称 90 | # $8 - OUTDIR_kernel_package: 内核包输出目录 91 | pack_kernel_Image() { 92 | local PATH_PROJECT_DIR=$1 93 | local SOURCE_kernel=$2 94 | local CHIP_ARCH=$3 95 | local PATH_TMP=$4 96 | local LINUX_CONFIG=$5 97 | local LINUX_BRANCH=$6 98 | local BOARD_NAME=$7 99 | local OUTDIR_kernel_package=$8 100 | 101 | local part_name="kernel-image" 102 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir "$part_name" "$PATH_TMP" "$LINUX_CONFIG" "$LINUX_BRANCH") 103 | 104 | local path_board_tmp_boot="/tmp-boot/Image" 105 | local path_tmp_boot="${TMP_KERNEL_DEB}${path_board_tmp_boot}" 106 | mkdir -p "$path_tmp_boot" 107 | 108 | cp "${SOURCE_kernel}/.config" "$path_tmp_boot/config-$(get_linux_version "$SOURCE_kernel")" 109 | cd "$SOURCE_kernel" 110 | run_status "export Image" cp "${SOURCE_kernel}/arch/${CHIP_ARCH}/boot/Image" "$path_tmp_boot" 111 | 112 | _gen_postinst_cp_file "$TMP_KERNEL_DEB" "$path_board_tmp_boot" /boot/ 113 | _pack_as_kernel_deb "$TMP_KERNEL_DEB" "$part_name" "linux kernel image file" \ 114 | "$BOARD_NAME" "$LINUX_BRANCH" "$CHIP_ARCH" "$PATH_PROJECT_DIR" "$SOURCE_kernel" "$OUTDIR_kernel_package" 115 | } 116 | 117 | # 打包设备树 118 | # 参数说明: 119 | # $1 - PATH_PROJECT_DIR: 项目所在绝对路径 120 | # $2 - SOURCE_kernel: 内核源码路径 121 | # $3 - CHIP_ARCH: 芯片架构 122 | # $4 - PATH_TMP: 临时路径 123 | # $5 - LINUX_CONFIG: 内核配置 124 | # $6 - LINUX_BRANCH: 内核分支 125 | # $7 - BOARD_NAME: 板子名称 126 | # $8 - OUTDIR_kernel_package: 内核包输出目录 127 | pack_kernel_dtb() { 128 | local PATH_PROJECT_DIR=$1 129 | local SOURCE_kernel=$2 130 | local CHIP_ARCH=$3 131 | local PATH_TMP=$4 132 | local LINUX_CONFIG=$5 133 | local LINUX_BRANCH=$6 134 | local BOARD_NAME=$7 135 | local OUTDIR_kernel_package=$8 136 | 137 | local part_name="kernel-dtb" 138 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir "$part_name" "$PATH_TMP" "$LINUX_CONFIG" "$LINUX_BRANCH") 139 | 140 | local path_board_tmp_boot="/tmp-boot/dtb" 141 | local path_tmp_boot="${TMP_KERNEL_DEB}${path_board_tmp_boot}" 142 | mkdir -p "$path_tmp_boot" 143 | 144 | cd "$SOURCE_kernel" 145 | run_status "export device-tree" make dtbs_install INSTALL_DTBS_PATH="$path_tmp_boot" ARCH="$CHIP_ARCH" 146 | 147 | # 设备树导出后,会产生一个类似allwinner/.dtb的路径,把里面的dtb提取到外面 148 | local folder_name=$(ls -d "$path_tmp_boot"/*/ | head -n 1) 149 | cp -r "${folder_name}"* "$path_tmp_boot" 150 | rm -r "$folder_name" 151 | 152 | _gen_postinst_cp_file "$TMP_KERNEL_DEB" "$path_board_tmp_boot" /boot/ 153 | echo "set-device" >>"$TMP_KERNEL_DEB/DEBIAN/postinst" 154 | echo "echo \"ok\"" >>"$TMP_KERNEL_DEB/DEBIAN/postinst" 155 | _pack_as_kernel_deb "$TMP_KERNEL_DEB" "$part_name" "linux kernel dtb files" \ 156 | "$BOARD_NAME" "$LINUX_BRANCH" "$CHIP_ARCH" "$PATH_PROJECT_DIR" "$SOURCE_kernel" "$OUTDIR_kernel_package" 157 | } 158 | 159 | # 打包内核模块 160 | # 参数说明: 161 | # $1 - PATH_PROJECT_DIR: 项目所在绝对路径 162 | # $2 - SOURCE_kernel: 内核源码路径 163 | # $3 - CHIP_ARCH: 芯片架构 164 | # $4 - PATH_TMP: 临时路径 165 | # $5 - LINUX_CONFIG: 内核配置 166 | # $6 - LINUX_BRANCH: 内核分支 167 | # $7 - BOARD_NAME: 板子名称 168 | # $8 - OUTDIR_kernel_package: 内核包输出目录 169 | # $9 - create_dir: 创建目录的函数 170 | pack_kernel_modules() { 171 | local PATH_PROJECT_DIR=$1 172 | local SOURCE_kernel=$2 173 | local CHIP_ARCH=$3 174 | local PATH_TMP=$4 175 | local LINUX_CONFIG=$5 176 | local LINUX_BRANCH=$6 177 | local BOARD_NAME=$7 178 | local OUTDIR_kernel_package=$8 179 | local create_dir=$9 180 | 181 | local part_name="kernel-modules" 182 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir "$part_name" "$PATH_TMP" "$LINUX_CONFIG" "$LINUX_BRANCH") 183 | 184 | cd "$SOURCE_kernel" 185 | run_status "export modules" make modules_install INSTALL_MOD_PATH="$TMP_KERNEL_DEB" ARCH="$CHIP_ARCH" 186 | if [ -d bsp/modules/gpu ]; then 187 | export srctree=$(pwd) 188 | run_status "export bsp modules" make modules_install INSTALL_MOD_PATH="$TMP_KERNEL_DEB/" ARCH="$CHIP_ARCH" -C bsp/modules/gpu M=bsp/modules/gpu 189 | fi 190 | 191 | for dir in "$TMP_KERNEL_DEB"/lib/modules/*/; do 192 | # 这个build文件夹指向源码绝对位置,要删掉 193 | if [ -d "${dir}build" ]; then 194 | rm -rf "${dir}build" 195 | fi 196 | # 这个source文件夹指向源码绝对位置,要删掉 197 | if [ -d "${dir}source" ]; then 198 | rm -rf "${dir}source" 199 | fi 200 | done 201 | local postinst_file="$TMP_KERNEL_DEB/DEBIAN/postinst" 202 | if [ ! -d "$TMP_KERNEL_DEB/DEBIAN" ]; then 203 | mkdir -p "$TMP_KERNEL_DEB/DEBIAN" 204 | fi 205 | cat <"$postinst_file" 206 | #!/bin/sh 207 | case "\$1" in 208 | configure) 209 | echo "update modules" 210 | depmod 211 | ;; 212 | abort-upgrade|abort-remove|abort-deconfigure) 213 | # 回滚操作 214 | ;; 215 | 216 | esac 217 | exit 0 218 | EOF 219 | chmod 755 "$postinst_file" 220 | 221 | _pack_as_kernel_deb "$TMP_KERNEL_DEB" "$part_name" "linux kernel modules" \ 222 | "$BOARD_NAME" "$LINUX_BRANCH" "$CHIP_ARCH" "$PATH_PROJECT_DIR" "$SOURCE_kernel" "$OUTDIR_kernel_package" 223 | } 224 | 225 | # 生成内核头文件 226 | # 参数说明: 227 | # $1 - tmpdir: 临时目录 228 | # $2 - arch: 架构 229 | # $3 - LINUX_GIT: 内核Git地址 230 | # $4 - LINUX_BRANCH: 内核分支 231 | # $5 - LINUX_CONFIG: 内核配置 232 | # $6 - TOOLCHAIN_FILE_NAME: 工具链文件名 233 | # $7 - TOOLCHAIN_NAME_IN_APT: APT中的工具链名称 234 | generate_kernel_headers() { 235 | local tmpdir=$1 236 | local arch=$2 237 | local LINUX_GIT=$3 238 | local LINUX_BRANCH=$4 239 | local LINUX_CONFIG=$5 240 | local TOOLCHAIN_FILE_NAME=$6 241 | local TOOLCHAIN_NAME_IN_APT=$7 242 | 243 | local version=$(get_linux_version .) 244 | 245 | local destdir="$tmpdir/usr/src/linux-headers-$version" 246 | create_dir "$destdir" 247 | if [ -d debian ]; then 248 | rm -rf debian 249 | fi 250 | create_dir debian 251 | 252 | local configobj=CONFIG_OBJTOOL 253 | is_enabled() { 254 | grep -q "^$1=y" include/config/auto.conf 255 | } 256 | # Collect source files 257 | ( 258 | find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl -o -name \*.mk 259 | find arch/*/include include scripts -type f -o -type l 260 | find security/*/include -type f 261 | find "arch/$arch" -name module.lds -o -name Kbuild.platforms -o -name Platform 262 | find $(find "arch/$arch" -name include -o -name scripts -o -name tools -type d) -type f 263 | ) >debian/hdrsrcfiles 264 | 265 | { 266 | # This affects arch/x86 267 | if is_enabled $configobj; then 268 | # echo tools/objtool/objtool 269 | find tools/objtool -type f -executable 270 | fi 271 | 272 | find "arch/$arch/include" Module.symvers include scripts -type f 273 | 274 | if is_enabled CONFIG_GCC_PLUGINS; then 275 | find scripts/gcc-plugins -name \*.so -o -name gcc-common.h 276 | fi 277 | find tools/ -name "*e_byteshift.h" 278 | } >debian/hdrobjfiles 279 | 280 | # 检测以scrpt开头的文件,删除那些被写进.gitignore的 281 | process_file() { 282 | local input_file="$1" 283 | local temp_file=$(mktemp) 284 | 285 | while IFS= read -r line; do 286 | if [[ $line == scripts* ]]; then 287 | if ! git check-ignore -q "$line"; then 288 | echo "$line" >>"$temp_file" 289 | fi 290 | else 291 | echo "$line" >>"$temp_file" 292 | fi 293 | done <"$input_file" 294 | 295 | cat "$temp_file" >"$input_file" 296 | } 297 | process_file debian/hdrsrcfiles 298 | process_file debian/hdrobjfiles 299 | echo "scripts/module.lds" >>debian/hdrsrcfiles 300 | 301 | tar -c -f - -C ./ -T debian/hdrsrcfiles | tar -xf - -C "$destdir" 302 | tar -c -f - -T debian/hdrobjfiles | tar -xf - -C "$destdir" 303 | 304 | # copy .config manually to be where it's expected to be 305 | create_dir "$tmpdir/DEBIAN" 306 | [[ ! -f $tmpdir/DEBIAN/postinst ]] && touch "$tmpdir/DEBIAN/postinst" 307 | local relseas_file="/etc/WalnutPi-release" 308 | 309 | cat <"$tmpdir/DEBIAN/postinst" 310 | #!/bin/bash 311 | cd /usr/src/linux-headers-$version 312 | 313 | echo "Compiling headers - please wait ..." 314 | yes "" | make ARCH=$arch clean 315 | NCPU=\$(grep -c 'processor' /proc/cpuinfo) 316 | find -type f -exec touch {} + 317 | yes "" | make ARCH=$arch oldconfig 318 | make -j\$NCPU ARCH=$arch -s scripts 319 | make -j\$NCPU ARCH=$arch -s M=scripts/mod/ 320 | echo "Compiling end" 321 | 322 | function replace_or_append() { 323 | local file_path="$relseas_file" 324 | local search_string="\$1" 325 | local replace_string="\$2" 326 | 327 | if grep -q "^\$search_string" "\$file_path"; then 328 | sed -i "/^\$search_string/c\\\\\$replace_string" "\$file_path" 329 | else 330 | echo "\$replace_string" >> "\$file_path" 331 | fi 332 | } 333 | replace_or_append "kernel_git" "kernel_git=$LINUX_GIT" 334 | replace_or_append "kernel_branch" "kernel_branch=$LINUX_BRANCH" 335 | replace_or_append "kernel_config" "kernel_config=$LINUX_CONFIG" 336 | replace_or_append "toolchain" "toolchain=$TOOLCHAIN_FILE_NAME$TOOLCHAIN_NAME_IN_APT" 337 | 338 | update-initramfs -uv -k $version 339 | 340 | EOF 341 | chmod +x "$tmpdir/DEBIAN/postinst" 342 | 343 | cat <"$tmpdir/DEBIAN/postrm" 344 | #!/bin/bash 345 | if [ "\$1" = "remove" ] ; then 346 | if [ -d /usr/src/linux-headers-$version ]; then 347 | rm -r /usr/src/linux-headers-$version 348 | fi 349 | fi 350 | EOF 351 | chmod +x "$tmpdir/DEBIAN/postrm" 352 | 353 | cp .config "$destdir/.config" 354 | create_dir "$tmpdir/lib/modules/$version" 355 | ln -s "/usr/src/linux-headers-$version" "$tmpdir/lib/modules/$version/build" 356 | } 357 | 358 | # 打包内核头文件 359 | # 参数说明: 360 | # $1 - PATH_PROJECT_DIR: 项目所在绝对路径 361 | # $2 - SOURCE_kernel: 内核源码路径 362 | # $3 - CHIP_ARCH: 芯片架构 363 | # $4 - PATH_TMP: 临时路径 364 | # $5 - LINUX_CONFIG: 内核配置 365 | # $6 - LINUX_BRANCH: 内核分支 366 | # $7 - BOARD_NAME: 板子名称 367 | # $8 - OUTDIR_kernel_package: 内核包输出目录 368 | # $9 - USE_CROSS_COMPILE: 交叉编译前缀 369 | # $10 - LINUX_GIT: 内核Git地址 370 | # $11 - TOOLCHAIN_FILE_NAME: 工具链文件名 371 | # $12 - TOOLCHAIN_NAME_IN_APT: APT中的工具链名称 372 | pack_kernel_headers() { 373 | local PATH_PROJECT_DIR=$1 374 | local SOURCE_kernel=$2 375 | local CHIP_ARCH=$3 376 | local PATH_TMP=$4 377 | local LINUX_CONFIG=$5 378 | local LINUX_BRANCH=$6 379 | local BOARD_NAME=$7 380 | local OUTDIR_kernel_package=$8 381 | local USE_CROSS_COMPILE=$9 382 | local LINUX_GIT=${10} 383 | local TOOLCHAIN_FILE_NAME=${11} 384 | local TOOLCHAIN_NAME_IN_APT=${12} 385 | 386 | local part_name="kernel-headers" 387 | 388 | local TMP_KERNEL_DEB=$(_gen_tmp_package_dir "$part_name" "$PATH_TMP" "$LINUX_CONFIG" "$LINUX_BRANCH") 389 | 390 | local SOURCE_kernel_CLEAN="${SOURCE_kernel}-clean" 391 | if [ -d "$SOURCE_kernel_CLEAN" ]; then 392 | rm -r "$SOURCE_kernel_CLEAN" 393 | fi 394 | run_status "copy kernel" cp -r "$SOURCE_kernel" "$SOURCE_kernel_CLEAN" 395 | 396 | cd "$SOURCE_kernel_CLEAN" 397 | run_status "make the kernel clean" make clean CROSS_COMPILE="$USE_CROSS_COMPILE" ARCH="$CHIP_ARCH" 398 | 399 | cd "$SOURCE_kernel_CLEAN" 400 | local version=$(get_linux_version $SOURCE_kernel_CLEAN) 401 | local destdir="$TMP_KERNEL_DEB/usr/src/linux-headers-$version" 402 | create_dir "$destdir" 403 | create_dir debian 404 | 405 | cd "$SOURCE_kernel_CLEAN" 406 | make clean CROSS_COMPILE="$USE_CROSS_COMPILE" ARCH="$CHIP_ARCH" 407 | generate_kernel_headers "$TMP_KERNEL_DEB" "$CHIP_ARCH" "$LINUX_GIT" "$LINUX_BRANCH" \ 408 | "$LINUX_CONFIG" "$TOOLCHAIN_FILE_NAME" "$TOOLCHAIN_NAME_IN_APT" 409 | 410 | _pack_as_kernel_deb "$TMP_KERNEL_DEB" "$part_name" "linux kernel header files" \ 411 | "$BOARD_NAME" "$LINUX_BRANCH" "$CHIP_ARCH" "$PATH_PROJECT_DIR" "$SOURCE_kernel_CLEAN" "$OUTDIR_kernel_package" 412 | } 413 | -------------------------------------------------------------------------------- /scripts/pack_all_img.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IMAGE_FLAG_NO_SCREEN_DISPLAY=$OPT_NO 4 | IMAGE_FLAG_DISK_RAED_ONLY=$OPT_NO 5 | 6 | PART1_SIZE=150 7 | PART2_SIZE=0 8 | 9 | # 检查所需文件是不是都生成了 10 | check_resource() { 11 | if [ ! -d "$OUTDIR_boot_package" ]; then 12 | echo $OUTDIR_boot_package "no exist" 13 | exit 14 | fi 15 | if [ ! -d "$OUTDIR_kernel_package" ]; then 16 | echo $OUTDIR_kernel_package "no exist" 17 | exit 18 | fi 19 | if [ ! -f "$OUTFILE_rootfs_tar" ]; then 20 | echo $OUTFILE_rootfs_tar "no exist" 21 | exit 22 | fi 23 | } 24 | 25 | __create_tmp_dir() { 26 | local TMP_ROOTFS_DIR=$1 27 | local TMP_mount_disk1=$2 28 | local TMP_mount_disk2=$3 29 | 30 | # 使用安全函数删除临时目录 31 | if [ -n "$TMP_ROOTFS_DIR" ] && [ "$TMP_ROOTFS_DIR" != "/" ]; then 32 | if [ -d "$TMP_ROOTFS_DIR/boot" ]; then 33 | umount "$TMP_ROOTFS_DIR/boot" 2>/dev/null || true 34 | safe_remove_tmp_dir "$TMP_ROOTFS_DIR/boot" 35 | fi 36 | safe_remove_tmp_dir "$TMP_ROOTFS_DIR" 37 | else 38 | echo "警告: TMP_ROOTFS_DIR变量未正确设置,跳过清理操作" 39 | echo "TMP_ROOTFS_DIR = $TMP_ROOTFS_DIR" 40 | fi 41 | 42 | if [ -n "$TMP_mount_disk1" ] && [ "$TMP_mount_disk1" != "/" ]; then 43 | safe_remove_tmp_dir "$TMP_mount_disk1" 44 | else 45 | echo "警告: TMP_mount_disk1变量未正确设置,跳过清理操作" 46 | echo "TMP_mount_disk1 = $TMP_mount_disk1" 47 | fi 48 | 49 | if [ -n "$TMP_mount_disk2" ] && [ "$TMP_mount_disk2" != "/" ]; then 50 | safe_remove_tmp_dir "$TMP_mount_disk2" 51 | else 52 | echo "警告: TMP_mount_disk2变量未正确设置,跳过清理操作" 53 | echo "TMP_mount_disk2 = $TMP_mount_disk2" 54 | fi 55 | 56 | mkdir -p $TMP_ROOTFS_DIR 57 | mkdir -p $TMP_ROOTFS_DIR/boot 58 | mkdir -p $TMP_mount_disk1 59 | mkdir -p $TMP_mount_disk2 60 | } 61 | 62 | __create_tmp_img_boot() { 63 | local TMP_IMG_BOOT=$1 64 | local PART1_SIZE=$2 65 | 66 | if [ -f "$TMP_IMG_BOOT" ]; then 67 | rm ${TMP_IMG_BOOT} 68 | fi 69 | run_status "create part1 file" dd if=/dev/zero of=$TMP_IMG_BOOT bs=1M count=$PART1_SIZE 70 | run_status "format part1 file" mkfs.fat -F 32 -n "boot" $TMP_IMG_BOOT 71 | } 72 | 73 | __add_file_to_tmp_rootfs_dir() { 74 | local OUTFILE_rootfs_tar=$1 75 | local OUTDIR_boot_package=$2 76 | local OUTDIR_kernel_package=$3 77 | local TMP_ROOTFS_DIR=$4 78 | local ENTER_img_file=$5 79 | 80 | run_status "add rootfs" tar xf $OUTFILE_rootfs_tar -C $TMP_ROOTFS_DIR -I 'xz -T0' 81 | 82 | # 如果ENTER_img_file不为空 83 | if [ -n "$ENTER_img_file" ]; then 84 | mkdir -p ${TMP_ROOTFS_DIR}/opt/burn 85 | cp ${ENTER_img_file} ${TMP_ROOTFS_DIR}/opt/burn/ 86 | run_status "copy $(basename $ENTER_img_file) to ${TMP_ROOTFS_DIR}/opt/burn/" cp "$ENTER_img_file" "${TMP_ROOTFS_DIR}/opt/burn/" 87 | fi 88 | 89 | echo "TMP_ROOTFS_DIR = ${TMP_ROOTFS_DIR}" 90 | 91 | cp /usr/bin/qemu-aarch64-static ${TMP_ROOTFS_DIR}/usr/bin/ 92 | chmod +x ${TMP_ROOTFS_DIR}/usr/bin/qemu-aarch64-static 93 | 94 | # 安装boot相关的deb包 95 | cp ${OUTDIR_boot_package}/*.deb ${TMP_ROOTFS_DIR}/opt/ 96 | cd ${TMP_ROOTFS_DIR}/opt/ 97 | local deb_packages=(*.deb) 98 | local total=${#deb_packages[@]} 99 | for ((i = 0; i < $total; i++)); do 100 | local deb_package=${deb_packages[$i]} 101 | run_status "boot package [$((i + 1))/${total}] : ${deb_package} " chroot ${TMP_ROOTFS_DIR} /bin/bash -c "dpkg -i /opt/${deb_package}" 102 | rm ${TMP_ROOTFS_DIR}/opt/${deb_package} 103 | done 104 | 105 | # 安装kernel产生的的deb包,先安装生成时间早的 106 | cd ${OUTDIR_kernel_package}/ 107 | local deb_packages=($(ls -t *.deb | tac)) 108 | cp ${OUTDIR_kernel_package}/*.deb ${TMP_ROOTFS_DIR}/opt/ 109 | cd ${TMP_ROOTFS_DIR}/opt/ 110 | total=${#deb_packages[@]} 111 | for ((i = 0; i < $total; i++)); do 112 | local deb_package=${deb_packages[$i]} 113 | run_status "kernel package [$((i + 1))/${total}] : ${deb_package} " chroot ${TMP_ROOTFS_DIR} /bin/bash -c "dpkg -i /opt/${deb_package}" 114 | rm ${TMP_ROOTFS_DIR}/opt/${deb_package} 115 | done 116 | } 117 | __create_img_file() { 118 | local OUT_IMG_FILE=$1 119 | local IMG_SIZE=$2 120 | local PART1_SIZE=$3 121 | 122 | if [ -f "$OUT_IMG_FILE" ]; then 123 | rm ${OUT_IMG_FILE} 124 | fi 125 | run_status "create img file: $OUT_IMG_FILE $IMG_SIZE MB" dd if=/dev/zero of=$OUT_IMG_FILE bs=1M count=$IMG_SIZE 126 | echo "创建分区" 127 | parted $OUT_IMG_FILE --script mklabel msdos 128 | parted $OUT_IMG_FILE --script mkpart primary fat32 1M $((PART1_SIZE + 1))M 129 | parted $OUT_IMG_FILE --script mkpart primary ext4 $((PART1_SIZE + 1))M 100% 130 | parted $OUT_IMG_FILE set 1 boot on 131 | } 132 | __get_new_img_file_name() { 133 | local OUT_IMG_FILE=$1 134 | 135 | local current_hour=$(date +"%H") 136 | local current_minute=$(date +"%M") 137 | local formatted_hour=$(printf "%02d" "$current_hour") 138 | local formatted_minute=$(printf "%02d" "$current_minute") 139 | 140 | NEW_IMG_FILE_NAME="${OUT_IMG_FILE}--${formatted_hour}_${formatted_minute}.img" 141 | echo "${NEW_IMG_FILE_NAME}" 142 | 143 | } 144 | # 参数说明: 145 | # $1 - OUTDIR_boot_package: boot包输出目录 146 | # $2 - OUTDIR_kernel_package: kernel包输出目录 147 | # $3 - OUTFILE_rootfs_tar: rootfs tar文件路径 148 | # $4 - PATH_SOURCE: 源代码路径 149 | # $5 - BOARD_MODEL: 开发板型号 150 | # $6 - FILE_apt_del: 需要删除的apt包列表文件 151 | # $7 - ENTER_os_ver: 操作系统版本选择 152 | # $8 - ENTER_rootfs_type: rootfs类型 153 | # $9 - IMAGE_FLAG_NO_SCREEN_DISPLAY: 无屏幕显示标志 154 | # $10 - BOOTLOADER_NAME: bootloader名称 155 | # $11 - OUTFILE_boot_bin: boot二进制文件路径 156 | # $12 - LINUX_GIT: Linux Git仓库地址 157 | # $13 - LINUX_BRANCH: Linux分支名称 158 | # $14 - PATH_PROJECT_DIR: 项目目录路径 159 | # $15 - NEW_IMG_FILE_NAME: 新镜像文件名(可选) 160 | 161 | pack_all_img() { 162 | local OUTDIR_boot_package=$1 163 | local OUTDIR_kernel_package=$2 164 | local OUTFILE_rootfs_tar=$3 165 | local PATH_SOURCE=$4 166 | local BOARD_MODEL=$5 167 | local FILE_apt_del=$6 168 | local ENTER_os_ver=$7 169 | local ENTER_rootfs_type=$8 170 | local IMAGE_FLAG_NO_SCREEN_DISPLAY=$9 171 | local BOOTLOADER_NAME=${10} 172 | local OUTFILE_boot_bin=${11} 173 | local LINUX_GIT=${12} 174 | local LINUX_BRANCH=${13} 175 | local PATH_PROJECT_DIR=${14} 176 | local ENTER_img_file="${15}" 177 | 178 | # 输出所有参数 179 | echo "=================== pack_all_img 参数值 ===================" 180 | echo "OUTDIR_boot_package: $OUTDIR_boot_package" 181 | echo "OUTDIR_kernel_package: $OUTDIR_kernel_package" 182 | echo "OUTFILE_rootfs_tar: $OUTFILE_rootfs_tar" 183 | echo "PATH_SOURCE: $PATH_SOURCE" 184 | echo "BOARD_MODEL: $BOARD_MODEL" 185 | echo "FILE_apt_del: $FILE_apt_del" 186 | echo "ENTER_os_ver: $ENTER_os_ver" 187 | echo "ENTER_rootfs_type: $ENTER_rootfs_type" 188 | echo "IMAGE_FLAG_NO_SCREEN_DISPLAY: $IMAGE_FLAG_NO_SCREEN_DISPLAY" 189 | echo "BOOTLOADER_NAME: $BOOTLOADER_NAME" 190 | echo "OUTFILE_boot_bin: $OUTFILE_boot_bin" 191 | echo "LINUX_GIT: $LINUX_GIT" 192 | echo "LINUX_BRANCH: $LINUX_BRANCH" 193 | echo "PATH_PROJECT_DIR: $PATH_PROJECT_DIR" 194 | echo "ENTER_img_file: $ENTER_img_file" 195 | echo "=========================================================" 196 | 197 | local TMP_IMG_BOOT="${PATH_TMP}/IMG/BootDisk-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 198 | local TMP_ROOTFS_DIR="${PATH_TMP}/IMG/Rootfs-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 199 | local TMP_mount_disk1="${PATH_TMP}/MountPoint/PART1-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 200 | local TMP_mount_disk2="${PATH_TMP}/MountPoint/PART2-${BOARD_NAME}-${ENTER_os_ver}_${ENTER_rootfs_type}" 201 | 202 | create_dir "${PATH_TMP}/IMG" 203 | create_dir "${PATH_TMP}/MountPoint" 204 | 205 | cleanup() { 206 | local LOOP_DEVICE=$1 207 | echo "Cleaning up..." 208 | cd $PATH_PROJECT_DIR 209 | unmount_point "$TMP_mount_disk2/boot" 210 | unmount_point "$TMP_ROOTFS_DIR" 211 | unmount_point "$TMP_mount_disk1" 212 | unmount_point "$TMP_mount_disk2" 213 | if [ -n "$LOOP_DEVICE" ]; then 214 | if losetup -l >/dev/null 2>&1; then 215 | while losetup -l | grep -q "$LOOP_DEVICE"; do 216 | echo "Releasing loop device $LOOP_DEVICE" 217 | kpartx -dv "$LOOP_DEVICE" 218 | losetup -d "$LOOP_DEVICE" 219 | sleep 1 220 | done 221 | fi 222 | fi 223 | } 224 | 225 | trap 'cleanup "$LOOP_DEVICE"; exit' SIGINT 226 | check_resource 227 | 228 | __create_tmp_dir "$TMP_ROOTFS_DIR" "$TMP_mount_disk1" "$TMP_mount_disk2" 229 | __create_tmp_img_boot "$TMP_IMG_BOOT" "$PART1_SIZE" 230 | # 挂载boot img到rootfs文件夹中 231 | run_status "mount part1 file" mount -o loop $TMP_IMG_BOOT ${TMP_ROOTFS_DIR}/boot 232 | # 将boot kernel rootfs都输出到临时目录中 233 | __add_file_to_tmp_rootfs_dir "$OUTFILE_rootfs_tar" "$OUTDIR_boot_package" "$OUTDIR_kernel_package" "$TMP_ROOTFS_DIR" "$ENTER_img_file" 234 | 235 | # 为了让set-lcd统一管理显示屏,所以需要构建时运行一次 236 | run_status "run set-lcd hdmi install " chroot ${TMP_ROOTFS_DIR} /bin/bash -c "set-lcd hdmi install" 237 | 238 | # 为了减小体积,可以删除掉在构建完成后就不需要了的包 239 | if [ -f ${FILE_apt_del} ]; then 240 | mapfile -t packages < <(grep -vE '^#|^$' ${FILE_apt_del}) 241 | total=${#packages[@]} 242 | for ((i = 0; i < ${total}; i++)); do 243 | local package=${packages[$i]} 244 | run_status "apt remove [$((i + 1))/${total}] : $package " chroot $TMP_ROOTFS_DIR /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' remove -y ${package}" 245 | done 246 | fi 247 | 248 | # 如果是ubuntu24,则禁用gdm3改为lightdm 249 | if [ "$ENTER_os_ver" == "$OPT_os_ubuntu24" ]; then 250 | if [[ "${ENTER_rootfs_type}" == "desktop" ]]; then 251 | echo "切换lightdm为默认桌面环境" 252 | run_status "remove gdm3 " chroot ${TMP_ROOTFS_DIR} /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-overwrite' remove -y gdm3" 253 | chroot $TMP_ROOTFS_DIR /bin/bash -c "dpkg-reconfigure lightdm" 254 | fi 255 | fi 256 | 257 | local ROOTFS_SIZE=$(du -sm $TMP_ROOTFS_DIR | cut -f1) 258 | local PART2_SIZE=$(echo "scale=0; ($ROOTFS_SIZE * 1.024 + 100)/1" | bc) 259 | 260 | echo "PART1_SIZE=${PART1_SIZE}MB" 261 | echo "PART2_SIZE=${PART2_SIZE}MB" 262 | 263 | cd ${PATH_SOURCE}/wpi-update 264 | echo -n "$BOARD_MODEL" >/tmp/walnutpi-board_model 265 | local VERSION_APT=$(echo $(./wpi-update -s | tail -n 1)) 266 | if [ -n "$ENTER_img_file" ]; then 267 | local OUT_IMG_FILE="${PATH_OUTPUT}/eMMC_burner-$(basename $ENTER_img_file)" 268 | else 269 | local OUT_IMG_FILE="${PATH_OUTPUT}/V${VERSION_APT}_$(date +%m-%d)_${ENTER_rootfs_type}_${BOARD_NAME}_${LINUX_BRANCH}_${ENTER_os_ver}" 270 | fi 271 | echo "镜像文件名为$OUT_IMG_FILE" 272 | local IMG_SIZE=$((PART1_SIZE + PART2_SIZE + 2)) 273 | __create_img_file "$OUT_IMG_FILE" "$IMG_SIZE" "$PART1_SIZE" 274 | 275 | __mount_img_to_dir() { 276 | LOOP_DEVICE="" 277 | local MAX_RETRIES=5 278 | local RETRY_COUNT=0 279 | 280 | # 循环获取可用 loop 设备并关联镜像文件 281 | until [ -n "$LOOP_DEVICE" ] && [ -b "$LOOP_DEVICE" ]; do 282 | LOOP_DEVICE=$(losetup -f) 283 | if [ $? -ne 0 ] || [ -z "$LOOP_DEVICE" ]; then 284 | RETRY_COUNT=$((RETRY_COUNT + 1)) 285 | if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then 286 | echo "Error: Failed to get a loop device after $MAX_RETRIES attempts." 287 | exit 1 288 | fi 289 | echo "Warning: Failed to get loop device, retrying in 3 second... ($RETRY_COUNT/$MAX_RETRIES)" 290 | sleep 3 291 | continue 292 | fi 293 | 294 | losetup "$LOOP_DEVICE" "$OUT_IMG_FILE" 295 | if [ $? -ne 0 ]; then 296 | RETRY_COUNT=$((RETRY_COUNT + 1)) 297 | if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then 298 | echo "Error: Failed to setup loop device after $MAX_RETRIES attempts." 299 | exit 1 300 | fi 301 | echo "Warning: Failed to setup $LOOP_DEVICE with $OUT_IMG_FILE, retrying in 1 second... ($RETRY_COUNT/$MAX_RETRIES)" 302 | kpartx -dv "$LOOP_DEVICE" 303 | losetup -d "$LOOP_DEVICE" 304 | sleep 3 305 | LOOP_DEVICE="" # 清除无效设备路径 306 | # 清除缓存 307 | 308 | fi 309 | done 310 | 311 | kpartx -av "$LOOP_DEVICE" 312 | 313 | # 挂载镜像文件 314 | local MAPPER_DEVICE=$(echo "$LOOP_DEVICE" | sed 's/\/dev\///' | sed 's/\//p/') 315 | MAPPER_DEVICE1="/dev/mapper/${MAPPER_DEVICE}p1" 316 | MAPPER_DEVICE2="/dev/mapper/${MAPPER_DEVICE}p2" 317 | echo "MAPPER_DEVICE=${MAPPER_DEVICE}" 318 | 319 | run_status "format part 1" mkfs.vfat "$MAPPER_DEVICE1" 320 | run_status "format part 2" mkfs.ext4 "$MAPPER_DEVICE2" 321 | 322 | mount "$MAPPER_DEVICE1" "$TMP_mount_disk1" 323 | mount "$MAPPER_DEVICE2" "$TMP_mount_disk2" 324 | 325 | if [ ! -d "$TMP_mount_disk2/boot" ]; then 326 | mkdir -p "$TMP_mount_disk2/boot" 327 | fi 328 | 329 | mount "$MAPPER_DEVICE1" "$TMP_mount_disk2/boot" 330 | } 331 | __mount_img_to_dir 332 | 333 | local BOOT_PARTUUID=$(blkid -s PARTUUID -o value $MAPPER_DEVICE1) 334 | local ROOTFS_PARTUUID=$(blkid -s PARTUUID -o value $MAPPER_DEVICE2) 335 | 336 | # 导入文件 337 | run_status "add $BOOTLOADER_NAME" dd if=$OUTFILE_boot_bin of=$OUT_IMG_FILE bs=1K seek=8 conv=notrunc 338 | # 使用tar将 TMP_ROOTFS_DIR 路径下的文件全部原封不动的导到TMP_mount_disk2下 339 | echo "move the rootfs files into the image" 340 | tar -cf - -C "$TMP_ROOTFS_DIR" . | tar -xf - -C "$TMP_mount_disk2" 341 | # run_status "add rootfs" tar -cf - -C "$TMP_ROOTFS_DIR" . | tar -xf - -C "$TMP_mount_disk2" 342 | 343 | # 写入uuid 344 | echo "rootdev=PARTUUID=${ROOTFS_PARTUUID}" | sudo tee -a ${TMP_mount_disk1}/config.txt 345 | if [ $IMAGE_FLAG_NO_SCREEN_DISPLAY == $OPT_NO ]; then 346 | echo "PARTUUID=${ROOTFS_PARTUUID} / ext4 defaults,acl,noatime,commit=600,errors=remount-ro 0 1" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 347 | else 348 | echo "PARTUUID=${ROOTFS_PARTUUID} / ext4 ro,defaults,acl,noatime,commit=600,errors=remount-ro 0 1" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 349 | fi 350 | echo "PARTUUID=${BOOT_PARTUUID} /boot vfat defaults 0 0" | sudo tee -a ${TMP_mount_disk2}/etc/fstab 351 | 352 | if [ $IMAGE_FLAG_NO_SCREEN_DISPLAY != $OPT_NO ]; then 353 | local config_file="${TMP_mount_disk1}/config.txt" 354 | run_status "config.txt : console_display=disable" sed -i 's/console_display=enable/console_display=disable/g' "$config_file" 355 | run_status "config.txt : display_bootinfo=disable" sed -i 's/display_bootinfo=enable/display_bootinfo=disable/g' "$config_file" 356 | fi 357 | 358 | local SOURCE_kernel="${PATH_SOURCE}/$(basename "$LINUX_GIT" .git)-$LINUX_BRANCH" 359 | local kernel_version=$(get_linux_version $SOURCE_kernel) 360 | # run_status_no_retry "generate initramfs" chroot $TMP_mount_disk2 /bin/bash -c "DEBIAN_FRONTEND=noninteractive update-initramfs -uv -k $kernel_version" 361 | echo ""generate initramfs"" 362 | run_as_silent chroot $TMP_mount_disk2 /bin/bash -c "DEBIAN_FRONTEND=noninteractive update-initramfs -uv -k $kernel_version" 363 | 364 | trap - SIGINT EXIT 365 | cleanup "$LOOP_DEVICE" 366 | 367 | NEW_IMG_FILE_NAME=$(__get_new_img_file_name "$OUT_IMG_FILE") 368 | mv $OUT_IMG_FILE $NEW_IMG_FILE_NAME 369 | 370 | echo -e "\noutputfile:\n\n\t\033[32m$(du -h ${NEW_IMG_FILE_NAME})\033[0m\n\n" 371 | } 372 | --------------------------------------------------------------------------------