BeagleBone Buildroot
building a Linux image for the BeagleBone Black
I'm going through the Bootlin training for BeagleBone Black with Buildroot. Even though it says it's for the BeagleBone Black board, it's for the wireless version, which doesn't seem available but the regular Black board still is.
So I'm putting up my own notes on it. There's also another tutorial that covers this that I also referenced. I also found the BeagleBone System Reference Manual. The source for the training PDFs is also interesting to see how they made them with LaTeX. I got the board from Adafruit, which I found also has a document on the BeagleBone Black device tree
The Bootlin slides go into details, but it could be used more as a reference. You don't have to use go through that to go through the lab, so you can just do the lab.
First, get their lab materials and extract to the directory you want to keep it. Also make sure you're up to date.
#cd to the directory you want this to live wget https://bootlin.com/doc/training/buildroot/buildroot-labs.tar.xz tar xvf buildroot-labs.tar.xz sudo apt update sudo apt dist-upgrade cd buildroot-labs/
Install the required dependencies. It called for just python, but there was only python3 for me, but I did see something called python-is-python3 which if you need something called just python maybe that will work. I also needed to add the ssl library. Also installs the serial communication program picocom we'll use later.
sudo apt install sed make binutils gcc g++ bash patch gzip bzip2 perl tar cpio python3 unzip rsync wget libncurses-dev libssl-dev picocom
Clone buildroot into the lab directory and checkout the version we'll use. Maybe look at tags and take whatever latest you want.
git clone https://git.buildroot.net/buildroot cd buildroot git checkout -b bootlin 2022.02
There's already a beaglebone_defconfig, but we'll build our own. We'll configure it with menuconfig.
make menuconfig
Now change the configuration:
- Target Options (hit enter to enter the submenu)
- Target Architecture
- Select Arm (little endian) (looks like can hit enter or space)
- Target Architecture Variant
- Select cortex-A8
- Target Architecture
- Exit out of Target Options (hit right arrow onto Exit, hit enter), go into Toolchain
- Toolchain type
- Select External toolchain (Buildroot's toolchain apparently takes a lot of time)
- Toolchain
- Select ARM 2021.07 (was already that by default for me)
- Toolchain type
- System Configuration
- System hostname: set to what you want - "mycoolbeagleboneblack"
- System banner: set to what you want - "Welcome to my cool BeagleBone!"
- Enable root login with password, then set password underneath that
- Kernel
- enable Linux Kernel (press space)
- Kernel version, can select the latest but the bootlin tutorial wants us to select Custom Version and enter 5.15.35 for the version underneath.
- Defconfig name, set to omap2plus - you can look at the Linux configs for support of this AM335X and find it in omap2plus_defconfig that has the line CONFIG_SOC_AM33XX=y.
- Kernel binary format, zImage (was that by default for me)
- enable Device Tree Blob
- then set In-tree Device Tree Source file names to am335x-boneblack, you can see in the Linux dts there's one called am335x-boneblack
- enable Needs host OpenSSL
- enable Linux Kernel (press space)
- Target packages
- enable Busybox, was by default for me. Nothing else is needed, but you can other stuff like GDB and gdbserver for remote debugging, or games, dropbear to be able to ssh into it
- Bootloaders, enable U-Boot
- Build system, use Kconfig
- U-Boot version, select Custom version. Then underneath set U-Boot version to 2022.04
- Board defconfig set to am335x_evm. I think that other tutorial has this as U-Boot configuration. Looking at U-Boot configs, you can see there's a am335x_evm_defconfig.
- U-Boot binary format, unselect u-boot.bin (because don't need i guess maybe this will be faster), and set to u-boot.img
- enable Install U-Boot SPL binary image
- set U-Boot SPL/TPL binary image name(s) to MLO
- Custom make options, set to DEVICE_TREE=am335x_boneblack. I don't think that other tutorial has this part.
If you see U-Boot board name, you might have something set wrong, or a change didn't get saved. Go through these settings again.
Then save and exit. Now you can make it, by splitting the output to an output file while also still printing to the terminal:
make 2>&1 | tee build.log
While that's building, set up the board. I got a USB to TTL serial cable from Adafruit. It's wires are different than whatever they must use in the bootlin tutorial. On the Adafruit one, It has:
- Red: power
- Black: ground
- White: RX into USB port
- Green: TX out of USB port
Connect ground (black) to the pin closest to power/eth (call that pin 1). The connect the USB TX (green) to the board's RX (pin 4), and the USB RX (white) to the board's TX (pin 5).
Do NOT connect the red power wire. Documentation somewhere said connecting power could fry the serial connection on the board since it doesn't need it.
When you plug in the serial connector you should see it come up as /dev/ttyUSB0. You can also see it appear when you run dmesg.
If you didn't install the serial communication program picocom in the previous step and don't have another one you'd prefer to use, you can do that now.
sudo apt install picocom
You can see only the user root and the group dialout can write to /dev/ttyUSB0. Add yourself to the group dialout.
sudo adduser $USER dialout
If you run groups
you'll see you're not yet part of the group dialout. You have to restart you computer for the change to take affect, so wait until you're done building and prepare an SD card in the mean time.
See what devices are on your computer with cat /proc/partitions
or lsblk
. Then connect your SD card and check devices again to see which is your SD card. You can also see the output of dmesg
. Let's say our SD card is at /dev/sdd (But yours might be something else! Verify what it is!)
Unmount your SD card. Then erase the beginning of the SD card to be sure the existing partitions aren't detected. Double check which device is your SD card! /dev/sdd is just the example we're using here! Yours might be different!
sudo dd if=/dev/zero of=/dev/sdd bs=1M count=16
Create two partitions:
sudo cfdisk /dev/sdd
- Choose dos partition table type
- Select New on the free space and create the first small partition (128MB), primary, with type e (W95 FAT16), mark bootable
- On the rest of the free space, select new to create another partition using the rest of the space, also primary, type 83 (Linux)
- Select write and quit
- Format the first partition as FAT32
sudo mkfs.vfat -a -F 32 -n boot /dev/sdd1
sudo mkfs.ext4 -L rootfs -E nodiscard /dev/sdd2
-L assigns a volume name to the partition
-E nodiscard disables bad block discarding. While this should be a useful option for cards with bad blocks, skipping this step saves long minutes in SD cards.
Remove the SD card and insert it again, the two partitions should be mounted automatically, in /media/$USER/boot and /media/$USER/rootfs.
Wait for the build to complete if it hasn't already.
Copy the MLO, u-boot.img, zImage and am335x-boneblack.dtb files from output/images/ to the boot partition of the SD card.
cp output/images/MLO output/images/u-boot.img output/images/zImage output/images/am335x-boneblack.dtb /media/eric/boot/
I like to run sync
after copying files to disks to be sure it was written.
Extract the rootfs.tar file to the rootfs partition of the SD card.
sudo tar -C /media/$USER/rootfs/ -xf output/images/rootfs.tar
Create extlinux/extlinux.conf in the boot partition with
label buildroot kernel /zImage devicetree /am335x-boneblack.dtb append console=ttyO0,115200 root=/dev/mmcblk0p2 rootwait
Dismount and remove the SD card, insert into the board. Start the serial program.
picocom -b 115200 /dev/ttyUSB0
You can quit picocom with ctrl-a then ctrl-x.
Hold the S2 button (the one by the USB port) and power the board to tell it to boot from the SD card instead of the eMMC.
Make sure you see the U-Boot version and date looks right. Login as root and with the password you chose, and explore the system.
The article also has this:
Note: if your system doesn’t boot as expected, make sure to reset the U-Boot environment by running the following U-Boot commands:
env default -f -a saveenv
and reset. This is needed because the U-Boot loaded from the SD card still loads the U-Boot environment from the eMMC.