Move bookworm system from SSD to NVME

Jul 31, 2024 Last reply: 1 year ago 55 Replies

My "PC" for most daily use, is a raspi 5 with updated Bookworm, running on a SSD connected to USB via a SATA-adapter. I am tempted to change to NVME to get the last bit of latency away. But what is the easiest way to copy the system to NVME? I see 3 possibilities:



1: Connect SSD and NVME to a Windows PC and use Macrium Reflect to move the system. 2: Connect NVME to raspi, boot the system from SSD, and somehow copy the running system to NVME. 3: Connect NVME to raspi, boot from SD-card and copy the system from SSD to NVME. But how?

By now option 1, is the only one I can manage and the one used to move the system from SD-card to SSD. Searching for help relating to options 2 and 3 on the net ends in quite complicated solutions that maybe will not work in bookworm. So if you see an easy solution that a Windows idiot can manage, please come forward :-)



Below is information showing what the system on the SSD looks like. The listing is taken when booted to a SD-card with a fresh Bookworm install:



raspberrypi@raspberrypi:~ $ df -h Filesystem Size Used Avail Use% Mounted on udev 3.8G 0 3.8G 0% /dev tmpfs 805M 6.2M 799M 1% /run /dev/mmcblk0p2 57G 5.0G 49G 10% / tmpfs 4.0G 368K 4.0G 1% /dev/shm tmpfs 5.0M 48K 5.0M 1% /run/lock /dev/mmcblk0p1 510M 75M 436M 15% /boot/firmware tmpfs 805M 160K 805M 1% /run/user/1000 /dev/sda2 234G 19G 203G 9% /media/raspberrypi/rootfs /dev/sda1 511M 76M 436M 15% /media/raspberrypi/bootfs


raspberrypi@raspberrypi:~ $ sudo cat /proc/mounts sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 proc /proc proc rw,relatime 0 0 udev /dev devtmpfs rw,nosuid,relatime,size=3945808k,nr_inodes=246613,mode=755 0 0 devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 tmpfs /run tmpfs rw,nosuid,nodev,noexec,relatime,size=824160k,mode=755 0 0 /dev/mmcblk0p2 / ext4 rw,noatime 0 0 securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot 0 0 pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0 bpf /sys/fs/bpf bpf rw,nosuid,nodev,noexec,relatime,mode=700 0 0 systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=29,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=4753



0 0 tracefs /sys/kernel/tracing tracefs rw,nosuid,nodev,noexec,relatime 0 0 debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0 mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0 configfs /sys/kernel/config configfs rw,nosuid,nodev,noexec,relatime 0 0 fusectl /sys/fs/fuse/connections fusectl rw,nosuid,nodev,noexec,relatime 0 0 ramfs /run/credentials/systemd-sysctl.service ramfs ro,nosuid,nodev,noexec,relatime,mode=700 0 0 ramfs /run/credentials/systemd-sysusers.service ramfs ro,nosuid,nodev,noexec,relatime,mode=700 0 0 ramfs /run/credentials/systemd-tmpfiles-setup-dev.service ramfs ro,nosuid,nodev,noexec,relatime,mode=700 0 0 /dev/mmcblk0p1 /boot/firmware vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro
0 0 ramfs /run/credentials/systemd-tmpfiles-setup.service ramfs ro,nosuid,nodev,noexec,relatime,mode=700 0 0 sunrpc /run/rpc_pipefs rpc_pipefs rw,relatime 0 0 binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0 tmpfs /run/user/1000 tmpfs rw,nosuid,nodev,relatime,size=824144k,nr_inodes=206036,mode=700,uid=1000,gid=1000
0 0 gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0 portal /run/user/1000/doc fuse.portal rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0 /dev/sda2 /media/raspberrypi/rootfs ext4 rw,nosuid,nodev,relatime,errors=remount-ro 0 0 /dev/sda1 /media/raspberrypi/bootfs vfat rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro
0 0 raspberrypi@raspberrypi:~ $

It's not Windows, you don't need 3rd party tools to do simple things such as copying files to new discs, everything you need is provided, although it may not be obvious what to do.

Option 3 is the best, as both the drives can be connected to the Pi, booting from an OS image the SD card allows you to perform the copy.

As long as your new NVME is larger than the SSD, you can just do low level copy with the dd command, then resize the rootfs partition on the new drive to use any extra space with the gparted program (if not installed use: apt install gparted).

e.g. dd if=/dev/sda of=/dev/nvme0n1 bs=1M status=progress

Use fdisk -l to find the nvme disk name as it may not be as above.

Alternatively use gparted to create a 512MB FAT boot partition, and the rest of the drive as a ext4 root partition, then mount them, and copy files from the boot and root partitions with rsync.

e.g.

mkdir -p /mnt/SSD/boot mount /dev/sda1 /mnt/SSD/boot mkdir -p /mnt/SSD/root mount /dev/sda2 /mnt/SSD/root

mkdir -p /mnt/NVME/boot mount /dev/nvme0n1p1 /mnt/NVME/boot mkdir -p /mnt/NVME/root mount /dev/nvme0n1p2 /mnt/NVME/root

rsync -vax /mnt/SSD/boot/ /mnt/NVME/boot rsync -vaxHAX /mnt/SSD/root/ /mnt/NVME/root

Make sure you look up what those commands do and have the correct parameters, rather than just cutting and pasting.

---druck

Use rsync to do a file-level copy. Then the difference in volume sizes won’t matter.

I haven’t done this on ARM, only on x86 machines (several times), but the procedure should be similar: after copying the installation across, you will need to fix up /etc/fstab for the changed filesystem IDs, and also reinstall the bootloader. Then you should be good to go.

If you can create an image - there are various tools to do that, then use the Raspberry Pi imager onto the NVME drive. That is what I did to move from a USB SSD to NVME, when I finally got an adapter

That will at least get over the problem of having a different partuuid etc

Is it possible to then create a DIFFERENT partition on the empty part of the new disk? And mount it as - say - /home?

I need to do this myself, although the urgency is very low

Thank you very much to all for taking your time to reply.

By now I think the first solution from druck will be my first try (when I get the NVME). I have before been looking at creating an image (as suggested by Chris Townley today) , but ran in to things I did not understand, or was ment for an earlier version of raspberry pi os. Then i posted the question here.

So if we look at the df -h listing from my first post: raspberrypi@raspberrypi:~ $ df -h Filesystem Size Used Avail Use% Mounted on udev 3.8G 0 3.8G 0% /dev tmpfs 805M 6.2M 799M 1% /run /dev/mmcblk0p2 57G 5.0G 49G 10% / tmpfs 4.0G 368K 4.0G 1% /dev/shm tmpfs 5.0M 48K 5.0M 1% /run/lock /dev/mmcblk0p1 510M 75M 436M 15% /boot/firmware tmpfs 805M 160K 805M 1% /run/user/1000 /dev/sda2 234G 19G 203G 9% /media/raspberrypi/rootfs /dev/sda1 511M 76M 436M 15% /media/raspberrypi/bootfs

Then the system to copy is on the 2 last lines. Correct?

And following drucks first suggestion I should run these 2 commands:

1: dd if=/dev/sda2 of=/dev/nvme0n1 bs=1M status=progress and 2: dd if=/dev/sda1 of=/dev/nvme0n1 bs=1M status=progress

replacing the name of the NVME to what I see when it is installed on the raspi.

Best regards, and thank you for the help.

No.

In order to preserve the partition information *you must dd the raw disk*

dd id=/dev/sda od = /dev/nvme0n1 (or whatever)

That will create a two partition disk with the UUIDS of the partitions the same as is mentioned in the boot data: If they don't match it wont boot.

Viz:

df -h | grep ^/dev/ /dev/root 15G 1.5G 13G 11% / /dev/mmcblk0p1 255M 51M 205M 20% /boot

These are the TWO partitions on a bootable PI device In /boot which is DOS style formatted will be instructions on how to boot the main system

In the main bootable system there will be the fstab file which needs to tally with the partition ids.

more /etc/fstab:

proc /proc proc defaults 0 0 PARTUUID=b8c9fbb7-01 /boot vfat defaults 0 2 PARTUUID=b8c9fbb7-02 / ext4 defaults,noatime 0 1

In the BOOT partition is this file more *.txt :::::::::::::: cmdline.txt :::::::::::::: console=serial0,115200 console=tty1 root=PARTUUID=b8c9fbb7-02 rootfstype=ext4 fs ck.repair=yes rootwait modules-load=dwc2,g_ether

Unless the bootloader finds that partition ID, it will *not load Linux*

AIUI the boot sequence is this:

Look for a DOS style VFAT partition on SD card, then USB, then NVME.

Look for a file named 'cmdline.txt' parse the root partition ID and attempt to load a linux image from the boot partition and have the kernel image mount the aforementioned PARTUUID as root partition.

If the PARTUUIDs don't match, the boot sequence hangs

So it is important to have the same PARTUUID in /boot/cmdline.txt, and in /etc/fstab, and in the partition label on the boot partition

The easy way to do this is not to clone the partitions, but the RAW DISK

That wont work, but you wont destroy anything by trying.

Are you saying that this command (the one right above) will clone the whole disc, and the job is done? Probably not. When I run "dd --help" on the system i want to clone, there is no information about the switch "id" you use in the command.

Running that command on my system gives: raspberrypi@raspberrypi:~ $ df -h | grep ^/dev/ /dev/sda2 234G 19G 203G 9% / /dev/sda1 511M 76M 436M 15% /boot/firmware For /dev/sda1 it says "firmware", so it probably should/can not be copied, and is permanent on the raspi5-system

So I will not try :-)

I think I should not take any more of your time for this project. Using a PC and a windows program (Macrium Reflect) to clone the disc will take maybe 30 minutes. Learning the ins and outs of how it should be done in raspi-os can take 14 days for a windows-addict:-)

Best regards, and thank you for the help so far.

That command is wrong (or for an odd version of dd - but I think it's a finger slip) make that:

dd if=/dev/sda of=/dev/nvme0n1 bs=1m

The add bs=1m will probably work wonders for performance.

Soory. old brain. dd if=/dev/sda of = /dev/nvme0n1 (or whatever)

It has to be copied because it contains the boot information

dd will clone it in a lot less time

And that is the point, You MUST clone the WHOLE DISK. Not the partitions inside it

+1

Not odd command, just brainfade. if=input file, I was thinking InputDevice...

On 01.08.2024 17:47, Jesper wrote: > raspberrypi@raspberrypi:~ $ df -h | grep ^/dev/ > /dev/sda2 234G 19G 203G 9% / > /dev/sda1 511M 76M 436M 15% /boot/firmware > For /dev/sda1 it says "firmware", so it probably should/can not be > copied, and is permanent on the raspi5-system

The Natural philosopher says to clone both sda1 and sda2. I still wonder if sda1 should be cloned. It is listed as "firmware". That sounds to me like it is on a flashmemory directly on the raspi5, and you modify it with raspi-config->Advanced options->Boot order.

But I can try running both commands: dd if=/dev/sda2 of=/dev/nvme0n1 bs=1m dd if=/dev/sda1 of=/dev/nvme0n1 bs=1m

Comments?

Best regards

Yes. not only must it be cloned, because it contains instructions as to what patition the linux systren is in, but the linux partiton id must be cloned as wqell and that does not exost ionside the partibin, but on the raw disk as well so that it has that partition number

That sounds to me

The second dd will wipe out the first. Dont waste my time, come back when you have demonstrated that it doesn't' work

I've been there and have the T-shirt

That's how I know what you have to do.

/boot in the older release is /boot/firmware in the new.

My Pi4Bookworn SSD that does boot has two partitionb on it

mounted on my desktop they show this

/dev/sdb1 510M 61M 450M

12% /media/leo/bootfs /dev/sdb2 110G 5.7G 99G 6% /media/leo/rootfs

Bootfs is what gets mounted on /boot/firmware rootfs is a traditional Linux filesystem

In bootfs the cmdline.txt specifies

/media/leo/bootfs$ more cmdline.txt console=serial0,115200 console=tty1 root=PARTUUID=778a9e44-02 rootfstype=ext4 fsck.repair=yes rootwait noswap=1

So that specifies the PARTUUID of the partition that *must* be mounted as root

That PARTUUIDs are shown a s follows

eo@Juliet:/media/leo/bootfs$ sudo blkid /dev/sdb /dev/sdb: PTUUID="778a9e44" PTTYPE="dos" leo@Juliet:/media/leo/bootfs$ sudo blkid /dev/sdb1 /dev/sdb1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="5DF9-E225" TYPE="vfat" PARTUUID="778a9e44-01" leo@Juliet:/media/leo/bootfs$ sudo blkid /dev/sdb2 /dev/sdb2: LABEL="rootfs" UUID="3b614a3f-4a65-4480-876a-8a998e01ac9b" TYPE="ext4" PARTUUID="778a9e44-02"

The partition IDs are not stored on the partitions, but in the partition table. This is why you have to clone the whole disk, to clone that partition table as well.

After booting linux will mount the original bootfs on /boot/firmware (it used to be /boot pirior to bookworm) and the partuuid specified in cmdline.txt as the root partition

The bootfs will be re-mounted according to what is in fstab

/etc$ more fstab proc /proc proc defaults 0 0 PARTUUID=778a9e44-01 /boot/firmware vfat defaults 0 2 PARTUUID=778a9e44-02 / ext4 defaults,noatime 0 1

All these ducks have to be lined up in a row or the bloody thing will not boot

>

This will copy sda2 to nvme0n1

This will overwrite that copy with sda1. You would probably be better off cloning sda as a whole - that will get all partitions, boot sectors etc.

+1.

That will boot, but have spare disk space. You can extend the root partition using the Pi toolset, or I hope (havent tried it yet) create another partition in the spare disk space....

Yes, that's also what The Natural Philosopher says in his reply. And I know that you both of course are right. But I still do not know what a command that clones both sda1 and sda2 to NVME should look like. Please?

When I run ls /media i get this: raspberrypi@raspberrypi:~ $ ls /media raspberrypi

Could this work to clone the whole disc: dd if=/dev/raspberrypi of=/dev/nvme0n1 bs=1m

Best regards

Really? It is given to you more than once

dd if=/dev/sda of=/dev/nvme0n1 bs=1m

/dev/sda is the WHOLE disk called /dev/sda /dev/sdaX where X is a number is that PARTITION on the disk /dev/sda

Yes the dd method will avoid any changes to partuuids, where as if you use the rsync method you will have to change the values in /etc/fstab and also potentially /boot/cmdline.txt (/boot/firmware/cmdline.txt on Bookworm).

Yes, you can do this with gparted, move the existing /home to the new partition and edit /etc/fstab to contain a line similar to:-

PARTUUID=abcd1234-03 /home ext4 nofail,noatime,errors=remount-ro 0 0

Then do a:-

mount -a

---druck

No that wont work, it will copy the contents of of the first partition over the start of the nvme drive and then copy the second partition over the top of that.

I think what you meant was to copy to /dev/nvme0n1p1 and /dev/nvme0n1p2, assuming you have already created two partitions of the correct size on the nvme disk. (I do it like this if creating additional partitions to enable running different OS versions, but its not needed for a straight copy).

The single dd command I gave in my last post copies the whole of the SSD to the nvme including the partition table and both parititions, giving an identical drive - as long as it is bigger. The only thing to do then is to use gparted to update the partition table and last partition to fill the rest of that new disk.

---druck

Bookworm now calls the first FAT partition on the disk which contains device file and the kernel 'firmware' and mounts it at /boot/firmware (previous versions just mounted at /boot). It is very much required for the Pi to start sucessfully.

Just the one:-

dd if=/dev/sda of=/dev/nvme0n1 bs=1m

---druck

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required