Booting with a USB Root Filesystem

From wiki.emacinc.com
Revision as of 17:51, 5 March 2019 by Mgloff (talk | contribs)
Jump to: navigation, search

It is possible to boot most EMAC OE systems using a USB thumb drive as the root filesystem and to optionally load a kernel from. This method can be especially useful for updating or recovering the root filesystem when a network connection or a network file server is not available. This page describes the steps required to boot into a root filesystem residing on a USB thumb drive.

Prerequisites

Some prerequisites must be met prior to being able to boot a root filesystem from a USB drive.

USB Thumb Drive

Any blank USB drive. If it is not blank, this process will completely wipe the data that exists on the USB drive.

Root Filesystem

A complete root filesystem for the EMAC OE system to boot from must be stored on the USB drive.

Linux Host Computer

Either a native Linux host or Windows host running a Linux virtual machine.

Configuring the USB Thumb Drive

In a terminal window, start the dmesg log with the follow option to watch for new devices.

developer@ldc:~# dmesg -w

Insert the USB drive and watch for the device to be announced.

[ 2796.940110] scsi host6: usb-storage 1-1.2:1.0
[ 2797.963442] scsi 6:0:0:0: Direct-Access Generic STORAGE DEVICE 0272 PQ: 0 ANSI: 0
[ 2797.963905] sd 6:0:0:0: Attached scsi generic sg4 type 0
[ 2798.269544] sd 6:0:0:0: [sdd] 7774208 512-byte logical blocks: (3.98 GB/3.71 GiB)
[ 2798.271027] sd 6:0:0:0: [sdd] Write Protect is off
[ 2798.271030] sd 6:0:0:0: [sdd] Mode Sense: 0b 00 00 08
[ 2798.272502] sd 6:0:0:0: [sdd] No Caching mode page found
[ 2798.272508] sd 6:0:0:0: [sdd] Assuming drive cache: write through
[ 2798.279486] sdd:
[ 2798.283834] sd 6:0:0:0: [sdd] Attached SCSI removable disk



The output of the dmesg command shows that the root device node for the USB drive in this case is sdd and no partitions. Partitions on the drive would be listed as sdd1, sdd2, etc. Inspect the output shown above to see the particular device node on the development PC where the USB drive is mounted. This will be different depending on the configuration of the development PC. The /dev/ prefix will go before the device name, but is not shown in the output of dmesg. The device node will start with sd. The third letter will specify which of these devices is assigned to the USB drive. The number will indicate the partitions, if any. Press Ctrl and 'c' to exit dmesg.

  • At this point, it is wise to double check that device node is actually the USB drive and not a hard drive in the system. Specifying the wrong device node could cause a complete loss of data on a hard drive.

    Continuing with /dev/sdd as the example device node, type the following command:
developer@ldc:~# mount | grep sdd

/dev/sdd on /media/developer/FBF6-1988 type vfat

This shows that the device node, /dev/sdd, is in fact the USB drive. This is because:

  • It is not mounted on one of the standard Linux filesystem mountpoints, such as /, /boot, /usr, or /home.
  • It is mounted in the /media directory, where it is expected. It may alternatively get mounted in /mnt, depending upon the configuration of the Linux distribution in use.

If nothing is returned, then the USB drive did not get automatically mounted. Proceed to the next step.

Use fdisk -l to inspect the device node. Use sudo with fdisk to gain the required root privileges to run fdisk

developer@ldc:~# sudo fdisk -l /dev/sdd
Disk /dev/sdd: 3.7 GiB, 3980394496 bytes, 7774208 sectors Disk model: STORAGE DEVICE Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x4fcf5773

The output of fdisk will also show information about any partitions that may exist on the USB drive. For example, another drive with a single FAT32 formatted partition will look like:

developer@ldc:~# sudo fdisk -l /dev/sdd
Disk /dev/sdd: 3.7 GiB, 3980394496 bytes, 7774208 sectors Disk model: STORAGE DEVICE Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xe6077d37 Device Boot Start End Sectors Size Id Type /dev/sdh1 2048 7774207 7772160 3.7G c W95 FAT32 (LBA)
  • As can be seen from the output of the fdisk -l command above, the disk is 3.7 GB in size, which corresponds with the size of the 4 GB USB drive being used in this example.

Unmount all of the USB drives partitions that were listed from the mount command above.

developer@ldc:~# sudo umount /dev/sdd

If there is a partition listed:

developer@ldc:~# sudo umount /dev/sdd1

Repartition the USB Drive

Once the correct drive letter is determined, we will create a new Linux partition.

developer@ldc:~# sudo fdisk /dev/sdd
Welcome to fdisk (util-linux 2.33.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): o Created a new DOS disklabel with disk identifier 0x05d5e983. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-7774207, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-7774207, default 7774207): Created a new partition 1 of type 'Linux' and of size 3.7 GiB. Command (m for help): p Disk /dev/sdd: 3.7 GiB, 3980394496 bytes, 7774208 sectors Disk model: STORAGE DEVICE Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x05d5e983 Device Boot Start End Sectors Size Id Type /dev/sdd1 2048 7774207 7772160 3.7G 83 Linux Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.

The fdisk commands are:

o - Create a new empty partition table

n - Create a new partition

p - The type of partition is a primary partition

1 - Create the first partition

<ENTER> - Accept default start

<ENTER> - Accept default end

p - Print the new partition layout

w - Write the new partition layout and exit

Format the Partition

The first partition will be formatted with the ext4 filesystem.

developer@ldc:~# yes | sudo mkfs.ext4 /dev/sdd1

Mount the Partition

The first partition of the USB drive will be mounted so that it is accessible to write to.

developer@ldc:~# sudo mkdir -p /media/card
developer@ldc:~# sudo mount /dev/sdd1 /media/card

The USB drive is now accessible through the /media/card directory.

Extract Filesystem Archive

Locate where the filesystem archive has been downloaded. If the archive is called rootfs.tar.gz and is in the users Downloads directory:

developer@ldc:~# cd /media/card
developer@ldc:/media/card# sudo tar zxf ~/Downloads/rootfs.tar.gz


Configuring the Client to Boot from USB

Configuring U-Boot

Insert the USB drive into an available port on the target board. Set the bootargs variable to tell the kernel to boot into the USB filesystem:

U-Boot> setenv bootargs console=${console} root=/dev/sda1 rootfstype=ext4
U-Boot> run bootargs

This line sets up the environment needed to boot from the USB drive. These options will be passed to the Linux kernel when booting it. The console=${console} part tells Linux to use the console setting from the U-Boot environment variable; this will usually be something along the lines of console=ttyS0,115200n8. The root=/dev/sda1 directive tells Linux to instantiate with the USB block device, /dev/sda1, as the root filesystem. The rootfstype=ext4 directive tells Linux that the root filesystem is of the EXT4 variety.

If the kernel is already programmed into the flash, it can be used in most cases to boot into the USB root filesystem. Execute the next line to load and run the default kernel.

U-Boot> boot

The machine should now boot, and show output on its console as it does so.

Alternate Kernel Load

An alternate kernel can be loaded into memory temporarily and booted if the kernel is not already programmed in the flash or a development kernel is to be tested. The below example assumes a kernel named zImage-test was placed in the /boot directory of the USB drive. Also see Executing kernel from RAM

U-Boot> usb start
U-Boot> usb storage
U-Boot> ext2load usb 0:1 ${loadaddr} /boot/zImage-test
U-Boot> bootz ${loadaddr}

The first two commands initialize the USB storage system in U-Boot. The ext2load line says to use the USB device 0 partition 1 and load into RAM at ${loadaddr} the file /boot/zImage-test from the USB drive. The last line boots the kernel that has been loaded into memory.

Conclusion

Using a USB thumb drive for the root filesystem allows boards to boot quickly into a rescue or known good version of a filesystem and provides a method for remotely backing up the filesystem installed on an embedded machine. Setting up a machine to boot to a root filesystem via USB requires little work; most of the work is in setting up the USB thumb drive.

Further Information

Where to Go Next