Answers:
如果btrfs被编译为内核模块,则需要创建一个initramfs来在引导时加载该模块。在Raspian(和其他debian衍生产品)上,update-initramfs
是执行此操作的最简单方法。
如果initramfs-tools
已安装,则任何时候apt-get
安装新内核,它都会update-initramfs
自动触发。
sudo apt-get update
sudo apt-get install initramfs-tools
但是,如果您用于rpi-update
安装新内核,则需要update-initramfs
在重新引导到新内核之前手动运行:
sudo update-initramfs -u -k <kernel-version>
这将在中创建或更新initramfs /boot/initrd.img-<kernel-version>
。
最后一步是将其添加到您的启动配置中:将以下行添加到/boot/config.txt
:
initramfs initrd.img-<kernel-version> followkernel
initrd-<kernel-version>
必须与中的文件名完全匹配/boot
。
每次运行时,您都需要重复这些步骤rpi-update
。
我的快速测试表明,对btrfs的支持是作为raspbian中的外部模块构建的,而不是直接链接到内核中。
这意味着内核必须能够加载该模块(存储在根文件系统中),然后才能知道如何挂载根文件系统。显然,这是行不通的。
方法1:
构建自己的内核,并调整其构建配置以预链接btrfs。如果您已经了解了如何构建和加载自己的内核,则对配置进行调整很容易。
方法二:
重新调整内容,使内核和模块位于ext4文件系统上,而您最想压缩的数据位于btrfs分区上。
方法2A:
将根分区保留为ext4并创建一个基于btrfs的新分区,但这无助于减少OS的安装(如果这是您的目标)。
方法2B:
创建一个很小的引导分区,其中包含内核和模块,而其他所有内容都保留在btrfs上。我不知道如何为Pi的引导加载程序执行此操作,或者对此有什么限制。
btrfs
默认情况下,Raspbian内核不支持该功能。最初的引导阶段正常运行,但是当内核加载时,它将看不到任何可以挂载的文件系统和混乱情况。存在解决方案:在initramfs中将btrfs添加为内核模块。在很大程度上要感谢三篇 不同的 文章,因此我将其设置为:
sudo apt install btrfs-tools initramfs-tools
echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
sudo mkdir -p /etc/initramfs-tools/hooks ; sudo mkdir -p /etc/initramfs-tools/scripts/local-premount ; sudo cp /usr/share/initramfs-tools/hooks/btrfs /etc/initramfs-tools/hooks ; sudo cp /usr/share/initramfs-tools/scripts/local-premount/btrfs /etc/initramfs-tools/scripts/local-premount; sudo chmod +x /etc/initramfs-tools/hooks/btrfs /etc/initramfs-tools/scripts/local-premount/btrfs
-c
为当前内核版本(uname -r)创建()新的initramfs-如果要更新现有的initramfs,则需要使用update(-u
)。这将创建一个名为/boot/initrd.img-*的文件,其中*是当前内核版本。注意生成的名称(脚本将输出它),我们将在下一步中使用它。update-initramfs -c -k $(uname -r)
/boot/config.txt
以使用此initramfs,并添加initramfs initrd.img-3.11.0+ followkernel
文件名没有路径,它是上一步中生成的文件名;“ followkernel”控制内存中的位置(config.txt文档)。这就解决了当前的内核,但是正如@Ingo指出的那样,升级内核会破坏系统。为了解决这个问题,我使用了他的内核安装挂钩脚本:
INITRD=Yes
/etc/kernel/postinst.d/initramfs-tools
chmod +x
然后至此,我们有了一个可以使用btrfs作为根设备的系统。通过重新引导进行测试:系统仍将从ext4分区(或/boot/cmdline.txt中的任何内容)引导,但dmesg | grep -i btrfs
现在应显示包含“ Btrfs loading ”的行。现在,我们需要实际制作和使用btrfs分区。
备份/
(ext4)分区-假设它是/ dev / mmcblk0p2-通常:关闭RPi,取出SD卡,将其安装在其他位置(在此示例sudo mount /dev/mmcblk0p2 /mnt
中为Linux计算机),然后将内容归档;请注意,您需要使用保留所有权和权限的工具,例如tar :(cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *
然后再次卸载SD卡)
mkfs.btrfs /dev/mmcblk0p2
sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
sudo nano /mnt/etc/fstab
应该有类似这样的行:
/dev/mmcblk0p2 / ext4 foo,bar,baz 0 1
将其更改为此(新的FS类型为btrfs,并使用默认选项):
/dev/mmcblk0p2 / btrfs defaults 0 1
sudo umount /mnt
找到新btrfs分区的UUID-用/ dev / mmcblk0p2查找行,然后复制UUID =部分,并使用(不是UUID_SUB,不是PARTUUID!这会在引导加载程序中触发错误,并且内核也不会引导):sudo blkid
/ dev / mmcblk0p2:UUID =“ cafebeef-0000-1234-aaaa-12346589” UUID_SUB =“ ababccdd-2345-cafe-beee-587989991110” TYPE =“ btrfs” PARTUUID =“ beef0bee-02”
挂载启动(FAT32)分区: sudo mount /dev/mmcblk0p1 /mnt
sudo nano /mnt/cmdline.txt
找到这两个参数
root=PARTUUID=1234-5678 rootfstype=ext4
并替换为
root=UUID=cafebeef-0000-1234-aaaa-12346589 rootfstype=btrfs
请注意,UUID是我们之前复制的UUID,只是没有引号。
sudo umount /mnt
在RPi上,请查看您确实是从btrfs根挂载运行: mount
/ dev / mmcblk0p2 on /输入btrfs(rw,space_cache,subvol = /)
等等!不完全是点击,而是通过站在巨人的肩膀上,我可以使它起作用。(也将其放入回购中。)
sudo apt upgrade
如果它也可以升级)内核,此设置将在引导时严重失败,因为新内核尝试加载将失败的旧initramfs,并且内核无法加载btrfs驱动程序。而且,至少chroot
在armhf系统上,这不是固定的简便方法。
apt upgrade
在引导新内核之前,您始终必须用眼睛监视正在执行的操作,并在需要时手动生成initramfs。对于初学者而言,这不是一项可行的任务,因为失败会导致戏剧性的变化。您可以看看如何在启动Raspberry Pi时使用初始化ramdisk(initramfs)?
4.14.98+
和4.14.98-v7+
。如果update-initramfs由内核更新触发,它将生成两个initrd.img *,每个模型一个。这不适用于/boot
分区(错误-空间不足),并且生成无法完成。
MODULES=list
。