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 make
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. MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 Using default environment Board: BeagleBone Black not set. Validating first E-fuse MAC Net: eth0: MII MODE cpsw 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 http://deb.debian.org/debian/
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 http://repos.rcn-ee.com/debian/ 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 192.168.7.2 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 finddev-ttyS0.device
, make sure you installedudev