Skip to content

Instantly share code, notes, and snippets.

@vsergeev
Created April 15, 2012 09:45
Show Gist options
  • Star 50 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save vsergeev/2391575 to your computer and use it in GitHub Desktop.
Save vsergeev/2391575 to your computer and use it in GitHub Desktop.
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
Copy link

Hello.

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

any insight?

Thanks,

Matt

@bradfa
Copy link

bradfa commented Sep 27, 2012

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

@bhaskerreddy
Copy link

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...

@Unturned3
Copy link

Hi bhaskerreddy,
Did you connect to your board using your laptop through a USB-serial adapter? Try connecting a USB keyboard directly to the board. Maybe it's because of a missing kernel driver for the USB cable to your laptop that's causing the problem.

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