之前看到一位大佬的博客,一下子激起了我为自己树莓派构建系统的兴趣,本文教程基于他的博客进行扩充

本文系统基于Ubuntu Server 20.04.1 LTS(基于Windows 10的VMWare虚拟机),x64架构CPU进行交叉构建。

考虑到有些萌新还没有使用过VMWare虚拟机,本文也将教授虚拟机配置过程。

一、前期准备

1 VMWare Workstation Pro 安装以及虚拟机配置

1.1 安装VMWare Workstation

伸手党福利!官方链接点此即可,点击“立即下载”。安装完后输入许可证密钥(如果没钱激活的话可以自行百度,当然不激活影响不大,只要不被判定为商业用途即可)。

1.2 配置虚拟机

  1. 左上角文件-新建虚拟机
  2. 不要典型!选择自定义!!
  3. 两次下一步之后选择稍后安装操作系统!不要直接选择映像文件!
  4. 客户机操作系统选择Linux-Ubuntu
  5. 名称自定,其他选项根据自身情况配置,下一步即可

1.3 安装系统

  1. 点击此处下载官方Ubuntu映像,建议使用下载工具(IDM等等)
  2. 右键虚拟机-编辑虚拟机设置
  3. 点击CD/DVD,勾选启动时连接,并点击使用ISO映像文件,选择你刚刚下好的映像
  4. 关闭窗口,开启虚拟机

PS. 由于我这里已经安装好系统,此处不再演示

2 安装依赖

# 获取root权限,便于后续操作

sudo su

2.1 换源,系统更新

个人习惯使用nano编辑文件,不喜欢也可使用vim等等

mv /etc/apt/sources.list /etc/apt/sources.list.bak
nano /etc/apt/sources.list

这边采用清华大院开源镜像站TUNA的源,文档来自Ubuntu 镜像使用帮助

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse

Ctrl+OCtrl+X保存并退出。

更新系统

apt update
apt upgrade

2.2 安装应用依赖以及下载文件

一揽子全部安装,省的后面再弄,麻烦。

apt install kpartx build-essential gcc-aarch64-linux-gnu bc bison flex libssl-dev make libc6-dev libncurses5-dev git debootstrap qemu-user-static

下载内核文件准备编译

wget https://cdn.jsdelivr.net/gh/yuzh0816/tools@0.1/firmware.tar.xz
# 此处可能会非常慢,因为文件来自Github
wget -O rpi-firmware.tar.gz https://github.com/Hexxeh/rpi-firmware/tarball/master

二、开始构建

如果想要在工作目录中构建,可以创建文件夹

mkdir debian
cd debian

1 创建镜像

注意,此处设置镜像文件大小为3G,实际情况可以根据自身情况调整

# 创建buster.img空镜像文件
dd if=/dev/zero of=buster.img bs=3G count=0 seek=1

使用cfdisk命令进行GUI模式镜像分区

cfdisk buster.img

创建两个分区,一个是FAT32的boot分区,一个是rootfs分区。

创建镜像

挂载镜像文件并查看挂载的设备名称

losetup -f --show buster.img
查看挂载的设备名称

此时loop设备在/dev/loop8下挂载,我们用kpartx把它两个分区挂载到/dev/mapper

kpartx -va /dev/loop8
挂载

可以看到挂载成功。

这时第一个分区在/dev/mapper/loop8p1,第二个是在/dev/mapper/loop8p2下。

现在格式化这两个分区(记得把下面的目录改成上面显示的loop-p-,警告不用管)。

#格式化boot分区

mkfs.fat -F 32 -n "boot" /dev/mapper/loop8p1

#格式化rootfs,设置label

mkfs.ext4 -L rootfs /dev/mapper/loop8p2
格式化分区

然后,在工作目录下新建两个分区的目录,并挂载。

mkdir boot rootfs
mount /dev/mapper/loop8p1 boot/
mount /dev/mapper/loop8p2 rootfs/

此时,空镜像文件已经制作完成,执行lsblk命令看挂载情况。

挂载情况

第一步完成。

三、RootFS构建

1 初步构建阶段

这里可以选择你想要构建的系统,此处选择为图方便选择Debian。

镜像可以选择的有很多(必须为Debian系统),列举两个清华大学TUNA镜像地址:

  1. Debian
  2. Ubuntu(Ports版,支持Arm64)

经过亲自测试可行的有Debian、UOS和Ubuntu。

# --foreign表示异构系统构建,即在不同CPU架构下进行构建
debootstrap --arch=arm64 --no-merged-usr --foreign buster rootfs/ https://mirrors.tuna.tsinghua.edu.cn/debian/

等待数分钟,执行后rootfs目录结构如下

目录

解压之前下好的压缩包(驱动文件以及固件)

tar -Jxvf firmware.tar.xz -C rootfs/lib/
mkdir rpi-firmware
tar -zxvf rpi-firmware.tar.gz -C rpi-firmware --strip-components 1
cp -r rpi-firmware/vc/hardfp/opt/vc rootfs/opt/
cp -r rpi-firmware/vc/sdk/opt/vc rootfs/opt/

编辑文件系统信息

#此处依然要将loop后的数字进行更改
blkid /dev/mapper/loop8*
blkid

复制两串PARTUUID,粘贴到rootfs/etc/fstab中。

nano rootfs/etc/fstab
fstab

然后换源

nano rootfs/etc/apt/sources.list
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main non-free contrib
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main non-free contrib
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main non-free contrib

2 第二构建阶段

开始构建

chroot rootfs/ debootstrap/debootstrap --second-stage
cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/
chroot构建
完成!

chroot进入系统根目录

chroot rootfs/ /usr/bin/qemu-aarch64-static /bin/bash
chroot

开始进行系统内配置:

1.  更新软件

dpkg --add-architecture armhf
apt update
apt upgrade
更新

2.  安装基本软件以及运行库

apt install libc6:armhf
apt install locales rng-tools wpasupplicant dhcpcd5 sudo parted
apt install net-tools avahi-daemon dphys-swapfile ssh openssh-server 
apt install htop bash-completion wget curl vim nano

3. 添加vc-userland支持

echo "/opt/vc/lib/"   >/etc/ld.so.conf.d/vc-userland.conf
cd /usr/bin/ ; for i in /opt/vc/bin/* ; do ln -sf $i ./ ; done ; cd /

4. 设置内核参数

echo -e "kernel.printk = 3 4 1 3\nvm.min_free_kbytes = 16384" > /etc/sysctl.d/98-rpi.conf
echo -e "net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

5. 设置时区(中国大陆选择上海)

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

6. 配置wpa_supplicant,并链接到boot目录下的wpa_supplicant.conf

ln -sf /usr/share/dhcpcd/hooks/10-wpa_supplicant /lib/dhcpcd/dhcpcd-hooks/10-wpa_supplicant
ln -sf /boot/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf

7. 配置主机名称(引号内“yuzhpi”内容更改为主机名称,可在局域网内显示、连接)

echo "yuzhpi" > /etc/hostname
echo -e "127.0.0.1\yuzhpi" >> /etc/hosts

8. 重新设置软件包区域、语言(经本人尝试,Ubuntu似乎不可行  ||  英语好的可以跳过,这步其实没啥必要)

dpkg-reconfigure locales

空格键选择en_US.UTF-8zh_CN.UTF-8Tab键选择Ok

选择zh_CN.UTF-8Tab选定。

9. 添加用户(最好为pi)

useradd -m -s /bin/bash pi
passwd pi #输入密码x2
echo "pi    ALL=(ALL:ALL)  NOPASSWD: ALL" > /etc/sudoers.d/00_pi

10. 安装常用软件

此处自便,根据需求安装即可。


退出chroot。

sync
exit
echo > rootfs/root/.bash_history #清除bash记录
sync

四、Boot分区(启动分区)配置

基本启动配置

复制Bootloader启动驱动文件

cp rpi-firmware/bootcode.bin rpi-firmware/fixup* rpi-firmware/start* boot/

然后同上文blikd命令,执行下面那句命令,将8改为最早弄的那个数字,保存PARTUUID(其实前面已经执行过了,就是之前让你们保存的那串PARTUUID)

blkid /dev/mapper/loop8p2

编辑cmdline.txt

nano boot/cmdline.txt

粘贴,把UUID覆盖此处UUID。

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=ca013eb7-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

编辑config.txt

nano boot/config.txt

文件内容如下

arm_64bit=1
dtparam=audio=on
[pi4]
dtoverlay=vc4-fkms-v3d
max_framebuffers=2
[all]

无线网络配置

touch boot/wpa_supplicant.conf

如无需配置无线,仅需执行上面那行命令即可。

nano boot/wpa_supplicant.conf

替换提示文本为网络配置。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=CN

network={
    ssid="wifi名称"
    psk="wifi密码"
    key_mgmt=WPA-PSK
    priority=1
}

四、内核构建

Git Clone官方内核

 git clone --depth=1 https://github.com.cnpmjs.org/raspberrypi/linux
git clone

可以通过修改linux/Makefile第五行EXTRAVERSION自定义版本号

e.g: EXTRAVERSION = -yuzh,则显示[版本号]-yuzh

开始编译

这步需要好久。好久。好久。。

cd linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-#可以添加' -j2'实现多核编译,jn即为n核编译
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=../rootfs modules_install

编译期间分配的CPU负载跑满

复制编译好的文件到Boot分区。

cp arch/arm64/boot/Image ../boot/kernel8.img
cp arch/arm64/boot/dts/broadcom/*.dtb ../boot/
cp -r arch/arm64/boot/dts/overlays/ ../boot/

五、大功告成

同步并卸载镜像。

cd ../
sync
umount boot/
umount rootfs/

取消挂载(你也可以选择关闭虚拟机),依然需要更改数字。

kpartx -d /dev/loop8
losetup -d /dev/loop8

把镜像从虚拟机复制出来,即可刷入板子。目前兼容3B3B+4B

六、总结

踩过的坑: 

  1. 有许多软件不兼容chroot内部进行,需要在板子上实操才行。
  2. 本以为编译速度很快,没想到速度这么慢。。
  3. 构建镜像中途不小心退出,且没有sync,需全部重头来过

快捷工具:

  1. Github Zip下载器,曲线救国