Transfer Raspbian from NOOBS partition to regular SD Card

Der nachfolgende Blogbeitrag ist rein englischsprachig … und sehr nerdig. — The following blog post describes how to transfer a living Raspbian (a/k/a Debian on a Raspberry Pi) that was installed via NOOBS, freeing it from the abstruse NOOBS partition scheme and then store it on a regular SD card with just a boot and a root partition.

The proposed method is extremely useful if you want to grow or shrink your Raspbian OS to a bigger or smaller SD card, or if you just want to backup your Raspi and not end up with a disk image that is sized like the entire SD card, even it was only half full. All three of these scenarios can usually be tackled e.g. with ApplePi-Baker v2, but it fails if your starting point was NOOBS. … As I googled for a HowTo like this and couldn’t find anything, I figured that other people might find this worth reading as well.

So let the nerd talk begin. I require that you to meet the following …

Prerequisites:

  • Your Raspi in question has booted into the Raspbian OS that you would like to transfer.
  • You are sitting in front of it, with a keyboard and a monitor connected to it. (An ssh remote access won’t suffice.)
  • A root password has been set and you know it. (A password-less sudo won’t suffice.)
  • You are logged into the text console as root. (If you’re still at the desktop, you should be able to switch to text console 2 with Ctrl-Alt-F2.)
  • The target SD card is attached to the Raspi via a USB card reader, but preferably not yet mounted.

First of all, make sure that the target SD card is big enough to hold the living system, duh. So please check with “df -h /”, just to be sure. Remember, a little bit of breathing space won’t harm. So if your Raspbian takes up 3.5 GB, it’s probably a good idea to use an 8 GB card. — Just saying …

Checking the existing partitions

Now check which partitions are actually mounted. Try “mount” and you should see which partition is mounted to “/” (your root partition) and which one is mounted to /boot (your boot partition). … Sometimes (e.g. with Debian 7 “Wheezy”) you might see that your root partition is mounted via /dev/root – in that case you might want to check with “ls -la /dev/root” where that symlink actually points to.

All that should also reflect if you check “cat /etc/fstab”: Depending on your prior NOOBS installation, your actual partition IDs might vary, but typically you’ll have /dev/mmcblk0p6 to be your boot partition, and /dev/mmcblk0p7 to be your root partition. … Take a note of this – if nothing else, take a mental note.

Partitioning the target SD card

Yes, we’re gonna do that manually – here be dragons. But fear not, it’s not that difficult.

Your target SD card should be attached to your Raspi via an SD card reader, and should thus be available as /dev/sda. Make sure with “mount” that none of the sda1/sda2/sda3 etc. partitions are mounted – and if some should indeed be mounted, unmount them prior to continuing with the help of “umount”.

Now please fire up the fdisk partition manager with “fdisk /dev/sda” and enter “p” to see what kinds of partitions are present. Those need to be deleted with the “d” command. … It will then ask you which partition to delete – or, if there’s only one left, delete that automatically. – You may at any point check where you stand with “p” and make sure you’ve deleted each and every partition that was present before. Don’t worry, nothing is permanent until writing the modified partition table back to the SD card. If anything goes wrong, simply hit Ctrl-C and start over.

After deleting the former partitions, we’ll now create the boot partition – which is supposed to be partition #1 at the beginning of the SD card, and typically it’s 60M big. The sequence of text commands to be entered (which you certainly shouldn’t follow blindly, but consciously – so nothing strange will happen along the way on your particular machine) should be like:

  • “n” – new partition
  • “p” – primary
  • “1” – partition #1
  • Enter – default starting position at the beginning of the SD card
  • “+60M” – we want to have that partition to be 60M big
  • “t” – change the partition type
  • (“1”) – select partition #1, probably selected automatically, as it’s the only one right now
  • “c” – “W95 FAT32 (LBA)”

When you check with “p”, you should see something like this:

/dev/sda1 2048 124928 61440 c W95 FAT32 (LBA)

Now for the root partition – this goes down a bit quicker:

  • “n” – new partition
  • “p” – primary
  • “2” – partition #2
  • Enter – default starting position right behind the boot partition
  • Enter – use the rest of the SD card

When you now check with “p”, you should see something like this (in my case on an 8 GB SD card):

/dev/sda1 2048 124928 61440+ c W95 FAT32 (LBA)
/dev/sda2 124929 15523839 7699455+ 83 Linux

Now the moment has come to write the new partition table. This will erase any previously existing partition(s) that were present before you deleted them. … This is the point of no return: Press “w” and hit the Enter key.

Formatting the freshly created partitions

Now we’ve got a DOS compatible boot partition and a Linux compatible root partition. All we have to do now for them to be usable is to format them, i.e. “make file systems”, or “mkfs” like this:

  • mkdosfs /dev/sda1
  • mkfs.ext4 /dev/sda2

mkdosfs will be done in a split second, while mkfs.ext4 will take a little longer while delivering a couple of status messages. Nothing unusual here.

Copying the boot partition

The DOS compatible boot partition contains a couple of firmware files and configuration scripts that the Raspi needs to boot up. It should be mounted at /boot – now it’s time to mount the target boot partition to be able to copy its contents.

  • mount -t vfat /dev/sda1 /mnt

You might omit the „-t vfat“, as mount usually assumes „-t auto“ nowadays. After that, please type “mount” to check that /dev/sda1 was indeed mounted at /mnt; then type “df -h /mnt” to check that you’re really looking at the 60M partition that we just created and afterwards formatted.

As for the actual copying, type the following:

cd /boot ; tar cvf - . | (cd /mnt && tar xf -)

In plain English: First change into the /boot directory where the source files reside. Our nice tar tool is going to “create a tape archive”, but will then pipe its output straight to stdout. This will be taken up via stdin by the second tar process at the end of that pipe, which will first change into the /mnt directory, and then “unpack” what it receives. … Don’t worry, no actual .tar archive is being written during the process, it’s all happening on the fly in memory.

After the copying has finished, “ls -la /boot” and “ls -la /mnt” should display pretty much the exact same files. … If something went wrong, like if perhaps your original /boot partition is bigger than 60M, start over with deleting and creating the partition – but now create a bigger boot partition.

Modifying the command line

With /dev/sda1 still mounted as /mnt, this is the right time to edit the Raspi’s future boot-time command line.

So please enter “vi /mnt/cmdline.txt” (or use your preferred light-weight text editor instead). In there, you should see (among other things) something like “root=/dev/mmcblk0p7” (i.e. the root partition that you took a mental note about): Change that to “root=/dev/mmcblk0p2”, as this is going to be our new root partition; currently, it’s sda2, which will become mmcblk0p2 later. (No, we haven’t copied that one just yet, hold on.)

Save the cmdline.txt file, leave the /mnt directory (e.g. with “cd /”), and then unmount both /boot and /mnt with “umount /boot” and “umount /mnt“.

Entering single user mode and freezing the root filesystem

Now for the big guns: We’re about to duplicate the content of the existing, living and breathing root partition. This takes a few preparations. First of all, let’s head into single user mode. — Note: Everything up to this point could have been done remotely via ssh, but once we’re kicking down networking and other essential system daemons in a second, all you’re going to have is the text console, i.e. your real monitor and your physical keyboard.

So enter “init 1” to switch to single user mode. Raspbian will now ask you for your root password to do so. … If root doesn’t have a password set, you won’t be able to switch into single user mode.

Once you’ve reached single user mode, please check whether your root filesystem is still mounted read/write or if it has been remounted read-only. Simply enter “mount” and see for yourself: If you should see something like

/dev/mmcblk0p7 on / type ext4 (ro,noatime)

then your root partitions has been re-mounted “ro” = read-only. (In Raspbian 10 / “Buster”, this should be the case.) But if you should  see something like

/dev/root on / type ext4 (rw,noatime)

your root partition is still “rw” = “read/write”. (I’ve seen this in Raspbian 7 / Wheezy.) In this case, I recommend to freeze any write access to the root file system by entering “fsfreeze -f /” right now.

Copying the root partition

Now for the actual copying. Did you unmount all unnecessary partitions yet? If not, just to be sure, enter “umount -a”. Then it’s time to mount the target root partition on the target SD card. So enter the following:

  • mount -t ext4 /dev/sda2 /mnt

Again, you could probably omit the “-t ext4” and it should still mount perfectly fine. However, better check with “mount” that you’ve actually mounted the e4fs partition /dev/sda2 at /mnt.

As we are about to copy the content of the root partition, you should know that we need to leave out a couple of directories:

  • /mnt – well, duh, we’re going to drop our files there, so trying to copy them would lead to a loop
  • /proc
  • /sys
  • /run

The latter three directories do not contain real files, but virtual ones that represent the currently running Linux system one way or another. They can’t be copied, but it isn’t necessary, as their contents are being created dynamically anyway.

Brace yourself for a lengthy command, again consisting of two tar processes, one gathering the files, one writing them. Here goes:

cd / ; tar --exclude=./mnt --exclude=./proc--exclude=./sys --exclude=./run -cvf - . | (cd /mnt && tar xf -)

This is supposed to be one long line, like shown on this screenshot:

Please note that the dash in front of the “-cvf” is crucial in this case (as opposed to when we were copying the boot partition earlier).

Hit enter – and have a little patience … actually a lot of patience, this might take a bit of time, copying a couple of GBs over USB2 to the target SD card (unless you are using a Raspi 4 and a USB3 SD card reader).

As a matter of fact, the long list of filenames scrolling over the screen slows things down. You might switch over to another text console with Alt-F2 (or Alt–F3, in case you’re already on console 2). The other text console won’t be functional, but you will notice that the copying is faster, as you can see from the SD activity LED flashing becoming much more rapid once the text screen doesn’t have to update for each and every file. … You may want to switch back and forth to watch what’s going on.

When something goes wrong: Interrupt the copying

If something looks odd – like perhaps when tar behaves bitchy and won’t honor the excludes: A simple Ctrl-C won’t be able to stop the copying.

I suggest the following method: Hit Ctrl-Z. This will suspend the copying and push it into the background. You can check with “jobs” that it’s still there. If you really want to interrupt the copy process, enter “killall tar” – the two tar processes should be the only ones running (which you could check with some variation of “ps” if you want to be sure). After killing the two tar processes, push the suspended copying back into the foreground with “fg” – and I promise it will terminate immediately.

After such an emergency stop, I’d probably go for “umount /mnt” to unmount the half-copied root filesystem – this might take a little while, as Raspbian is probably still busy syncing the disk write cache. However, after that, I’d start over with formatting the root partition with mkfs.ext4 and start over with a modified command line that works better for you. … No, you won’t have to re-format and re-copy the boot partition if that went well before.

If everything went well: Creating empty folders and modifying the fstab

Let’s assume the copy process took its time, but went through just fine. — If you froze the read/write root filesystem, this is the time to unfreeze it with “fsfreeze -u /”.

We excluded /mnt, /proc, /sys, and /run from the copying. Still, those four folders should exist as empty folders in the new root partition. So type the following:

cd /mnt ; mkdir mnt proc sys run

The most essential thing to do now, however, is to make sure that the copied Raspbian will mount the correct partitions as its boot and root partitions. So enter “vi /mnt/etc/fstab” (or use your preferred light-weight text editor instead again). In there, you should see something like

/dev/mmcblk0p6 /boot vfat defaults 0 2
/dev/mmcblk0p7 / ext4 defaults,noatime 0 1

Change that to

/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1

and save the file.

One last thing: In case you have a /dev/root device that is a symlink to the actual root device, you should update that as well (although I think that Raspbian does that automatically, but better safe than sorry).

If “ls -la /mnt/dev/root” displays something like “/mnt/dev/root -> mmcblk0p7”, please enter the following:

cd /mnt/dev ; ln -sf mmcblk0p2 root

Now the root device symlink should be in place and correctly point to mmcblk0p2.

Shutting down, swapping cards, rebooting

Everything is prepared: Shut down your Raspi with “shutdown -h now” and wait until the SD activity LED flashes 10 times in a row before you can safely cut the power supply.

Now pull out the USB SD card reader, remove the card, and replace the Raspi’s original SD card with the one we just partitioned, formatted, and copied. Fingers crossed – once you power up the Raspi, it should boot up the cloned system as if it was nothing. With one major difference: You won’t see the “For recovery, hold Shift” message anymore, as we got rid of NOOBS.

The reward of everything we just did is: You can now power down your Raspi, take out the SD, pop it into your Mac’s SD card reader, and create a beautifully shrunken backup copy of it with ApplePi-Baker v2.

Additional notes about PARTUUIDs vs. /dev/mmcblk0p* device names

I recently noticed that in some Raspbian installations, both /etc/fstab and as well /boot/cmdline.txt do not in fact contain /dev/mmcblk0p* device names for the root and boot partitions, but actually PARTUUIDs or UUIDs. You can easily retrieve those UUIDs via “sudo blkid”  for every block device that is connected to the system, even for non-mounted ones.

As a matter of fact, when copying partitions with ApplePi-Baker v2, it will leave these UUIDs unchanged – not even when shrinking or growing partitions during the imaging process. At least that’s my experience, and that’s probably a good thing, otherwise the cloned systems wouldn’t boot anymore

Anyway: If it should become necessary at some point to use these UUIDs instead of device names to address partitions, you’ll have to edit those in /etc/fstab and /boot/cmdline.txt before booting the copied Raspbian.

However: While I’ve seen those PARTUUIDs on a fresh regular installation of Raspbian 10 “Buster”, I never came across them when looking at NOOBS installations. If this should change somewhere along the line, I’ll look into it and update this blog post.

Keine Kommentare möglich.