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-serverapt-get install vim iproute2 iputils-ping kmod less ifupdown init udevecho "deb http://repos.rcn-ee.com/debian/ stretch main" >> /mnt/etc/apt/sources.list; apt-get updateapt-get install linux-image-4.9.36-ti-r45echo "/dev/mmcblk0p2 / ext4 defaults 0 1" > /mnt/etc/fstabcp /etc/hosts /mnt/etc/hosts- configure
/etc/network/interfacesor/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
systemdwaits 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
systemdcan’t finddev-ttyS0.device, make sure you installedudev