Posts tagged ‘debian’

While having pre-configured devices is super-fun for getting started quickly, I usually want to know exactly what is installed on them. So I spent some time installing my BeagleBone from scratch.

U-Boot – the bootloader

First step is the boot-loader. The ROM bootloader loads the 2nd stage bootloader in to on-chip RAM and executes it. On-chip RAM is limited to just over 100kB, not enough for a full fledged bootloader. So U-boot is itself split in 2 stages, typically called MLO and u-boot.img.

To build these, I downloaded the git repository of U-Boot, applied Robert Nelson’s patches (you’ll recognise that name if you did some BeagleBone Googling before) and did:

patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
make distclean
make am335x_boneblack_config

I have no idea what these patches do, but everyone seems to apply them…

You can probably cross-compile these on your x86-based workstation, but I just run the compile on the BeagleBone itself. I copied the resulting files to the SD-card: MLO and u-boot.img. Booting with S2 pressed greeted me with:

U-Boot SPL 2017Trying to boot from MMC1
reading u-boot.img
reading u-boot.img

U-Boot 2017.07-00043-g8822c8f (Jul 11 2017 - 19:34:01 +0000)

CPU  : AM335X-GP rev 2.1
I2C:   ready
DRAM:  512 MiB
No match for driver 'omap_hsmmc'
No match for driver 'omap_hsmmc'
Some drivers were not found
Reset Source: Power-on reset has occurred.
Using default environment

Board: BeagleBone Black
 not set. Validating first E-fuse MAC
Net:   eth0: MII MODE
Press SPACE to abort autoboot in 2 seconds

A minimal Debian image

I used debootstrap to generate a minimal Debian environment:

debootstrap --verbose --variant=minbase stretch /mnt

I bootstrapped in to a loop-mounted file, but you can do that straight to an SD-card if you’re brave.

I had trouble getting this to work from the shipped Wheezy. debootstrap stopped with:

I: Extracting liblzma5...
I: Extracting zlib1g...
E: no . cannot create devices

The problem seems to be that Wheezy doesn’t use devfs. I tar’ed up /dev and export DEVICES_TARGZ=/mnt/dev.targz to get through this point, then removed the extracted files from the target.

Since minbase is really minimal, I added the following:

  • apt-get install --no-install-recommends openssh-server
  • apt-get install vim iproute2 iputils-ping kmod less ifupdown init udev
  • echo "deb stretch main" >> /mnt/etc/apt/sources.list; apt-get update
  • apt-get install linux-image-4.9.36-ti-r45
  • echo "/dev/mmcblk0p2 / ext4 defaults 0 1" > /mnt/etc/fstab
  • cp /etc/hosts /mnt/etc/hosts
  • configure /etc/network/interfaces or /etc/network/interfaces.d/

OK, well, to be honest, the above list was compiled from several trail-and-error attempts to get the image to boot… Who could have guessed you need a kernel to actually boot 😉 If you’re lazy, you can just extract my tarball, and try to log in on via USB with SSH as root (password admin).

Now you can either manually boot the kernel in U-Boot:

load mmc 0:2 ${loadaddr} /boot/vmlinuz-4.9.36-ti-r45
load mmc 0:2 ${fdtaddr} /boot/dtbs/4.9.36-ti-r45/am335x-boneblack.dtb
set bootargs console=tty0 console=ttyS0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait fixrtc init=/lib/systemd/systemd
bootz ${loadaddr} - ${fdtaddr}

Or put the equivalent commands in uEnv.txt on the FAT partition: (I copied the kernel & Flattened Device Tree file to the FAT partition (mmc 0:1) for easier debugging).

bootargs=console=tty0 console=ttyS0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait fixrtc init=/lib/systemd/systemd
uenvcmd=load mmc 0:1 ${loadaddr} kernel.img; load mmc 0:1 ${fdtaddr} fdt; bootz ${loadaddr} - ${fdtaddr}

Some notes:

  • The boot takes ~3 minutes longer than it should, because systemd waits for eth0 to come up (which it won’t because it’s not connected), only giving up after a few minutes.
  • If you have trouble getting the serial console to work because systemd can’t find dev-ttyS0.device, make sure you installed udev


My BeagleBone Black came pre-installed with a 2-year-old Debian Wheezy on it’s eMMC chip (image, hashes). The out-of-the-box experience is actually quite impressive: the BeagleBone presents itself over the USB bus as a mass storage device with the needed drivers and some documentation. Once you install the driver (only the RNDIS is needed, the Black does not have a serial-over-USB anymore), you can just surf to the BeagleBone and control USER-LEDs from your web browser. Impressive!

But I don’t want nor need these fancy features eating up CPU, disk space and RAM, so I went looking for a minimal Debian image to use. Besides the bare minimum, I wanted the Ethernet-over-USB to work, and SSH.

  1. Get a copy of the BeagleBoard image builder
  2. Build a rootfs tarball for the desired config. I used, which matched my requirements quite nicely. You can see the (additional) packages that will be installed listed in the corresponding config file.
    ./ -c
  3. From the generated directory inside deploy, run
    ./ --img-1gb ~/disk-image.img --dtb beaglebone

    I wanted to keep the FAT boot partition, which is no longer needed, so I reverted that part of the commit before running the above command.

  4. dd the generated image (hash) onto an SD card.

To boot from the SD card, press the boot button (S2) at power-on and release when the 4 User-LEDs are on. Be patient: it took my board ~90 seconds to get SSHd up and running.

Note: sometimes, udhcpd would refuse to start. Rebooting (i.e. press the power button (S3) briefly, wait for the LEDs to go off, press-and-hold S2, press S3, release S2 when 4 LEDs are on) helped. I’m guessing it’s a race condition on bootup that sometimes prevent udhcpd from starting. Manually assigning your side also works.

You can use the /opt/scripts/tools/ script to grow the root partition to the actual size of the SD card instead of the 1GB it originally has.

I’ve been re-searching for this page long enough to make a note this time. (local copy)