前言

Armbian 是一套以 Linux 为基础的针对 Arm 架构及相关硬件所开发的轻量级软件系统,而且主要面向嵌入式体系架构的单板机(SBCs)应用场景,比如电视盒子、游戏机、NAS、媒体播放器、个人小电脑等等。目前 Armbian 支持 Debian 和 Ubuntu 的编译选项,可以生成具有字符或图形界面的运行系统。

此教程适用于 Amlogic S9xxx 系列处理器和 Rockchip 盒子,编译一次需要1-3小时左右,需要耐心等待,理论上 CPU 核心数越多编译越快。

环境要求

  1. 系统版本

    推荐 Debian 11 或者 Ubuntu 22.04

  2. 配置要求

    至少 4G RAM,SSD,推荐4核处理器以上,预留 25G 硬盘空间

  3. 网络要求

    最好是境外主机或者能够访问国际网络,大陆网络环境编译耗时久且需要修改地方较多

  4. 编译依赖

    # 升级
    sudo apt update -y
    sudo apt full-upgrade -y
    # 安装依赖
    sudo apt install -y acl aptly aria2 bc binfmt-support bison \
       btrfs-progs build-essential busybox ca-certificates ccache clang \
       coreutils cpio crossbuild-essential-arm64 cryptsetup curl \
       debian-archive-keyring debian-keyring debootstrap device-tree-compiler \
       dialog dirmngr distcc dosfstools dwarves f2fs-tools fakeroot flex gawk \
       gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi gdisk git gpg gzip \
       imagemagick jq kmod lib32ncurses-dev lib32stdc++6 libbison-dev \
       libc6-dev-armhf-cross libc6-i386 libcrypto++-dev libelf-dev \
       libfdt-dev libfile-fcntllock-perl libfl-dev liblz4-tool libncurses-dev \
       libncurses5 libncurses5-dev libncursesw5-dev libpython2.7-dev libssl-dev \
       libusb-1.0-0-dev linux-base lld llvm locales lz4 lzma lzop mtools \
       ncurses-base ncurses-term nfs-kernel-server ntpdate p7zip p7zip-full \
       parallel parted patchutils pigz pixz pkg-config pv python2 python3 \
       python3-dev python3-distutils qemu-user-static rename rsync subversion \
       swig tar u-boot-tools udev unzip uuid uuid-dev uuid-runtime vim wget \
       whiptail xsltproc xz-utils zip zlib1g-dev zstd
    # 清理
    sudo apt autoremove --purge
    sudo apt clean
    

编译镜像

拉取 Armbian 源码

git clone https://github.com/armbian/build.git
cd build

自定义配置

  1. 安装特定的软件包

    安装特定的软件包只要在 userpatches/lib.config 中增加下面一行即可(文件目录请自行创建),当然也可以写在下面的自定义脚本中运行(推荐):

    # PACKAGE_LIST_ADDITIONAL="$PACKAGE_LIST_ADDITIONAL package_name"
    PACKAGE_LIST_ADDITIONAL="$PACKAGE_LIST_ADDITIONAL python-serial python" # additional packages
    

    建议仔细阅读分析一下 lib/functions/configuration/main-config.sh 这个文件,里面定义了编译中所使用的环境变量,修改相应的变量可以改变编译结果,当然不是在这个文件中直接修改,而是放到 lib.config当中做调整。

  2. 在编译的镜像中运行自定义命令

    方法是在 userpatches 目录中创建脚本文件 customize-image.sh,写入需要执行的命令,这些命令是在 chroot 环境中运行的,该脚本文件是在编译完成后并在生成最终目标镜像之前被执行。如果要复制文件到镜像中,需要将文件放在 userpatches/overlay下,然后在 customize-image.sh 通过 /tmp/overlay 路径进行访问。官方提供了一个模版可以参考,下面是我列出的一些常用命令:

    #!/bin/bash
    # 修改软件源
    cat >/etc/apt/sources.list <<'EOF'
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
    deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
    EOF
    cat >/etc/apt/sources.list.d/armbian.list <<'EOF'
    deb https://mirrors.tuna.tsinghua.edu.cn/armbian bullseye main bullseye-utils bullseye-desktop
    EOF
    
    # 安装常用依赖
    apt update
    apt dist-upgrade -y
    apt install -y apt-transport-https ca-certificates \
       curl gnupg lsb-release pciutils net-tools iperf3 zip unzip \
       ntpdate iputils-ping vim iftop iotop mtr wget sudo qrencode \
       python3 python3-pip python3-venv
    
    # 修改默认 Python 版本
    ln -s /usr/bin/python3 /usr/bin/python
    
    # 安装 Docker
    curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
    apt update
    apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    systemctl enable docker --now
    mkdir /etc/docker
    cat >/etc/docker/daemon.json <<'EOF'
    {
     "log-driver": "json-file",
     "log-opts": {
       "max-size": "100m"
     },
     "storage-driver": "overlay2"
    }
    EOF
    systemctl daemon-reload
    systemctl restart docker
    
    # 取消首次登录创建新用户步骤并修改 root 用户密码
    # 不修改的默认用户密码是 root/1234
    rm -f /root/.not_logged_in_yet
    echo "root:1234567" | chpasswd
    
    # 关闭 root 用户终端自动登陆
    rm -f /etc/systemd/system/[email protected]/override.conf
    rm -f /etc/systemd/system/[email protected]/override.conf
    systemctl daemon-reload
    
    # 设置开机自启脚本(脚本文件自行创建)
    mv /tmp/overlay/initialization.sh /root
    chmod +x /root/initialization.sh
    ## 将要开机执行的命令添加到 /etc/rc.local 中 'exit 0' 的上面即可
    sed -i 's/^exit 0$//g' /etc/rc.local
    cat >>/etc/rc.local <<'EOF'
    bash /root/initialization.sh
    exit 0
    EOF
    chmod a+x /etc/rc.local
    systemctl enable rc-local
    
    # 清理缓存
    apt autoremove -y && apt autoclean && apt remove -y && apt clean
    
  3. 实现 EMMC 自动写入

    默认不会自动写入 EMMC,系统需要插着U盘才能使用,手动写入需要进入系统执行 armbian-install 命令然后根据提示操作,要实现自动写入则需要利用上方创建的 initialization.sh 开机自启脚本,脚本内容如下,详见注释:

    #!/bin/bash
    INSTALLED="/root/.installed"
    if [ ! -d "$INSTALLED" ]; then
     mkdir $INSTALLED
    fi
    
    # 修改 DNS
    cat >/etc/resolv.conf <<'EOF'
    nameserver 114.114.114.114
    nameserver 119.29.29.29
    nameserver 223.5.5.5
    EOF
    
    # EMMC 自动写入(一定要最后执行)
    if [ ! -f "$INSTALLED/emmc" ]; then
     touch $INSTALLED/emmc
     echo -e "101\n1" | (/usr/sbin/armbian-install) # 这里是斐讯N1的自动写入
     poweroff
    fi
    
    
  4. 其他自定义需求

    官方文档的这个页面有很详细的说明

开始编译

编译速度取决于你的机器 CPU 性能和核心数

# RELEASE: bullseye 代表 Debian 11,jammy 代表 Ubuntu 22,其他参数不要修改
sudo ./compile.sh RELEASE=bullseye BOARD=odroidn2 BRANCH=current BUILD_DESKTOP=no HOST=armbian EXPERT=yes \
    BUILD_MINIMAL=no KERNEL_ONLY=no KERNEL_CONFIGURE=no CLEAN_LEVEL=make,debs COMPRESS_OUTPUTIMAGE="sha"

完整参数列表参考:https://docs.armbian.com/Developer-Guide_Build-Options/

打包镜像

编译成功的镜像文件不能直接写到U盘去引导,因为只有一个根文件系统,N1 的引导需要有引导分区和根文件系统分区,所以需要重新打包可引导的映像。

  1. 拉取源码
    # 拉取源码
    git clone https://github.com/ophub/amlogic-s9xxx-armbian.git
    # 进入 amlogic-s9xxx-armbian 根目录
    cd amlogic-s9xxx-armbian
    
  2. 打包镜像
    # 在 amlogic-s9xxx-armbian 目录下创建文件夹 build/output/images
    mkdir -p build/output/images
    # 拷贝上面编译好的 Armbian 镜像到 amlogic-s9xxx-armbian/build/output/images 目录里
    ## Armbian 镜像文件名称中的发行版本号(如:21.11.0)和内核版本号(如:5.15.50)请保留,它将在重构后用作 Armbian 固件的名称
    ## 进入 amlogic-s9xxx-armbian 根目录,然后运行 sudo ./rebuild -b s905d -k 5.10.125 命令即可生成指定 board 的 Armbian 镜像文件
    sudo ./rebuild -b s905d -k 5.10.158
    
参数含义说明
-bBoard指定电视盒子型号,如 -b s905x3 . 多个型号使用 _ 进行连接,如 -b s905x3_s905d . 使用 all 表示全部型号。可以指定的型号有: a311d, s905x3, s905x3-b, s905x2, s905l3a, s905x, s905w, s905d, s905d-ki, s905l2, s905, s922x, s922x-n2, s912, s912-m8s 。说明:s922x-revas922x-gtking-pro-rev_as922x-n2s922x-odroid-n2s912-m8ss912-mecool-m8s-pro-ls905d-kis905d-mecool-ki-pros905x2-km3s905x2-mecool-km3
-kKernel指定 kernel 名称,如 -k 5.10.125 . 多个内核使用 _ 进行连接,如 -k 5.10.125_5.15.50
-aAutoKernel设置是否自动采用同系列最新版本内核。当为 true 时,将自动在内核库中查找在 -k 中指定的内核如 5.10.125 的同系列是否有更新的版本,如有 5.10.125 之后的最新版本时,将自动更换为最新版。设置为 false 时将编译指定版本内核。默认值:true
-vVersion指定内核 版本分支 名称,如 -v stable_rk3588 。指定的名称须与分支目录名称相同。默认使用 stable_rk3588 分支版本。
-rKernelRepository指定内核仓库地址,如 -r https://github.com/ophub/kernel/tree/main/pub 。默认使用 ophub/kernel 的内核仓库。
-sSize对固件的 ROOTFS 分区大小进行设置,默认大小为 2560MiB, 固件大小必须大于 2048MiB. 例如: -s 2560
-tRootfsType对固件的 ROOTFS 分区的文件系统类型进行设置,默认为 ext4 类型,可选项为 ext4btrfs 类型。例如: -t btrfs
-nCustomName设置固件名称中的签名部分。默认值为空。可根据需要添加签名如 _server_gnome_desktop_ophub 等,设置自定义签名时请勿包含空格。
  • sudo ./rebuild : 使用默认配置,对全部型号的电视盒子进行打包。
  • sudo ./rebuild -b s905x3 -k 5.10.125 : 推荐使用. 使用默认配置进行相关内核打包。
  • sudo ./rebuild -b s905x3_s905d -k 5.10.125_5.15.50 : 使用默认配置,进行多个内核同时打包。使用 _ 进行多内核参数连接。
  • sudo ./rebuild -b s905x3 -k 5.10.125 -s 2560 : 使用默认配置,指定一个内核,一个型号进行打包,固件大小设定为2560MiB。
  • sudo ./rebuild -b s905x3 -v dev -k 5.10.125 : 使用默认配置,指定型号,指定版本分支,指定内核进行打包。
  • sudo ./rebuild -b s905x3_s905d 使用默认配置,对多个型号的电视盒子进行全部内核打包, 使用 _ 进行多型号连接。
  • sudo ./rebuild -k 5.10.125_5.15.50 : 使用默认配置,指定多个内核,进行全部型号电视盒子进行打包, 内核包使用 _ 进行连接。
  • sudo ./rebuild -k 5.10.125_5.15.50 -a true : 使用默认配置,指定多个内核,进行全部型号电视盒子进行打包, 内核包使用 _ 进行连接。自动升级到同系列最新内核。
  • sudo ./rebuild -t btrfs -s 2560 -k 5.10.125 : 使用默认配置,设置文件系统为 btrfs 格式,分区大小为 2560MiB, 并指定内核为 5.10.125 ,对全部型号电视盒子进行打包。
  1. 至此,镜像编译完成,新的镜像同样保存在 build/output/images 目录

编辑镜像

涉及镜像文件内容变更时,不需要重新编译镜像,直接挂载编辑镜像文件即可。

  1. 解压已经打包好的镜像,查看镜像分区信息
    # 使用下方命令可以查看镜像分区信息
    fdisk -l filename.img
    
  2. 挂载 img 系统镜像分区
    # 查询下一个可用 loop 设备文件,假设是 /dev/loop0
    losetup -f
    
    # 使用 losetup -P 参数挂载 img 文件
    losetup -P /dev/loop0 filename.img
    lsblk
    
    # 一般会有两个分区,分别为启动分区和文件系统分区
    mkdir boot
    mkdir rootfs
    mount /dev/loop0p1 ./boot/
    mount /dev/loop0p2 ./rootfs/
    
    # 现在就可以根据需要修改镜像了,可执行文件别忘了赋权
    
  3. 编辑完成后,卸载镜像
    umount /dev/loop0p1
    umount /dev/loop0p2
    losetup -d /dev/loop0
    

参考文档


Never give up your dreams.