Loading...
 

Boot from removable storage - Buildroot

Below we will show how to copy kernel and Buildroot root file system binaries to a microSD card or USB device, as well as how to set up boot parameters in U-Boot to boot from them.

Buildroot filesystem and images can be either:

 

SD card


MicroSD card is ESPRESSObin's main storage and booting environment, so begin by inserting the microSD card in your local Linux machine. If your laptop does not have a microSD card slot, use a USB microSD card reader. Once we have plugged the microSD card in our laptop, we should see the SD card listed most probably as /dev/sd* device (or /dev/mmcblk0*) so make sure to check with lsblk:

user@laptop:/$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 238,5G  0 disk
├─sda1   8:1    0   487M  0 part /boot/efi
├─sda2   8:2    0 234,1G  0 part /
└─sda3   8:3    0   3,9G  0 part [SWAP]
sdb      8:16   1   478M  0 disk
├─sdb1   8:17   1   100M  0 part
└─sdb2   8:18   1   377M  0 part


We can see that our microSD card was recognized as /dev/sdb/. Since we will be formatting our SD card, we want to clear everything from it first (of course, backup content from your SD card before this). We clear it with:

user@laptop:/$ sudo dd if=/dev/zero of=/dev/sdb bs=1M count=100


and check again with lsblk that everything was cleared:

user@laptop:/$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 238,5G  0 disk
├─sda1   8:1    0   487M  0 part /boot/efi
├─sda2   8:2    0 234,1G  0 part /
└─sda3   8:3    0   3,9G  0 part [SWAP]
sdb      8:16   1   478M  0 disk


Now we will create a new partition (sdb1) on the empty SD card:

user@laptop:/$ (echo n; echo p; echo 1; echo ''; echo ''; echo w) | sudo fdisk /dev/sdb


and format it as EXT4 with:

  • For e2fsprogs < 1.43 use:
user@laptop:/$ sudo mkfs.ext4 /dev/sdb1
  • For e2fsprogs >=1.43 use:
user@laptop:/$ sudo mkfs.ext4 -O ^metadata_csum,^64bit /dev/sdb1


Next we mount this partition on our local Linux machine (e.g. we will mount it to /mnt/sdcard):

user@laptop:/$ sudo mkdir -p /mnt/sdcard
user@laptop:/$ sudo mount /dev/sdb1 /mnt/sdcard


Head into the mounted directory and there extract the root file system (rootfs.tar.gz) we have built above when compiling Buildroot:

user@laptop:/$ cd /mnt/sdcard
user@laptop:/mnt/sdcard$ sudo tar -xvf /home/user/buildroot/output/images/rootfs.tar.gz


When we now list the directory we can see that the root file system is now on our SD card:

user@laptop:/mnt/sdcard$ ls
bin  etc   lib    libexec  lost+found  media  opt   root  sbin  tmp  var
dev  home  lib64  linuxrc  marvell     mnt    proc  run   sys   usr


Next thing needed is to copy the kernel (here we will use v4.4.8) image (named Image) and the device tree generated for ESPRESSObin (named armada-3720-community.dtb) to our SD card. We will (acting as root) copy them to a new directory named boot:

user@laptop:/mnt/sdcard$ sudo mkdir -p boot
user@laptop:/mnt/sdcard$ sudo cp /home/user/kernel/4.4.8/arch/arm64/boot/Image boot/
user@laptop:/mnt/sdcard$ sudo cp /home/user/kernel/4.4.8/arch/arm64/boot/dts/marvell/armada-3720-community.dtb boot/


Our boot directory should now look like this:

user@laptop:/mnt/sdcard$ ls boot/
armada-3720-community.dtb  Image


Our SD card is now ready and contains the necessary images. Exit the mounted directory and unmount it from your local machine with:

user@laptop:/mnt/sdcard$ cd
user@laptop:/$ sudo umount /mnt/sdcard

 

Setting U-Boot parameters


Unplug the SD card from your local machine and plug it into the SD card slot on the ESPRESSObin, plug the power adapter and connect to the board via micro USB cable and serial connection as described in Quick User Guide, section Serial Connection.

For the ESPRESSObin to boot the images we have placed on the SD card, we must configure valid U-Boot parameters to do so. When the boot starts, hit any key to stop autoboot and get to the Marvell U-Boot prompt:

Hit any key to stop autoboot:
Marvell>>
Marvell>>


First we can check that the files on our SD card are recognized with ext4ls command which is used for listing files from an ext4-formatted partition and whose syntax is as follows:

ext4ls  <dev[:part]> [directory]


So in our case, we want to list contents from mmc device 0 and its first partition:

Marvell>> ext4ls mmc 0:1
       4096 .
       4096 ..
      16384 lost+found
         11 linuxrc
       4096 home
       4096 opt
       4096 lib
       4096 media
       4096 etc
       4096 marvell
       4096 proc
       4096 run
       4096 bin
       4096 usr
       4096 sbin
       4096 var
       4096 sys
       4096 root
       4096 tmp
       4096 mnt
       4096 dev
          3 lib64
       4096 libexec
       4096 boot
Marvell>> ext4ls mmc 0:1 boot
       4096 .
       4096 ..
            8175 armada-3720-community.dtb
        12358656 Image


Now on to setting U-Boot parameters. You can list all existing parameters with printenv command. There are only a few variables we need to set (other needed variables should be set by default) in order to boot from microSD card. First we set proper boot image name and device tree name:

Marvell>> setenv image_name boot/Image
Marvell>> setenv fdt_name boot/armada-3720-community.dtb


Next we setup the boot command by changing the bootmmc variable. We will use this variable to boot the microSD card:

Marvell>> setenv bootmmc 'mmc dev 0; ext4load mmc 0:1 $kernel_addr $image_name;ext4load mmc 0:1 $fdt_addr $fdt_name;setenv bootargs $console root=/dev/mmcblk0p1 rw rootwait; booti $kernel_addr - $fdt_addr'


Be careful to set the root variable to point to where you have extracted the root file system (in our case we extracted it to the first partition).

After this we will save the variables we have set so far:

Marvell>> save


You can save the variables at any desired moment. Note also that you can also setup the bootcmd variable for the ESPRESSObin to automatically boot from the microSD card every time you power up the board:

Marvell>> setenv bootcmd 'mmc dev 0; ext4load mmc 0:1 $kernel_addr $image_name;ext4load mmc 0:1 $fdt_addr $fdt_name;setenv bootargs $console root=/dev/mmcblk0p1 rw rootwait; booti $kernel_addr - $fdt_addr'

 

 Note

An important thing here is to check the values for default kernel load address (variable kernel_addr) and dtb load address (variable fdt_addr). If the kernel image is too large, it will overwrite the fdt table loaded to the memory. In such cases it is needed to modify fdt_addr to avoid dtb being overwritten by the kernel copy. To reassign dtb load address to, for example, 0x1800000, we would use:

Marvell>> setenv fdt_addr 0x1800000


Now we simply boot the kernel with:

Marvell>> run bootmmc


and after the kernel is successfully booted (see example bootlog here) you should get to the Buildroot login console:

Welcome to Buildroot
buildroot login:


Here login with root, after which you can check, depending on the kernel version you used, that everything has gone as expected:

Welcome to Buildroot
buildroot login: root
# uname -a
Linux buildroot 4.4.8-armada-17.02.1-g7aeb724 #2 SMP PREEMPT Tue Feb 7 16:48:36 CET 2017 aarch64 GNU/Linux
#


View an example bootlog here.

USB device


Here we will cover how to transfer necessary Buildroot files to USB device and boot from it.

Aside from few changes, booting from USB is quite similar to booting from microSD card, but we will go through the whole process again below.

Insert the USB device in your local Linux machine and run lsblk. Your USB device is probably listed as /dev/sd* device although this may vary:

user@laptop:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 238,5G 0 disk
├─sda1 8:1 0 487M 0 part /boot/efi
├─sda2 8:2 0 234,1G 0 part /
└─sda3 8:3 0 3,9G 0 part [SWAP]
sdb 8:16 1 7,5G 0 disk
└─sdb1 8:17 1 7,5G 0 part


We can see that our USB device is recognized as /dev/sdb/. Since we will be formatting our USB device we want to clear everything from it first (of course, backup content if necessary). We clear it with:

user@laptop:/$ sudo dd if=/dev/zero of=/dev/sdb bs=1M count=100
[sudo] password for user:
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 23,3945 s, 4,5 MB/s


and check again with lsblk that everything was cleared:

user@laptop:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 238,5G 0 disk
├─sda1 8:1 0 487M 0 part /boot/efi
├─sda2 8:2 0 234,1G 0 part /
└─sda3 8:3 0 3,9G 0 part [SWAP]
sdb 8:16 1 7,5G 0 disk


Now we will create a new partition (sdb1) on the empty USB device:

user@laptop:~$ (echo n; echo p; echo 1; echo ''; echo ''; echo w) | sudo fdisk /dev/sdb

Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
[...]
Created a new partition 1 of type 'Linux' and of size 7,5 GiB.

Command (m for help): The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.


and format it as EXT4 with:

  • For e2fsprogs < 1.43 use:
user@laptop:/$ sudo mkfs.ext4 /dev/sdb1
  • For e2fsprogs >=1.43 use:
user@laptop:/$ sudo mkfs.ext4 -O ^metadata_csum,^64bit /dev/sdb1


Next we mount this partition on our local Linux machine (e.g. we will mount it to /mnt/usb):

user@laptop:/$ sudo mkdir -p /mnt/usb
user@laptop:/$ sudo mount /dev/sdb1 /mnt/usb


Head into the mounted directory and there extract the root file system (rootfs.tar.gz) you have either built from source or downloaded:

user@laptop:/$ cd /mnt/usb
#if built from source
user@laptop:/mnt/usb$ sudo tar -xvf /home/user/buildroot/output/images/rootfs.tar.gz
#if downloaded from Tech Spec page
user@laptop:/mnt/usb$ sudo tar -xvf /path/to/archive/rootfs.tar.gz


When we now list the directory we can see that the root file system is now on our SD card:

user@laptop:/mnt/usb$ ls
bin  etc   lib    libexec  lost+found  media  opt   root  sbin  tmp  var
dev  home  lib64  linuxrc  marvell     mnt    proc  run   sys   usr


Next thing needed is to copy the kernel image (named Image) and the device tree generated for ESPRESSObin (named armada-3720-community.dtb) to our USB. We will (acting as root) copy them to a new directory named boot:

user@laptop:/mnt/usb$ sudo mkdir -p boot
user@laptop:/mnt/usb$ sudo cp /home/user/kernel/4.4.8/arch/arm64/boot/Image boot/
user@laptop:/mnt/usb$ sudo cp /home/user/kernel/4.4.8/arch/arm64/boot/dts/marvell/armada-3720-community.dtb boot/


Of course, in case you downloaded kernel from Tech Spec page, replace paths from above with paths where you extracted the images. Our boot directory should now look like this:

user@laptop:/mnt/usb$ ls boot/
armada-3720-community.dtb Image


Our USB device is now ready and contains the necessary images and filesystem. Exit the mounted directory and unmount it from your local machine with:

user@laptop:/mnt/usb$ cd
user@laptop:/$ sudo umount /mnt/usb

 

Setting U-Boot parameters


Unplug the USB device from your local machine and plug it into an USB port on the ESPRESSObin, plug the power adapter and connect to the board via micro USB cable and serial connection as described in Quick User Guide, section Serial Connection.

For the ESPRESSObin to boot the images we have placed on the SD card, we must configure valid U-Boot parameters to do so. When the boot starts, hit any key to stop autoboot and get to the Marvell U-Boot prompt:

Hit any key to stop autoboot:
Marvell>>
Marvell>>


First we can check that the necessary files are on our USB device with:

Marvell>> usb start(Re)start USB...USB0:   Register 2000104 NbrPorts 2Starting the controllerUSB XHCI 1.00scanning bus 0 for devices... 2 USB Device(s) found       scanning usb for storage devices... 1 Storage Device(s) found       scanning usb for ethernet devices... 0 Ethernet Device(s) foundMarvell>> ext4ls usb 0:1       4096 .       4096 ..      16384 lost+found       4096 libexec       4096 dev       4096 sbin       4096 sys       4096 etc       4096 usr       4096 marvell       4096 root          3 lib64       4096 run       4096 tmp         11 linuxrc       4096 media       4096 home       4096 bin       4096 opt       4096 lib       4096 var       4096 proc       4096 mnt       4096 bootMarvell>> ext4ls usb 0:1 boot       4096 .       4096 ..        12341760 Image            8175 armada-3720-community.dtb


using printenv we can list currently set U-Boot variables. If changed, here we need to set up correct values for image names:

Marvell>> setenv image_name boot/Image
Marvell>> setenv fdt_name boot/armada-3720-community.dtb


and set bootusb variable which we will use to boot from USB device:

Marvell>> setenv bootusb 'usb start;ext4load usb 0:1 $kernel_addr $image_name;ext4load usb 0:1 $fdt_addr $fdt_name;setenv bootargs $console root=/dev/sda1 rw rootwait; booti $kernel_addr - $fdt_addr'

after this we will save the environment we set so far:

Marvell>> save

and lastly we boot by issuing run bootusb (login with root):

Marvell>> run bootusb
(Re)start USB...
USB0:   Register 2000104 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
       scanning usb for ethernet devices... 0 Ethernet Device(s) found
12358656 bytes read in 993 ms (11.9 MiB/s)
8175 bytes read in 321 ms (24.4 KiB/s)
## Flattened Device Tree blob at 01000000
   Booting using the fdt blob at 0x1000000
   Using Device Tree in place at 0000000001000000, end 0000000001004fee

Starting kernel ...

Timer summary in microseconds:
       Mark    Elapsed  Stage
          0          0  reset
    747,000    747,000  id=64
    761,000     14,000  main_loop
    761,000          0  id=65
 84,067,000 83,306,000  usb_start
199,386,000115,319,000  bootm_start
203,932,000  4,546,000  start_kernel
203,932,000          0  id=15
119,415,317,249,578,296,40119,415,317,247,538,976,40  board_init_f

[...]

Starting vsftpd: OK
Starting HPA's tftpd: 
Welcome to Buildroot
buildroot login: root
#