innercoder.com

A blog for Linux programming enthusiasts

Setup Network Boot With BeagleBone Black and U-Boot on SD Card

| Comments

I recently started reading a book called Operating System Design by Douglas Comer. I like the engineering point of view of the book, similar to Tanenbaum’s Operating System Design and Implementation. This post is about getting U-Boot on the BeagleBone and booting the Xinu OS from a TFTP server. Of course, some pieces can be taken from this post to help in other similar situations.

Something that is not very clear in the book’s webpage is the best way to setup the beaglebone to constanly load the OS after changes have been made. They have the instructions for the Intel Galileo but not for the Beaglebone, but they are actually quite similar. These instructions will be based using Debian 7.5 using common packages that should be found in other distributions.

If you follow the instructions you will go through these steps:

  1. Setup a machine to TFTP from. This could be a virtual machine or the actual machine you are using. I will skip this step.
  2. You will need to install a dhcp and tftp server. I used the packages isc-dhcp-server and tftpd-hpa respectively. They are very easy to setup.
  3. Setup an SD card with u-boot.
  4. Connect to the beaglebone via serial cable.
  5. Run uboot.

Setup DHCP and TFTP

For the TFTP server, I decided to install the package tftpd-hpa. Once installed, the configuration file goes is installed at /etc/default/tftpd-hpa". Here is a sample configuration.

1
2
3
4
5
6
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"

For the DHCP server, I installed the package isc-dhcp-server. The configuration file is located at /etc/dhcp/dhcpd.conf. It has a long configuration file, look for this specific part.

1
2
3
4
5
6
7
8
9
10
11
12
13
# A slightly different configuration for an internal subnet.
subnet 192.168.27.0 netmask 255.255.255.0 {
   range 192.168.27.2 192.168.27.4;
   option subnet-mask 255.255.255.0;
   next-server 192.168.27.1;
   filename "xinu.boot";
#  option domain-name-servers ns1.internal.example.org;
#  option domain-name "internal.example.org";
#  option routers 10.5.5.1;
#  option broadcast-address 10.5.5.31;
#  default-lease-time 600;
#  max-lease-time 7200;
}

The included filename parameter is necessary for the tftp boot. This file will be retrieved by u-boot in the Beaglebone.


Setup U-Boot

What you will need is:

For the cross-compiler I used Emdebian. Add the following to the apt sources file. The authors still recommend the use of the Squeeze toolschains.

1
2
# Embedian
deb http://www.emdebian.org/debian/ squeeze main

Install the following packages for the needed dependencies. The last two commands are the actual cross-compilers. For both C and C++.

1
2
3
4
5
6
apt-get install emdebian-archive-keyring
apt-get install linux-libc-dev-armel-cross
apt-get install libc6-armel-cross libc6-dev-armel-cross
apt-get install binutils-arm-linux-gnueabi
apt-get install gcc-4.4-arm-linux-gnueabi
apt-get install g++-4.4-arm-linux-gnueabi

Download the latest source for u-boot. At the time of writing I got u-boot-2015.10.

To cross compile it, follow these steps.

  • Locate the arm compiler binary.
1
2
which arm-linux-gnueabi-gcc-4.4
/usr/bin/arm-linux-gnueabi-gcc-4.4
  • Export these location to a variable in your current shell session, removing the trailing gcc-4.4 at the end.
1
export CC=/usr/bin/arm-linux-gnueabi-
  • Clean compilation area, configure, and compile.
1
2
3
make ARCH=arm CROSS_COMPILE=${CC} distclean
make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig
make ARCH=arm CROSS_COMPILE=${CC}

The am335x was obtained from a previous source of u-boot, in the file boards.cfg.

Whe the compilation finishes, you will see the files MLO and u-boot.img.

There are a lot of tutorials to compile and install U-boot in the SD card. Here is a popular one by Robert Nelson at https://eewiki.net/display/linuxonarm/BeagleBone+Black#BeagleBoneBlack-Bootloader:U-Boot

Once U-boot has compiled you will need to prepare the SD card. Basically this SD card will contain the U-boot bootloader which will then can be scripted to automatically load the OS image from either a TFTP or NFS server. First identify the correct device directory for the SD card, it is usually called /dev/mmcblk0. Perform the following step using the dd command.

1
sudo dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=256

This is to clear any possible previous content. Now ,we need only one partition we need only one bootable partition with 64MB. I used fdisk. You need your partition table looking like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo fdisk /dev/mmcblk0

Command (m for help): p

Disk /dev/mmcblk0: 15.9 GB, 15931539456 bytes
4 heads, 16 sectors/track, 486192 cylinders, total 31116288 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x7099e902

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1   *        2048      133119       65536   83  Linux

Command (m for help): q

Now format this partition to FAT32.

1
sudo mkfs.vfat -F 32 /dev/mmcblk0p1

We can now copy the generated MLO and u-boot.img to the MMC card.


Testing

Now, plug the MMC card to the BeagleBone and if everything went correctly. You will see this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
U-Boot SPL 2013.04-dirty (Jul 10 2013 - 14:02:53)
musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
musb-hdrc: MHDRC RTL version 2.0
musb-hdrc: setup fifo_mode 4
musb-hdrc: 28/31 max ep, 16384/16384 memory
USB Peripheral mode controller at 47401000 using PIO, IRQ 0
musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
musb-hdrc: MHDRC RTL version 2.0
musb-hdrc: setup fifo_mode 4
musb-hdrc: 28/31 max ep, 16384/16384 memory
USB Host mode controller at 47401800 using PIO, IRQ 0
OMAP SD/MMC: 0
mmc_send_cmd : timeout: No status update
reading u-boot.img
reading u-boot.img


U-Boot 2013.04-dirty (Jul 10 2013 - 14:02:53)

I2C:   ready
DRAM:  512 MiB
WARNING: Caches not enabled
NAND:  No NAND device found!!!
0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
** Warning - readenv() failed, using default environment

musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
musb-hdrc: MHDRC RTL version 2.0
musb-hdrc: setup fifo_mode 4
musb-hdrc: 28/31 max ep, 16384/16384 memory
USB Peripheral mode controller at 47401000 using PIO, IRQ 0
musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
musb-hdrc: MHDRC RTL version 2.0
musb-hdrc: setup fifo_mode 4
musb-hdrc: 28/31 max ep, 16384/16384 memory
USB Host mode controller at 47401800 using PIO, IRQ 0
Net:   <ethaddr> not set. Validating first E-fuse MAC
cpsw, usb_ether
Hit any key to stop autoboot:  0
gpio: pin 53 (gpio 53) value is 1
mmc0 is current device
micro SD card found
mmc0 is current device
gpio: pin 54 (gpio 54) value is 1
SD/MMC found on device 0
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **
gpio: pin 55 (gpio 55) value is 1
** No partition table - mmc 0 **
U-Boot#

If the DHCP and TFTP servers are good to go, you can test them with the following command.

1
2
3
4
5
6
7
8
9
10
U-Boot# tftpboot
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.27.1; our IP address is 192.168.27.4
Filename 'xinu.boot'.
Load address: 0x80200000
Loading: #######
   662.1 KiB/s
done
Bytes transferred = 90176 (16040 hex)

After that you can boot into Xinu with

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
U-Boot# bootm
## Booting kernel from Legacy Image at 80200000 ...
   Image Name:
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    90112 Bytes = 88 KiB
   Load Address: 81000000
   Entry Point:  81000000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Ethernet Link is Up. Speed is 100Mbps
Link is Full Duplex
MAC Address is: 1C:BA:8C:A1:03:9A

Xinu for bbb -- version #96  (root)  Tue Sep  1 00:40:49 CDT 2015

 519739936 bytes of free memory.  Free list:
           [0x810505E0 to 0x9FFF9FFF]
     84876 bytes of Xinu code.
           [0x81000000 to 0x81014B8B]
    131972 bytes of data.
           [0x81015000 to 0x81035383]

mac addr: 9a03 a18cba1c
...initializing network stack
...using dhcp to obtain an IP address
dhcp: got offer send req
calling udp_sendto

IP address is 192.168.27.4   (0xc0a81b04)
Subnet mask is 255.255.255.0 and router is 0.0.0.0

...creating a shell


------------------------------------------
   __    __   _____    _   _    _    _
   \ \  / /  |__ __|  | \ | |  | |  | |
    \ \/ /     | |    |  \| |  | |  | |
    / /\ \    _| |_   | \   |  | |  | |
   / /  \ \  |     |  | | \ |  \  --  /
   --    --   -----    -   -     ----
------------------------------------------


Welcome to Xinu!


xsh $

The commands to build the Xinu image are very simple. The actual download is self-suficient and requires no external packages. Everything is included in it.

Let me know your thoughts, questions, or feedback. Regards.

Comments