Create a gist now

Instantly share code, notes, and snippets.

Minimalist "Embedded Linux from Scratch" Beaglebone Distribution Build

Busybox "Embedded Linux from Scratch" Distribution for the Beaglebone

Prepare your Build Sandbox

$ mkdir -p beaglelfs/{sources,rootfs_install,boot_mnt,rootfs_mnt}

Acquire an ARM Toolchain

Download the latest i686 Binary TAR of the ARM GNU/Linux (glibc-based) Lite Toolchain:

http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/arm-gnu-linux

$ tar xvfj arm-2011.09-70-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
$ export PATH=/path/to/arm-2011.09/bin:$PATH

Build MLO and U-Boot

$ cd /path/to/beaglelfs/sources/
$ git clone git://arago-project.org/git/projects/u-boot-am33x.git
$ cd u-boot-am33x
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- am335x_evm_config
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

This produces the TI first stage bootloader "MLO", and u-boot bootloader "u-boot.img".

Build the Linux Kernel

$ cd /path/to/beaglelfs/sources/
$ git clone git://arago-project.org/git/projects/linux-am33x.git
$ cd linux-am33x
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- am335x_evm_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig
    Device Drivers -> Generic Driver Options -> Maintain a devtmpfs filesystem to mount at /dev
    Device Drivers -> Generic Driver Options -> Automount devtmpfs at /dev, after the kernel mounted the rootfs
$ make -j4 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- EXTRA_CFLAGS=-mno-unaligned-access uImage

(You may need to install the uboot-mkimage package or include
 u-boot-am33x/tools in your path for the mkimage tool)

This produces the Linux kernel image arch/arm/boot/uImage.

$ make -j4 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- EXTRA_CFLAGS=-mno-unaligned-access modules
$ sudo make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- EXTRA_CFLAGS=-mno-unaligned-access INSTALL_MOD_PATH=/path/to/beaglelfs/rootfs_install modules_install

This installs any kernel modules to the root file system temporary installation folder.

Build Busybox

$ cd /path/to/beaglelfs/sources/
$ git clone git://busybox.net/busybox.git
$ cd busybox
$ git checkout remotes/origin/1_19_stable
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- defconfig
$ LDFLAGS="--static" make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j4
$ LDFLAGS="--static" make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install
$ rsync -a _install/ /path/to/beaglelfs/rootfs_install/

This produces the statically-linked busybox and all of the symlinks
that let it multiplex multiple programs.

Setup essential root filesystem files

$ cd /path/to/beaglelfs/rootfs_install

Create Core Device files
$ mkdir dev
$ sudo mknod dev/console c 5 1
$ sudo mknod dev/null c 1 3

Create a basic inittab for init
$ mkdir etc
$ cat >> etc/inittab
null::sysinit:/bin/mount -t proc proc /proc
null::sysinit:/bin/hostname -F /etc/hostname
null::respawn:/sbin/getty -L ttyO0 115200 vt100
null::shutdown:/sbin/mount -a -r
^D

Create the mountpoint for proc
$ mkdir proc

Create a root user with an empty password
$ mkdir root
$ cat >> etc/passwd
root:x:0:0:root:/root:/bin/sh
^D
$ cat >> etc/shadow
root::10933:0:99999:7:::
^D

Install a basic udhcpc script
$ mkdir -p usr/share/udhcpc
$ cp /path/to/beaglelfs/sources/busybox/examples/udhcp/simple.script usr/share/udhcpc/default.script

Designate a hostname
$ cat >> etc/hostname
minibeagle
^D

Create an SD Card Image File

Create and Partition the Image
$ dd if=/dev/zero of=sdcard.img bs=1M count=128
$ echo "Cylinders: " `du -b sdcard.img | awk '{print int($1/255/63/512)}'`
$ fdisk sdcard.img
x for expert mode
h to set heads to 255
s to set sectors to 63
c to set cylinders to value above
r to return to normal mode
n for new partition: primary, number 1, default first sector, +16M size
t to set type of partition with code: c (W95 FAT32 LBA)
a to mark bootable partition number 1
n for new partition: primary, number 2, default first sector, default full size
w to write the partition table

Map block devices to the image
$ sudo modprobe loop
$ sudo losetup /dev/loop0 sdcard.img
$ sudo kpartx -av /dev/loop0

Format the boot and root partitions of the image
$ sudo mkfs.vfat -F 16 -n "boot" /dev/mapper/loop0p1
$ sudo mkfs.ext3 -L "rootfs" /dev/mapper/loop0p2

Mount the SD Card Image File, Copy Bootloaders, Kernel, Rootfs

Mount boot (FAT) and rootfs (ext3) partitions
$ cd /path/to/beaglelfs/
$ sudo mount /dev/mapper/loop0p1 boot_mnt
$ sudo mount /dev/mapper/loop0p2 rootfs_mnt

Copy TI bootloader, u-boot bootloader, kernel image to boot partition
$ sudo cp /path/to/beaglelfs/sources/u-boot-am33x/MLO boot_mnt/
$ sudo cp /path/to/beaglelfs/sources/u-boot-am33x/u-boot.img boot_mnt/
$ sudo cp /path/to/beaglelfs/sources/linux-am33x/arch/arm/boot/uImage boot_mnt/
$ sudo umount boot_mnt

Copy root filesystem and chown it to root
$ sudo rsync -a rootfs_install/ rootfs_mnt/
$ sudo chown -R root:root rootfs_mnt/*
$ sudo umount rootfs_mnt

Unassociate the loopback device
$ sudo kpartx -d /dev/loop0
$ sudo losetup -d /dev/loop0

Copy the SD Card Image File to a Real SD Card

$ sudo dd if=sdcard.img of=/dev/sdcardblockdevice bs=1M

Load the ftdi serial driver

$ sudo rmmod ftdi_sio usbserial
$ sudo modprobe ftdi_sio vendor=0x0403 product=0xa6d0

Boot up the Beaglebone!

Observe the boot output in your favorite serial port terminal on /dev/ttyUSB0 (typically).

U-Boot SPL 2011.09-00002-gd0e52e5 (Apr 14 2012 - 22:13:07)
Texas Instruments Revision detection unimplemented
No AC power, disabling frequency switch
OMAP SD/MMC: 0
reading u-boot.img
reading u-boot.img


U-Boot 2011.09-00002-gd0e52e5 (Apr 14 2012 - 22:13:07)

I2C:   ready
DRAM:  256 MiB
WARNING: Caches not enabled
No daughter card present
NAND:  HW ECC Hamming Code selected
No NAND device found!!!
0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
*** Warning - readenv() failed, using default environment

Net:   cpsw
Hit any key to stop autoboot:  3 ��� 2 ��� 1 ��� 0 
SD/MMC found on device 0
reading uEnv.txt

** Unable to read "uEnv.txt" from mmc 0:1 **
reading uImage

3132976 bytes read
## Booting kernel from Legacy Image at 80007fc0 ...
   Image Name:   Linux-3.1.0-00010-g66bfbd2
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3132912 Bytes = 3 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   XIP Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Linux version 3.1.0-00010-g66bfbd2 (anteater@anteater-laptop) (gcc version 4.6.1 (Sourcery CodeBench Lite 2011.09-70) ) #3 Sun Apr 15 03:47:19 EDT 2012
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7f
[    0.000000] CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine: am335xevm
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] AM335X ES1.0 (neon )
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
[    0.000000] Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait ip=none
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Memory: 256MB = 256MB total
[    0.000000] Memory: 253516k/253516k available, 8628k reserved, 0K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     DMA     : 0xffa00000 - 0xffe00000   (   4 MB)
[    0.000000]     vmalloc : 0xd0800000 - 0xf8000000   ( 632 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0569000   (5508 kB)
[    0.000000]       .init : 0xc0569000 - 0xc05a2000   ( 228 kB)
[    0.000000]       .data : 0xc05a2000 - 0xc05f7380   ( 341 kB)
[    0.000000]        .bss : 0xc05f73a4 - 0xc0631920   ( 234 kB)
[    0.000000] NR_IRQS:396
[    0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
[    0.000000] Total of 128 interrupts on 1 active controller
[    0.000000] OMAP clockevent source: GPTIMER1 at 24000000 Hz
[    0.000000] OMAP clocksource: GPTIMER2 at 24000000 Hz
[    0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[    0.000000] Console: colour dummy device 80x30
[    0.000248] Calibrating delay loop... 498.89 BogoMIPS (lpj=2494464)
[    0.058636] pid_max: default: 32768 minimum: 301
[    0.058804] Security Framework initialized
[    0.058931] Mount-cache hash table entries: 512
[    0.059386] CPU: Testing write buffer coherency: ok
[    0.060496] devtmpfs: initialized
[    0.065357] print_constraints: dummy: 
[    0.065822] NET: Registered protocol family 16
[    0.066246] GPMC revision 6.0
[    0.069136] OMAP GPIO hardware version 0.1
[    0.071965] omap_l3_smx omap_l3_smx.0: couldn't find resource
[    0.072625] omap_mux_init: Add partition: #1: core, flags: 0
[    0.076608]  omap_i2c.1: alias fck already exists
[    0.078638]  omap2_mcspi.1: alias fck already exists
[    0.079352]  omap2_mcspi.2: alias fck already exists
[    0.110257] bio: create slab <bio-0> at 0
[    0.112549] SCSI subsystem initialized
[    0.114673] usbcore: registered new interface driver usbfs
[    0.115116] usbcore: registered new interface driver hub
[    0.115398] usbcore: registered new device driver usb
[    0.115825] registerd cppi-dma Intr @ IRQ 17
[    0.115844] Cppi41 Init Done Qmgr-base(d083a000) dma-base(d0838000)
[    0.115856] Cppi41 Init Done
[    0.117806] omap_i2c omap_i2c.1: bus 1 rev4.0 at 100 kHz
[    0.121099] Advanced Linux Sound Architecture Driver Version 1.0.24.
[    0.122604] Switching to clocksource gp timer
[    0.128714] Switched to NOHz mode on CPU #0
[    0.147961] musb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
[    0.148184] musb-hdrc musb-hdrc.0: dma type: dma-cppi41
[    0.149640] musb-hdrc musb-hdrc.0: USB OTG mode controller at d080a000 using DMA, IRQ 18
[    0.149855] musb-hdrc musb-hdrc.1: dma type: dma-cppi41
[    0.151151] musb-hdrc musb-hdrc.1: USB OTG mode controller at d080c800 using DMA, IRQ 19
[    0.151659] NET: Registered protocol family 2
[    0.151904] IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.152274] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.152499] TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
[    0.152728] TCP: Hash tables configured (established 8192 bind 8192)
[    0.152745] TCP reno registered
[    0.152764] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.152796] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.153089] NET: Registered protocol family 1
[    0.153769] RPC: Registered named UNIX socket transport module.
[    0.153793] RPC: Registered udp transport module.
[    0.153804] RPC: Registered tcp transport module.
[    0.153816] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.154092] NetWinder Floating Point Emulator V0.97 (double precision)
[    0.167605] VFS: Disk quotas dquot_6.5.2
[    0.167693] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    0.168407] msgmni has been set to 495
[    0.169412] io scheduler noop registered
[    0.169428] io scheduler deadline registered
[    0.169512] io scheduler cfq registered (default)
[    0.170656] Could not set LED4 to fully on
[    0.173080] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.175542] omap_uart.0: ttyO0 at MMIO 0x44e09000 (irq = 72) is a OMAP UART0
[    0.668999] console [ttyO0] enabled
[    0.673414] omap_uart.1: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1
[    0.681311] omap_uart.2: ttyO2 at MMIO 0x48024000 (irq = 74) is a OMAP UART2
[    0.689344] omap_uart.3: ttyO3 at MMIO 0x481a6000 (irq = 44) is a OMAP UART3
[    0.697310] omap_uart.4: ttyO4 at MMIO 0x481a8000 (irq = 45) is a OMAP UART4
[    0.705250] omap_uart.5: ttyO5 at MMIO 0x481aa000 (irq = 46) is a OMAP UART5
[    0.726113] brd: module loaded
[    0.736568] loop: module loaded
[    0.740097] i2c-core: driver [tsl2550] using legacy suspend method
[    0.746651] i2c-core: driver [tsl2550] using legacy resume method
[    0.753148] at24 1-0051: 32768 byte 24c256 EEPROM, writable, 64 bytes/write
[    0.812658] No daughter card found
[    0.816289] at24 1-0050: 32768 byte 24c256 EEPROM, writable, 64 bytes/write
[    0.831584] Board name: A335BONE
[    0.834997] Board version: 00A3
[    0.838295] The board is a AM335x Beaglebone.
[    0.843361]  omap_hsmmc.0: alias fck already exists
[    0.851729] mtdoops: mtd device (mtddev=name/number) must be supplied
[    0.858922] omap2-nand driver initializing
[    0.863622] OneNAND driver initializing
[    0.912675] davinci_mdio davinci_mdio.0: davinci mdio revision 1.6
[    0.919181] davinci_mdio davinci_mdio.0: detected phy mask fffffffe
[    0.926567] davinci_mdio.0: probed
[    0.930150] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver SMSC LAN8710/LAN8720
[    0.938999] CAN device driver interface
[    0.943056] CAN bus driver for Bosch D_CAN controller 1.0
[    0.949690] usbcore: registered new interface driver cdc_ether
[    0.956107] usbcore: registered new interface driver cdc_subset
[    0.962384] Initializing USB Mass Storage driver...
[    0.967794] usbcore: registered new interface driver usb-storage
[    0.974135] USB Mass Storage support registered.
[    0.979051] musb-hdrc musb-hdrc.1: MUSB HDRC host driver
[    0.984773] musb-hdrc musb-hdrc.1: new USB bus registered, assigned bus number 1
[    0.992721] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    0.999860] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    1.007479] usb usb1: Product: MUSB HDRC host driver
[    1.012711] usb usb1: Manufacturer: Linux 3.1.0-00010-g66bfbd2 musb-hcd
[    1.019664] usb usb1: SerialNumber: musb-hdrc.1
[    1.025620] hub 1-0:1.0: USB hub found
[    1.029587] hub 1-0:1.0: 1 port detected
[    1.035337] mousedev: PS/2 mouse device common for all mice
[    1.042763] omap_rtc omap_rtc: rtc core: registered omap_rtc as rtc0
[    1.049481] omap_rtc: already running
[    1.053818] i2c /dev entries driver
[    1.060556] OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
[    1.067621] cpuidle: using governor ladder
[    1.072584] cpuidle: using governor menu
[    1.081471] usbcore: registered new interface driver usbhid
[    1.087411] usbhid: USB HID core driver
[    1.092564] usbcore: registered new interface driver snd-usb-audio
[    1.101564] ALSA device list:
[    1.104747]   No soundcards found.
[    1.108320] oprofile: hardware counters not available
[    1.113644] oprofile: using timer interrupt.
[    1.118164] nf_conntrack version 0.5.0 (3961 buckets, 15844 max)
[    1.125088] ip_tables: (C) 2000-2006 Netfilter Core Team
[    1.130831] TCP cubic registered
[    1.134275] NET: Registered protocol family 17
[    1.138959] can: controller area network core (rev 20090105 abi 8)
[    1.145592] NET: Registered protocol family 29
[    1.150264] can: raw protocol (rev 20090105)
[    1.154770] can: broadcast manager protocol (rev 20090105 t)
[    1.160774] Registering the dns_resolver key type
[    1.165831] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
[    1.173916] ThumbEE CPU extension supported.
[    1.179327] _regulator_get: mpu.0 supply mpu not found, using dummy regulator
[    1.186978] omap2_set_init_voltage: Fail set voltage-dpll_mpu_ck(f=500000000 v=1100000)on vddmpu
[    1.196236] omap2_set_init_voltage: unable to set vdd_mpu
[    1.207896] Detected MACID=40:5f:c2:76:77:2b
[    1.215524] omap_rtc omap_rtc: setting system clock to 2000-01-01 00:12:14 UTC (946685534)
[    1.224900] Waiting for root device /dev/mmcblk0p2...
[    1.264022] mmc0: host does not support reading read-only switch. assuming write-enable.
[    1.274498] mmc0: new high speed SDHC card at address 1234
[    1.281098] mmcblk0: mmc0:1234 SA04G 3.70 GiB 
[    1.288802]  mmcblk0: p1 p2
[    2.954651] kjournald starting.  Commit interval 5 seconds
[    3.074509] EXT3-fs (mmcblk0p2): using internal journal
[    3.080015] EXT3-fs (mmcblk0p2): recovery complete
[    3.092581] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[    3.099909] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    3.109798] devtmpfs: mounted
[    3.113310] Freeing init memory: 228K

minibeagle login: root
login[541]: root login on 'ttyO0'
~ # uname -a
Linux minibeagle 3.1.0-00010-g66bfbd2 #3 Sun Apr 15 03:47:19 EDT 2012 armv7l GNU/Linux
~ # whoami
root
~ # ps
PID   USER     TIME   COMMAND
    1 root       0:00 init
    2 root       0:00 [kthreadd]
    3 root       0:00 [ksoftirqd/0]
    4 root       0:00 [kworker/0:0]
    5 root       0:00 [kworker/u:0]
    6 root       0:00 [rcu_kthread]
    7 root       0:00 [khelper]
    8 root       0:00 [kdevtmpfs]
    9 root       0:00 [netns]
   10 root       0:00 [kworker/u:1]
   42 root       0:00 [irq/72-serial i]
   44 root       0:00 [irq/73-serial i]
   46 root       0:00 [irq/74-serial i]
   48 root       0:00 [irq/44-serial i]
   50 root       0:00 [irq/45-serial i]
   52 root       0:00 [irq/46-serial i]
  214 root       0:00 [sync_supers]
  216 root       0:00 [bdi-default]
  218 root       0:00 [kblockd]
  226 root       0:00 [omap2_mcspi]
  237 root       0:00 [khubd]
  346 root       0:00 [musb-hdrc.0]
  349 root       0:00 [musb-hdrc.1]
  351 root       0:00 [rpciod]
  353 root       0:00 [kworker/0:1]
  361 root       0:00 [kswapd0]
  362 root       0:00 [fsnotify_mark]
  363 root       0:00 [nfsiod]
  364 root       0:00 [crypto]
  481 root       0:00 [kpsmoused]
  500 root       0:00 [kworker/u:2]
  533 root       0:00 [mmcqd/0]
  538 root       0:00 [kjournald]
  541 root       0:00 -sh
  543 root       0:00 [flush-179:0]
  545 root       0:00 ps
~ # 

Note

There are known issues with DNS functionality in statically-linked glibc programs (like busybox in this case), because libnss must be dynamically loaded. Building a uClibc toolchain and linking busybox against that would resolve this.

References

http://pakesson.se/b/2012/01/arch-linux-on-the-beaglebone/

http://dev.gentoo.org/~armin76/arm/beaglebone/install.xml

http://blog.galemin.com/2011/05/linux-kernel-2-6-39-codesourcery-2011-03-41-alignment-exception/

http://free-electrons.com/docs/elfs/

@capnmattttt

Hello.

I get too make errors both regarding the spl file being to big to fit in SRAM.

any insight?

Thanks,

Matt

@bradfa
bradfa commented Sep 27, 2012

@capnmatttt, try mainline u-boot, it works for beaglebone now

@bhaskerreddy

hello..
I have connected beaglebone to my Laptop through USB cable.
I tried all the above steps... and was successful till booting the kernel.. now i am at the login prompt of minibeagle As shown below....

[ 1.340415] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[ 1.347748] VFS: Mounted root (ext3 filesystem) readonly on device 179:2.
[ 1.356289] devtmpfs: mounted
[ 1.359776] Freeing init memory: 228K

minibeagle login:

But i am unable to give input from keyboard.
Help me...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment