← Back to list

Custom Embedded Linux From Scratch( Phase 5): Integration, Deployment, and Booting the BeagleBone…

In this final phase, we will assemble all pieces onto an SD card, configure the boot process, and bring our custom Linux system to life.

Shubham Gupta · 2026-03-05 11:02 · 0 claps · 6.5 min read
#embedded-linux #beaglebone-black #buildroot #u-boot #kernel
Open on Medium ↗
Wiki topics: 🔓 · Open Source

Custom Embedded Linux From Scratch( Phase 5): Integration, Deployment, and Booting the BeagleBone Black

Custom Embedded Linux for BeagleBone Black — Article Series

Toolchain → U-Boot → Kernel → RootFS → Booting
   ✓         ✓        ✓          ✓      ★

Over the previous phases of this series, we built each component required to create a fully custom embedded Linux system for the BeagleBone Black:

Phase 1: A cross-compilation toolchain:

[embed]Custom Embedded Linux for Beagle Bone Black Custom Embedded Linux for Beagle Bone Black In the world of IoT and embedded systems, most developers are content with…shubhamgupta577.medium.com

Phase 2: The U-Boot bootloader:

[embed]Custom Embedded Linux Phase 2: Compiling U-Boot for the BeagleBone Black Custom Embedded Linux Phase 2: Compiling U-Boot for the BeagleBone Black In Phase 1, we built the "Forge" - our custom…shubhamgupta577.medium.com

Phase 3: The Linux kernel and Device Tree:

[embed]Custom Embedded Linux Phase 3: Building Kernel for the BeagleBone Black Custom Embedded Linux Phase 3: Building Kernel for the BeagleBone Black For Phase 3, we move into the "Brain" of the…shubhamgupta577.medium.com

Phase 4: The Buildroot-generated Root Filesystem (RootFS):

[embed]Custom Embedded Linux Phase 4: Constructing the Root Filesystem with Buildroot In our previous phases, we built ashubhamgupta577.medium.com

At this point we have all the pieces required to run a complete operating system:

  • MLO → First stage bootloader
  • U-Boot → Main bootloader
  • Linux Kernel (zImage) → Core of the OS
  • Device Tree (.dtb) → Hardware map
  • Root Filesystem (RootFS) → User space environment

But these components are still just files sitting on our development machine.

To transform them into a bootable embedded system, they must be assembled, structured, and deployed onto physical storage in a format the BeagleBone Black can understand.

By the end of this phase, our custom firmware stack will move from source code to a running Linux system on the BeagleBone Black.

What You Will Learn

In this article we will cover:

  • Understanding the AM335x boot sequence
  • Partitioning an SD card for embedded Linux
  • Deploying bootloader, kernel, and root filesystem
  • Configuring U-Boot boot instructions
  • Booting and debugging the system via serial console

Now that every component of the system has been built, it is time to assemble them and bring the BeagleBone Black to life.

In this final phase, we will assemble these pieces onto an SD card, configure the boot process, and bring our custom Linux system to life on the BeagleBone Black.

1. Understanding the Boot Flow

Before copying files, it is important to understand what actually happens when the board powers on.

The boot sequence on the AM335x processor follows a strict order.

Each stage prepares the system for the next one. If any single component is missing or misconfigured, the board will fail to boot.

2. The Architectural Layout: Partitioning the SD Card

Embedded Linux rarely dumps every file into a single folder. To manage the different stages of the boot process, it uses distinct partitions to separate the bootloader, the kernel, and the userspace.

While many default setups use a 2-partition layout, we are using a highly modular 3-partition layout:

To manipulate block devices (like your SD card), you will need administrative privileges (sudo) on your host machine. You can use utilities like fdisk or gparted(GUI based)to destroy the existing partition table and create three new primary partitions

2.1 Preparing the SD Card

The BeagleBone Black ROM bootloader expects a specific partition layout.

We will create three partitions:

[embed]

Insert the SD card and identify its device name:

lsblk
#Assume the card appears as 
/dev/sdb

#Now start the partitioning tool:
sudo fdisk /dev/sdb

Create three partitions as per the table above

Note: Ensure the BOOT flag is enabled in first partition where MLO and UBoot lives

Write the partition table and exit.

2.2 Formatting the Partitions

Now we format all partitions.

Boot partition:

# Boot partition
sudo mkfs.vfat /dev/sdb1
# Kernel partition
sudo mkfs.ext4 /dev/sdb2
# RootFS partition
sudo mkfs.ext4 /dev/sdb3

2.3 Mount the Partitions

Create temporary mount points.

# Create temporary mount points.
mkdir boot
mkdir kernel
mkdir rootfs

# Mount them
sudo mount /dev/sdb1 boot
sudo mount /dev/sdb2 kernel
sudo mount /dev/sdb3 rootfs

Now the SD card is ready to receive our firmware.

2.4 Copy the Components

From previous phases, we already built:

MLO
u-boot.img
zImage
am335x-boneblack.dtb
rootfs.tar.xz

First copy the bootloader and kernel files to the partitions.

cp MLO boot/
cp u-boot.img boot/

sudo cp zImage kernel/
sudo cp am335x-boneblack.dtb kernel/

sudo tar -xvJf rootfs.tar.xz -C rootfs/

Question: Why did copying to the BOOT partition work fine without sudo, but copying to the KERNEL partition required it?

Answer: FAT32 does not support Linux permissions (owners/groups), so the OS mounts it with default user access. Ext4 does support permissions, and because the mount point is owned by root, it requires sudo to write to it.

(Note: You may notice a lost+found folder appear in Partitions 2 and 3. This is a standard feature of ext4 filesystems used for file recovery, which does not exist on FAT32.)

⚠️ Important rule: MLO must be the first file copied to the FAT partition.

The ROM bootloader reads the filesystem in order.

3. The Instruction Manual: Decoding uEnv.txt

The default U-Boot configuration often assumes a 2-partition setup. Because we built a 3-partition system, if we let U-Boot run automatically, it will look for the Kernel in the wrong place and fail.

We must manually tell U-Boot where to look by creating a uEnv.txt file in the BOOT partition.

Here is what the configuration logic looks like:

console=ttyS0,115200n8

loadaddr=0x82000000
fdtaddr=0x88000000

loadkernel=ext4load mmc 0:2 ${loadaddr} /zImage
loadfdt=ext4load mmc 0:2 ${fdtaddr} /am335x-boneblack.dtb

setbootargs=setenv bootargs console=${console} root=/dev/mmcblk0p3 rw rootfstype=ext4 rootwait

uenvcmd=echo Custom 3-Partition Boot; run setbootargs; run loadkernel; run loadfdt; bootz ${loadaddr} - ${fdtaddr}
  • Pointer 1 (The Kernel): The load mmc 0:2 command changes the boot partition source to Partition 2 (0:2), instructing U-Boot to pull the zImage and .dtb from there.
  • Pointer 2 (The RootFS): The bootargs variable includes root=/dev/mmcblk0p3. This tells the Linux kernel that once it takes over, it should mount the third partition as its root directory.
  • The Debug Tip: We added a custom echo message (echo "Custom Boot Starting") to verify on the serial console that our specific configuration is actually being loaded.

4. Booting the BeagleBone Black

4.1 Unmount the SD Card

Once everything is copied, unmount all partitions.

sudo umount boot
sudo umount kernel
sudo umount rootfs

Your SD card now contains a complete embedded Linux system.

If you plug this SD card into your BeagleBone Black, hold the boot button, and apply power, you will watch your serial console light up. U-Boot will pass the baton to your Kernel, your Kernel will parse your Device Tree, and your Root Filesystem will launch your BusyBox environment.

If everything is correct, you should see something similar to:

U-Boot 2025.xx
Loading kernel...
Starting kernel...

After a few seconds:

Welcome to Buildroot
buildroot login:

Congratulations — your custom Linux system is now running.

5. Debugging Boot Failures

Boot failures are common in embedded development. Here are the most frequent problems.

Kernel Panic: Unable to mount rootfs

Cause: root=/dev/mmcblkop2 incorrect

Fix: Ensure the root filesystem partition number is correct.

Board stops at U-Boot

Cause: Kernel or DTB file missing.

Fix: Verify files exist in the boot partition.

No serial output

Cause: Wrong console device.

Fix: console=ttyS0, 115200

Pro Tip: If the BeagleBone fails to boot from SD card, verify that MLO was copied first. The AM335x ROM loader reads the FAT filesystem sequentially and expects the first-stage bootloader to appear early in the directory structure.

6. The Security Perspective: Connecting the Dots for Pentesting

Since this series is geared towards Firmware Pentesting, understanding this physical deployment phase is arguably the most important lesson.

When you dump a real firmware image from a commercial IoT router or camera using a tool like binwalk, you will often see this exact structure: a FAT header (bootloader) followed by SquashFS or Ext4 sections (Kernel/RootFS).

Because you built this structure by hand, you now know exactly how to attack it:

  • Persistence: If an attacker gains write access to Partition 2, they can replace the zImage with a malicious kernel, allowing persistent control over the device even after firmware resets.
  • Config Injection: If you can write to Partition 1, you can edit uEnv.txt to change the boot arguments. By simply adding init=/bin/sh, you can force the kernel to bypass all login prompts and drop you into a root shell.

7. Conclusion: From Source Code to Running Linux

In this series, we constructed an entire embedded Linux system step-by-step.

We learned how to:

  • Build a cross-compilation toolchain
  • Compile the U-Boot bootloader
  • Configure and build the Linux Kernel
  • Generate a Root Filesystem with Buildroot
  • Assemble everything and boot the BeagleBone Black

This process reveals something important about embedded systems:

The operating system is not a single program — it is a carefully orchestrated chain of components, each responsible for preparing the system for the next stage.

Understanding this chain is what separates someone who simply uses embedded Linux from someone who truly understands how it works.

The Full System Architecture

At the end of this series, we now understand every layer of an embedded Linux system. Have a look at it as a relay race

But by building everything manually, we now understand how each component depends on the others.

If you are joining this article directly, you can start from the beginning of the series.

1️⃣ Phase 1 — Toolchain Setup 2️⃣ Phase 2 — Compiling U-Boot 3️⃣ Phase 3 — Building the Linux Kernel 4️⃣ Phase 4 — Constructing the Root Filesystem 5️⃣ Phase 5 — Integration and Booting the System

Previous article — RootFS using Buildroot


메타데이터
post_id
eb35d998566a
slug
custom-embedded-linux-from-scratch-phase-5-integration-deployment-and-booting-the-beaglebone-eb35d998566a
url
https://medium.com/@shubhamgupta577/custom-embedded-linux-from-scratch-phase-5-integration-deployment-and-booting-the-beaglebone-eb35d998566a
canonical_url
https://medium.com/@shubhamgupta577/custom-embedded-linux-from-scratch-phase-5-integration-deployment-and-booting-the-beaglebone-eb35d998566a
author_url
https://medium.com/@shubhamgupta577
status
ok
fetched_at
2026-07-15 04:16:48