Booting from a Hard Disk - sakaki-/gentoo-on-rpi-64bit GitHub Wiki
This is a list of instructions on how to install gentoo onto a hard disk for the Rpi4 using genpi64 as a basis. This guide assumes you've already setup genpi64 on a SD card and are able to ssh or access the console over the network.
Hardware
For the enclosure / Sata interface for this example I'm using parts from GeekWorm
- Rpi 4 8Gb
- 16Gb Micro SD Card
- Geekworm Raspberry Pi X735 (allows control over the power like ATX / acts as a fan for the Pi Board)
- Geekworm Raspberry Pi 4 NAS Dual SATA, X829 - allows the attachment of 2 x Sata disks to an Rpi4 via USB3 and provides a couple of USB3 ports as a hub
- Geekworm X829-C1 Matching Metal Case (include power switch / case fan)
- Geekworm DC 5V 4A Power Adapter
- 2 x BarraCuda 2 TB Internal Hard Drive 2.5 inch
Both disks show up fine with this setup as /dev/sda /dev/sdb Note a metal case will impact the wifi range though
UAS issues
With the Rpi3 and older there was no support for UAS when connecting to a Sata hard disk over USB. With the Rpi4 UAS is supported which is good since it offers better performance but it can cause issues with some sata USB controllers that don't support UAS fully and have not yet been properly blacklisted within the kernel
- https://www.raspberrypi.org/forums/viewtopic.php?t=245931
- https://github.com/raspberrypi/linux/issues/3070
This was an issue I ran into, but it took a while to show up under dmesg
- As a fix the first step is to get the vendor / product id of the usb device that handles the drive (in my case 174c:0829)
- Add this to the /boot/cmdline.txt (Substituting your own vendor / product id's)
- usb-storage.quirks=174c:0829:u
- Then do a reboot
This will largely depend on the type of USB3 to Sata bridge you are using. The speed difference isn't that much for a regular disk, but may affect an SSD more (see below)
Determining sata speed
- https://www.cyberciti.biz/faq/linux-command-to-find-sata-harddisk-link-speed/
- https://www.cyberciti.biz/tips/how-fast-is-linux-sata-hard-disk.html
From the looks of things smartctl doesn't have support for this usb bridge yet
smartctl -i /dev/sda
#/dev/sda: Unknown USB bridge [0x174c:0x0829 (0x100)]
#Please specify device type with the -d option.
Another approach is hdparm
hdparm -I /dev/sda | egrep "Model|speed|Transport"
# For the X829 this shows
#* Gen1 signaling speed (1.5Gb/s)
#* Gen2 signaling speed (3.0Gb/s)
#* Gen3 signaling speed (6.0Gb/s)
#* SMART Command Transport (SCT) feature set
To run some timing tests
hdparm -tT /dev/sda
# For the X829 / BarraCuda drives
# UAS enabled
#/dev/sda:
# Timing cached reads: 2132 MB in 2.00 seconds = 1067.16 MB/sec
# Timing buffered disk reads: 386 MB in 3.01 seconds = 128.33 MB/sec
# UAS disabled (to prevent issues)
#/dev/sda:
# Timing cached reads: 2112 MB in 2.00 seconds = 1056.71 MB/sec
# Timing buffered disk reads: 350 MB in 3.01 seconds = 116.16 MB/sec
Setting up Partitions
First we're going to create three new partitions on the disk.
- Boot partition - copy of /boot/ from the sd card
- Swap partition
- Root partition - copy of / from the sd card
The boot partition isn't really needed at this point but it may be useful later on once USB booting via the EEPROM is supported for the Rpi4
Setup the partition table
# To reset the partition table
parted /dev/sda mklabel msdos
# Create some new partitions
parted -a optimal /dev/sda mkpart primary fat32 0% 2048MB
parted -a optimal /dev/sda mkpart primary linux-swap 2048MB 18GB
parted -a optimal /dev/sda mkpart primary ext4 18.0GB 100%
Next lets format some partitions
mkfs.vfat -F 32 -n DISKBOOT /dev/sda1
mkswap /dev/sda2
mkfs.ext4 /dev/sda3
Copying over data
Copy Boot partition
Copy over the boot partition, just in case USB booting becomes a thing
mkdir /mnt/boot
mount -t auto /dev/sda1 /mnt/boot
cp -a /boot/* /mnt/boot/
umount /mnt/boot
Copy root partition
Mount the disk ext4 root where we will be copying the root files to
mkdir /mnt/diskroot
mount -t auto /dev/sda3 /mnt/diskroot
Mount the current root to a different directory, this avoid things like /sys/ files being picked up
mkdir /mnt/oldroot
mount -t auto /dev/mmcblk0p2 /mnt/oldroot
Copy over the data
rsync -aHS --progress /mnt/oldroot/. /mnt/diskroot/.
unmount the old root
umount /mnt/oldroot
Update fstab
Next we're going to update the fstab on the disk root. Run the following to get the UUID values
blkid -p /dev/sda1
blkid -p /dev/sda2
blkid -p /dev/sda3
The output will look something like this. The part we're interested in is the PART_ENTRY_UUID value for each partition We use PART_ENTRY_UUID instead of UUID as UUID is within the filesystem so may need a initramfs to read initially such as within cmdline.txt
/dev/sda3: UUID="247e836f-7929-4702-aadd-955dfc947d8c" VERSION="1.0" BLOCK_SIZE="4096" TYPE="ext4" USAGE="filesystem" PART_ENTRY_SCHEME="dos" PART_ENTRY_UUID="ea23b7f3-03" PART_ENTRY_TYPE="0x83" PART_ENTRY_NUMBER="3" PART_ENTRY_OFFSET="35155968" PART_ENTRY_SIZE="3871873024" PART_ENTRY_DISK="8:0"
Create a directory for the boot partition on the disk
mkdir /mnt/diskroot/boot-hd
Edit the fstab file
vi /mnt/diskroot/etc/fstab
Replace the lines
PARTUUID=7a0c8bb0-01 /boot vfat defaults 0 2
PARTUUID=7a0c8bb0-02 / ext4 defaults,noatime 0 1
/var/cache/swap/swap1 none swap sw 0 0
With the PARTUUID values taken from blkid above, as an example (note the uuid valus will be different for your setup)
PARTUUID=ea23b7f3-01 /boot-hd vfat defaults 0 3
PARTUUID=7a0c8bb0-01 /boot vfat defaults 0 2
PARTUUID=ea23b7f3-03 / ext4 defaults,noatime 0 1
PARTUUID=ea23b7f3-02 none swap sw 0 0
Finally unmount the disk root
umount /mnt/diskroot
Switch boot to hard disk
Now we're going to switch the boot process across to use the root partition on the disk instead of the sd card
First lets make a backup of the cmdline.txt just in case we need to boot from the sdcard at some point in the future in an emergency. (this file can be easily edited under linux or windows via a sd card reader)
cp cmdline.txt cmdline.txt.sdcard
Next edit the cmdline.txt file and replace
root=PARTUUID=7A0C8BB0-02
With the PARTUUID of the disk above
root=PARTUUID=ea23b7f3-03
Finally make a copy of cmdline.txt so that we can swap back and forth between the hard disk and the sd card just by copying a file
cp cmdline.txt cmdline.txt.hddisk
Reboot time
If all goes to plan then on the next reboot the OS should boot from the hard disk instead of the SD Card. the boot partition on the SD card will still be needed to startup the root on the hard disk. But hopefully in the future that can be switched across to the hard disk as well once the EEPROM features move out of beta
The way the mounts are setup above /boot will point to the SD card's boot /boot-hd will point to the boot partition on the hard disk (not yet used)
so any changes should be made to /boot for the boot process