前言

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 $(curl -fsSL https://is.gd/depend_ubuntu2204_armbian)
    # 清理
    sudo apt autoremove --purge
    sudo apt clean
    

编译镜像

拉取 Armbian 源码

git clone --single-branch --depth=1 --branch=main https://github.com/armbian/build.git build
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-get update
    apt-get 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://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
    apt-get update
    apt-get 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": "10m",
       "max-file": "1"
     },
     "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/serial[email protected]/override.conf
    systemctl daemon-reload
    
    # 设置开机自启脚本(脚本文件自行创建)
    mv /tmp/overlay/init.sh /root
    chmod +x /root/init.sh
    ## 将要开机执行的命令添加到 /etc/rc.local 中 'exit 0' 的上面即可
    sed -i 's/^exit 0$//g' /etc/rc.local
    cat >>/etc/rc.local <<'EOF'
    bash /root/init.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 命令然后根据提示操作,要实现自动写入则需要利用上方创建的 init.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为例,其他设备需要修改101为对应选项
    echo "Automatic restart will occur in 3 seconds."
    echo "Please remove the USB flash drive after system restart!"
    echo "Please remove the USB flash drive after system restart!"
    echo "Please remove the USB flash drive after system restart!"
    sleep 3
    poweroff
    fi
    
    
  4. 其他自定义需求

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

开始编译

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

# RELEASE: bullseye 代表 Debian 11,jammy 代表 Ubuntu 22,其他参数不要修改
./compile.sh RELEASE=bullseye BUILD_MINIMAL=no \
    BOARD=odroidn2 BRANCH=current BUILD_ONLY=default HOST=armbian BUILD_DESKTOP=no EXPERT=yes \
    KERNEL_CONFIGURE=no CLEAN_LEVEL="make,cache,alldebs,sources" 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 根目录,然后运行如下命令即可生成指定 board 的 Armbian 镜像文件
    sudo ./rebuild -b s905d -k 6.1.21
    

    打包参数说明:本地化打包说明

  3. 至此,镜像编译完成,新的镜像同样保存在 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
    
    # 重新压缩
    gzip filename.img
    

参考文档


Never give up your dreams.