“一只公鸡要下蛋,不是它的活它要干。”
开始之前
编译设备需要具有网络连接以及5GB的空闲磁盘空间
因为整个过程将不生成镜像文件,直接把系统写入磁盘,所以需要一张额外的空白MicroSD储存卡(推荐至少8GB),以及相应的读卡器
为了节省时间,除/boot外,/home、/proc等都将直接包含在/下,不额外进行分区

所有操作均在
Debian发行版系统上完成
磁盘分区
将准备好的sd卡放入读卡器,插入编译设备的USB口让系统进行识别,准备开始分区工作
如果没有接入其他的储存设备,那么新的设备将在/dev/sdb处
执行以下命令开始磁盘分区:sudo /sbin/fdisk /dev/sdb
成功进入fdisk后,首先输入p并回车,让fdisk打印磁盘信息,记录磁盘标识符 (Disk identifier)的值(如:0xac9d888d),这在之后会用到

观察磁盘标签类型 (Disklabel type)的值,如果不是dos则输入o并回车,将磁盘的分区表修改为DOS,之后便可进行分区
- 输入
n并回车,创建第一个分区(启动分区)
分区类型 (Partition type)与分区号 (Partition number)以及First sector (第一个扇区)选项保持默认,无需输入任何数值,直接回车
在最后一个扇区 (Last sector)选项输入526335,回车完成分区创建,此时将回到fdisk主菜单
回到主菜单后,输入t并回车
fdisk将自动跳转到Hex代码或别名 (Hex code or alias)选项,输入b,回车修改分区文件系统类型为W95 FAT32
完成分区文件系统类型更改后,将再次回到fdisk主菜单
输入a并回车,fidks将自动为分区添加“可启动”标识 - 输入
n并回车,创建第二个分区(系统分区)
分区类型 (Partition type)与分区号 (Partition number)以及First sector (第一个扇区)依旧保持默认选项
在最后一个扇区 (Last sector)选项时,如不使用交换分区,则直接回车,完成分区工作;如需使用交换分区,则输入结束扇区的扇区号并回车完成第二分区分区工作 - 【可跳过】输入
n并回车,创建第三个分区(交换分区)
所有选项全部保持默认,一路回车完成创建工作并回到fdisk主菜单
回到主菜单后,输入t并回车
在分区号 (Partition number)选项输入3,回车
在Hex代码或别名 (Hex code or alias)选项输入82,回车完成分区工作
执行完上述操作后,输入w并回车,让fdisk将更改写入磁盘,写入完成后,fdisk将自动退出
最后使用mkfs系列命令进行分区格式化
- 格式化启动分区:
sudo /sbin/mkfs.vfat /dev/sdb1 - 格式化系统分区:
sudo /sbin/mkfs.ext4 /dev/sdb2

构建内核
首先需获取构建内核所需要的依赖
- 如果需构建32位系统,请执行以下命令:
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev sudo apt install crossbuild-essential-armhf - 如果需构建64位系统,请执行以下命令:
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev sudo apt install crossbuild-essential-arm64
当命令执行完成后,执行git clone --depth=1 https://github.com/raspberrypi/linux下载内核源码
如果需要获取不同版本的源码,请参考该命令:
git clone --depth=1 --branch <branch> https://github.com/raspberrypi/linux
在Github的版本列表中一众以rpi-开头的分支才是内核源码
源码下载完成后,对于不同的设备,接下来的操作也会有些许不同
构建32位系统:
- 如果正在为
Raspberry Pi 1、Raspberry Pi Zero、Raspberry Pi Zero W、Raspberry Pi Compute Module 1构建32位操作系统,请执行以下命令:cd linux KERNEL=kernel make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig - 如果正在为
Raspberry Pi 2、Raspberry Pi 3、Raspberry Pi 3+、Raspberry Pi Zero 2 W、Raspberry Pi Compute Modules 3、Raspberry Pi Compute Modules 3+构建32位操作系统,请执行以下命令:cd linux KERNEL=kernel7 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig - 如果正在为
Raspberry Pi 4、Raspberry Pi 400、Raspberry Pi Compute Module 4构建32位操作系统,请执行以下命令cd linux KERNEL=kernel7l make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
构建64位系统:
- 如果正在为
Raspberry Pi 3、Raspberry Pi 3+、Raspberry Pi 4、Raspberry Pi 400、Raspberry Pi Zero 2 W、Raspberry Pi Compute Modules 3、Raspberry Pi Compute Modules 3+、Raspberry Pi Compute Modules 4构建64位操作系统,请执行以下命令:cd linux KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
在正式构建前,可以使用menuconfig修改内核的配置
注意,该步骤并不是必要的,有时候保持默认配置并不是一个坏的选择
开始使用menuconfig前,请执行sudo apt install libncurses5-dev以确保必要依赖
命令执行完成后,即可使用menuconfig修改内核配置
- 对于32位内核,使用下方命令修改配置:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig - 对于64位内核,使用下方命令修改配置:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

(以下内容为树莓派官方文档中对
menuconfig的介绍,原文英文,由机器翻译)
menuconfig实用程序具有简单的键盘导航功能。经过简短的编译后,您将看到一个子菜单列表,其中包含您可以配置的所有选项;有很多,所以花点时间仔细阅读并熟悉一下。
使用箭头键进行导航,使用Enter键进入子菜单(由--->指示),使用Escape两次进入上一级或退出,使用空格键循环选项的状态。有些选项有多个选项,在这种情况下,它们将显示为子菜单,并按Enter键选择一个选项。您可以在大多数条目上按h来获取有关特定选项或菜单的帮助。
在你的第一次尝试中,要抵制启用或禁用很多东西的诱惑;破坏配置相对容易,所以从小处着手,熟悉配置和构建过程。
完成内核配置后,即可开始进行编译工作
- 对于32位内核,请执行以下命令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j2 zImage modules dtbs - 对于64位内核,请执行以下命令:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j2 Image modules dtbs
内核的编译将耗费大量的时间以及CPU资源,请保持编译设备拥有充足的电源以及良好的散热
制作rootfs
在内核编译完成后,使用cd ../回到上一级目录
在开始前请先执行sudo apt install qemu qemu-user-static binfmt-support debootstrap安装所需依赖
安装完成后,创建sdcard文件夹并cd进入,并在其中创建rootfs文件夹,用于挂载sd卡
执行sudo mount /dev/sdb2 rootfs/挂载已格式化的文件系统
接着使用debootstrap构建基础系统
命令参考:
debootstrap --foreign --arch [体系结构] [发行版本代号] [目录] [下载源]
[下载源]参数如不填则将使用默认的下载站点
下方链接中包含了所有可用的下载源,替换默认源请使用离自己最近的站点:
https://www.debian.org/mirror/list
由于编译设备系统与目标系统的体系架构不相同,添加了
--foreign参数
debootstrap在安装后存在于/sbin下,并且需要root权限
这里以构建arm64体系结构,版本为bullseye的基础系统作为示例参考:
sudo /sbin/debootstrap --foreign --arch=arm64 bullseye rootfs/

在debootstrap执行完成后,将qumu-user-static包提供的文件拷贝到rootfs内,让编译设备系统能够chroot到arm架构的系统内
- 对于32位系统:
sudo cp -a /usr/bin/qemu-arm-static rootfs/usr/bin/ - 对于64位系统:
sudo cp -a /usr/bin/qemu-aarch64-static rootfs/usr/bin/
下载ch-mount.sh到文件夹中,用以进入制作好的rootfs
wget https://raw.githubusercontent.com/psachin/bash_scripts/master/ch-mount.sh
使用chmod +x ./ch-mount.sh赋予脚本执行权限,再使用./ch-mount.sh -m rootfs/生成临时挂载点并进入rootfs
脚本执行时会请求
root权限,但不要以root身份执行脚本
进入rootfs后,可能会出现I have no name!字样,为正常现象
接下来如无特殊说明,本节内的所有操作均在rootfs内的系统中完成

debootstrap二次解压:debootstrap/debootstrap --second-stage
命令执行成功后将会输出以下信息:
I: Base system installed successfully.
解压完成后,需先执行apt install ca-certificates为rootfs内的系统安装CA证书
证书安装完毕后,便可以打开/etc/apt/source.list文件更换镜像源
更换镜像源后,执行apt update更新软件列表,完成后继续安装必要程序
apt install dhcpcd5 locales sudo wget
执行useradd添加用户,例如:useradd nolen
修改新用户的密码,例如:passwd nolen
打开/etc/sudoers文件,在# User privilege specification下方新增一行,允许用户使用sudo命令:
nolen ALL=(ALL:ALL) ALL

在修改sudoer文件时,可能遭遇
W10: Warning: Changing a readonly file警告
这时只需退出编辑器,使用chmod 640 /etc/sudoers修改sudoers文件的权限即可
不要忘记修改回去:chmod 440 /etc/sudoers
打开/etc/fstab文件,修改其中内容,让内核能够正常挂载文件系统,例如:
# UNCONFIGURED FSTAB FOR BASE SYSTEM
proc /proc proc defaults 0 0
PARTUUID=ac9d888d-01 /boot vfat defaults 0 2
PARTUUID=ac9d888d-02 / ext4 defaults,noatime 0 1
PARTUUID=ac9d888d-03 swap swap defaults 0 0
在示例中
ac9d888d是之前分区时获取到的磁盘id:0xac9d888d
后方的-01、-02代表着磁盘的第一个分区(启动分区)、第二个分区(系统分区)
ac9d888d-03是交换分区
格式参考:
<file system> <mount point> <type> <options> <dump> <pass>
<file system>- 为要挂载的分区或存储设备,即相应的UUID
<mount point>- 为挂载点
<type>- 为文件系统类型
<options>- 为挂载时使用的参数
<dump>- 为是否做备份
<pass>- 为需要检查的文件系统的检查顺序

最后可以修改/etc/hostname修改主机名称,例如:echo 'my-rpi' > /etc/hostname
以及在/etc/hosts中新增127.0.0.1 my-rpi以防止sudo命令出现警告信息
完成后即可输入exit退出rootfs,然后使用./ch-mount -u rootfs/卸载掉临时挂载点
安装内核以及驱动
执行sudo mount /dev/sdb1 boot/挂载已格式化的文件系统
使用cd ../linux切换到内核源码目录,为rootfs中的系统安装必要模块
- 对于32位系统,请执行以下命令:
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../sdcard/rootfs modules_install - 对于64位系统,请执行以下命令:
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=../sdcard/rootfs modules_install
在系统模块安装完成后,即可将内核以及驱动放入启动分区
- 对于32位系统,请执行以下命令:
sudo cp arch/arm/boot/dts/*.dtb ../sdcard/boot/ sudo cp arch/arm/boot/dts/overlays/*.dtb* ../sdcard/boot/overlays/ sudo cp arch/arm/boot/dts/overlays/README ../sdcard/boot/overlays/ sudo cp arch/arm/boot/zImage ../sdcard/boot/$KERNEL.img - 对于64位系统,请执行以下命令:
sudo cp arch/arm64/boot/dts/broadcom/*.dtb ../sdcard/boot/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* ../sdcard/boot/overlays/ sudo cp arch/arm64/boot/dts/overlays/README ../sdcard/boot/overlays/ sudo cp arch/arm64/boot/Image ../sdcard/boot/$KERNEL.img
虽然内核以及驱动都以安装完成,但缺少启动必要文件
cd ../回到上一级,执行git clone --depth=1 https://github.com/raspberrypi/firmware获取文件
当文件拉取完成后,执行以下命令将文件放入启动分区:
sudo cp firmware/boot/*.dat sdcard/boot/
sudo cp firmware/boot/*.elf sdcard/boot/
文件复制完成后,使用cd命令切换到已挂载的启动分区内,创建启动配置文件cmdline.txt以及内核配置文件config.txt
cd sdcard/boot/
sudo touch cmdline.txt
sudo touch config.txt

打开并修改cmdline.txt文件内容:
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=ac9d888d-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles psi=1
cmdline.txt中root=PARTUUID=选项的值指向的是磁盘系统分区,注意替换
打开并修改config.txt文件内容:
- 对于32位系统:
[all] arm_64bit=0 framebuffer_width=1280 framebuffer_height=720 disable_overscan=1 dtparam=audio=on - 对于64位系统
[all] arm_64bit=1 framebuffer_width=1280 framebuffer_height=720 disable_overscan=1 dtparam=audio=on
完成后回到上一级目录,卸载各文件系统
cd ../
sudo umount boot/
sudo umount rootfs/
