RaspberryPi4B移植64位Debian

运行环境

获取根文件系统

1
2
3
4
5
sudo su
apt install debootstrap fdisk dosfstools
ROOTFS_PATH=/opt/debian
mkdir $ROOTFS_PATH /mnt/boot/ /mnt/root/
debootstrap --arch=arm64 stable $ROOTFS_PATH http://ftp2.cn.debian.org/debian

进入根文件系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 挂载主机设备并chroot到根文件系统内
mount -o bind /dev $ROOTFS_PATH/dev
mount -o bind /proc $ROOTFS_PATH/proc
mount -o bind /sys $ROOTFS_PATH/sys
chroot $ROOTFS_PATH /bin/bash -l

# 进入chroot环境后可安装额外软件
apt install sudo vim openssh-server cpufrequtils parted
apt install wireless-tools wpasupplicant bluez bluez-tools
apt install alsa-utils pulseaudio pulseaudio-module-bluetooth
apt install pciutils usbutils dnsmasq hostapd bridge-utils

# 添加一个用户并赋予sudo权限
useradd -m -g sudo -s /bin/bash pi
passwd pi
echo "pi ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chown -R pi:sudo /home/pi

# 设置DNS和软件源
echo "LC_ALL=C" > /etc/default/locale
echo "nameserver 127.0.0.1" > /etc/resolv.conf
echo "nameserver 114.114.114.114" >> /etc/resolv.conf
echo "deb http://ftp2.cn.debian.org/debian/ buster main non-free contrib" > /etc/apt/sources.list

# 设置主机名和时区并允许SSH使用密码登录
echo RPI4 > /etc/hostname
sed -i '/localhost/s/$/\t'"RPI4"'/g' /etc/hosts
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config

# 清理所有已缓存的包
apt clean

添加内核和扩容脚本

  1. 安装自己编译的内核和无线驱动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 前面设置完成后就可以退出chroot环境了
umount $ROOTFS_PATH/dev
umount $ROOTFS_PATH/proc
umount $ROOTFS_PATH/sys

# 安装无线网卡和蓝牙固件到根文件系统
wget https://github.com/RPi-Distro/bluez-firmware/raw/master/broadcom/BCM4345C0.hcd
wget https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm/brcmfmac43455-sdio.bin
wget https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm/brcmfmac43455-sdio.clm_blob
wget https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm/brcmfmac43455-sdio.txt
cp BCM4345C0.hcd $ROOTFS_PATH/lib/firmware/brcm/
cp *sdio* $ROOTFS_PATH/lib/firmware/brcm/

# 复制内核模块及头文件到根文件系统
tar -xzvf raspbian-kernel-kvm.tgz # 自编译的树莓派内核,详见RaspberryPi4B编译含KVM的64位内核
mv /home/pi/kernel/lib/modules/ $ROOTFS_PATH/lib/
mv /home/pi/kernel/usr/include/* $ROOTFS_PATH/usr/include/
  1. 复制下面自动扩容脚本到$ROOTFS_PATH/usr/lib/resize.sh,并使其可被执行 chmod +x resize.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash

# 挂载设备及定义变量
mount -t proc proc /proc
mount -t sysfs sysfs /sys
ROOT_PART_DEV=$(findmnt / -o source -n)
ROOT_PART_NUM=$(echo $ROOT_PART_DEV | grep -o "[0-9]$")
ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
ROOT_DEV_NAME=/dev/$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
mount /boot
mount -o remount,rw $ROOT_PART_DEV

# 扩容分区并重载分区
parted -s $ROOT_DEV_NAME -- resizepart $ROOT_PART_NUM 100%
partprobe $ROOT_PART_DEV
resize2fs -f $ROOT_PART_DEV

# 删除参数并重启系统
sed -i 's| init=/usr/lib/resize\.sh||' /boot/cmdline.txt
sed -i "s/ quiet//g" /boot/cmdline.txt
sync
sleep 5
echo b > /proc/sysrq-trigger

复制系统到SD卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 树莓派仅支持从msdos/mbr类型的分区表中的FAT32文件系统启动,转换GPT为MBR分区表
parted /dev/sda mktable msdos

# 使用du -h分别查看/mnt/boot/和/mnt/root/的大小。例如boot占用16M大小,root占用555M
# 使用fdisk为插入读卡器内的SD卡创建两个大于占用的分区,例如:boot分区64M,root分区836M
fdisk -l /dev/sda
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 133120 131073 64M b W95 FAT32 (LBA)
/dev/sda2 135168 1847296 1712129 836M 83 Linux

# 格式化分区并挂载,FAT32不支持小于32MB的分区
mkfs.vfat -F 32 /dev/sda1
mkfs.ext4 /dev/sda2

# 想要树莓派4B启动Linux,boot分区下必须拥有以下七个文件:
fixup4.dat start4.elf :适用于4B的引导程序
kernel8.img config.txt cmdline.txt :内核及启动配置文件
bcm2711-rpi-4-b.dtb overlays/ :设备树文件

# 复制启动文件和根文件系统到SD卡的对应分区
mount /dev/sda1 /mnt/boot/
mount /dev/sda2 /mnt/root/
cp -r /home/pi/kernel/boot/* /mnt/boot/
cp -r $ROOTFS_PATH/* /mnt/root/

# /mnt/root/config.txt文件的内容
arm_64bit=1
kernel=kernel-kvm.img
dtparam=audio=on
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

# /mnt/boot/cmdline.txt文件的内容,修改PARTUUID的值为sda2对应的值
console=serial0,115200 console=tty1 root=PARTUUID=c2d20ef0-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/resize.sh

# 查看sda的PARTUUID值
ls -l /dev/disk/by-partuuid/
lrwxrwxrwx 1 root root 10 Dec 27 2019 c2d20ef0-01 -> ../../sda1
lrwxrwxrwx 1 root root 10 Dec 27 2019 c2d20ef0-02 -> ../../sda2

# 修改/mnt/root/etc/fstab中的内容为以下
proc /proc proc defaults 0 0
PARTUUID=c2d20ef0-01 /boot vfat defaults 0 2
PARTUUID=c2d20ef0-02 / ext4 defaults,noatime 0 1

chmod 4755 /mnt/root/usr/bin/sudo # 解决无法使用sudo的问题
# 最后将SD卡插入树莓派上电试试看是否正常使用,如果正常就可以制作IMG镜像了

制作IMG镜像文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 首先清理遗留的垃圾文件
rm /mnt/root/root/.bash_history
rm /mnt/root/root/.bash_logout

cd /var/log/
rm alternatives.log auth.log* daemon.log* debug dpkg.log \
fontconfig.log kern.log lastlog messages syslog user.log

# 然后查看前面插入的SD卡分区信息
fdisk -l /dev/sda
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 133120 131073 64M b W95 FAT32
/dev/sda2 135168 1847296 1712129 836M 83 Linux

# 最后使用dd命令把有数据的扇区导出到img镜像文件
dd if=/dev/sda of=debian-buster-arm64.img bs=512 count=1847297

# 因为最后一个分区的End扇区是:1847296
# 扇区又是从0开始编号的,所以总扇区数要多加1个变成了:1847297
# 每个扇区又是512字节,所以总占用的字节数为:(1847296 + 1) * 512
# dd命令的bs代表每次导出多少数据,count是导出次数。如上每次dd 512KB共dd 1847297次

其他使用问题

  1. 使用WiFi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apt install wireless-tools wpasupplicant
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf

# 配置文件路径:/etc/wpa_supplicant/wpa_supplicant.conf
# 允许使用wpa_cli扫描可用的网络和netdev组中的用户控制wpa_supplicant
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1 # 允许保存的连接信息覆盖配置

network={
ssid="AP-NAME" # 接入点的名称
psk="password" # 接入点的密码
scan_ssid=1 # 连接隐藏的点
priority=5 # 连接的优先级
}

network={ # 连接开放接入点
ssid="AP-NAME"
key_mgmt=NONE
}

# 最后使用DHCP客户端为其获取IP地址
dhclient wlan0
  1. 使用蓝牙
1
2
3
4
5
6
7
8
9
10
apt install bluez bluez-tools
hciattach /dev/ttyAMA0 bcm43xx 921600 noflow - # 启动蓝牙
hciconfig -a # 查看设备
bluetoothctl # 进入交互,后面是在bluetoothctl交互环境中执行
[bluetooth]# power on # 打开蓝牙
[bluetooth]# agent on # 启动代理
[bluetooth]# scan on # 开始扫描
[bluetooth]# pair F4:4E:FD:F0:2A:69 # 设备配对
[bluetooth]# trust F4:4E:FD:F0:2A:69 # 添加信任
[bluetooth]# connect F4:4E:FD:F0:2A:69 # 连接设备
  1. 播放音频
1
2
3
4
5
# 编辑 /etc/pulse/daemon.conf 取消注释(删除;)并放入负值:exit-idle-time = -1
apt install alsa-utils pulseaudio mpg123
pulseaudio --start # 启动PA服务
alsamixer # 调节音量,按F6可选择输出声卡
mpg123 xxx.mp3 # 测试mp3播放
  1. 手动扩容
1
2
3
4
5
6
7
8
9
10
11
12
# 如果自动扩容失败,可通过下面操作来扩容root分区到100%
parted /dev/mmcblk0 resizepart 2 100%
partprobe /dev/mmcblk0p2
resize2fs /dev/mmcblk0p2

# 其他磁盘操作命令备忘
parted /dev/sda print # 查看当前分区表类型
parted /dev/sda mktable msdos # 转换GPT为MBR分区表
parted /dev/sda mkpart primary fat32 1 65M # 先创建boot启动分区
parted /dev/sda mkpart primary ext4 65M 800M # 再创建root系统分区
e2label /dev/sda1 boot # 为boot分区设置卷标
e2label /dev/sda2 root # 为root分区设置卷标