Difference between revisions of "Building for BeagleBone"

From eLinux.org
Jump to: navigation, search
(Root File System)
(Root File System)
Line 313: Line 313:
Finally you can flash the rootfs image to sdcard:
Finally you can flash the rootfs image to sdcard:
<syntaxhighlight lang="bash">$ sudo dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdc2</syntaxhighlight>
<syntaxhighlight lang="bash">$ sudo dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdc2</syntaxhighlight>
The end:
<syntaxhighlight lang="bash">
Welcome to Buildroot
beaglebone login:

Revision as of 15:24, 16 November 2014

Arm Compiler

Setting up cross-compile environment is the first and necessary step.

Linaro Toolchain

Linaro is an open organization focused on improving Linux on ARM. Toolchain Working Group provides the preferred community toolchain.

Arch Linux : gcc-linaro-arm-linux-gnueabihf

Distro provided

The easier way is install the default compiler provided by your distribution.

Ubuntu : gcc-arm-linux-gnueabi

Arch Linux : arm-linux-gnueabi-gcc

  • Tip: Do a alias in your environment, where N is the number of processors cores plus one:
$ alias armmake='make -jN ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- '


crosstool-NG aims at building toolchains. So, by this way you will build your own cross-compiler, but this requires that you choose an operation system and LibC. Therefore we will build a cross-compiler for Linux/gLibc.


Mainline U-boot

You can use the mainline u-boot for beaglebone.


$ git clone git://git.denx.de/u-boot.git


$ armmake distclean

Configure for BeagleBone:

$ armmake am335x_evm_config


$ armmake

Test your new U-Boot

You need a microSd card with 2Gb or more. In order to make U-Boot work you will need to create the first partion as FAT32 LBA, bootable, with something like 64 Megabytes.
This command wipes everything from your sdcard and creates that partition.

$ echo -e "o\nn\np\n1\n\n+64M\na\n1\nt\nc\nw\n" | sudo fdisk /dev/MYDISK ; sudo fdisk /dev/MYDISK -l

This comand should print something like:

Disk /dev/sdb: 7948 MB, 7948206080 bytes
16 heads, 4 sectors/track, 242560 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1c524301
    Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        2048      133119       65536    c  W95 FAT32 (LBA)

The U-Boot compilation generated two files, MLO and uboot.img. Mount the partition that you just created and copy FIRST the MLO file to partition. Then copy the u-boot.img.

$ sudo mount /dev/MYDISK /mnt
$ sudo cp MLO /mnt
$ sudo cp u-boot.img
$ sudo sync
$ sudo umount  /mnt

Now with that sdcard in BeagleBone the output from serial should be:

U-Boot SPL 2014.07-rc4-00264-g23f23f2-dirty (Jul 05 2014 - 21:56:58)
reading u-boot.img
reading u-boot.img

U-Boot 2014.07-rc4-00264-g23f23f2-dirty (Jul 05 2014 - 21:56:58)

I2C:   ready
DRAM:  512 MiB
NAND:  0 MiB
*** Warning - readenv() failed, using default environment

Net:   <ethaddr> not set. Validating first E-fuse MAC
cpsw, usb_ether
Hit any key to stop autoboot:  0 
switch to partitions #0, OK
mmc0 is current device
SD/MMC found on device 0
reading uEnv.txt
** Unable to read file uEnv.txt **
** Invalid partition 2 **
switch to partitions #0, OK
mmc1(part 0) is current device
SD/MMC found on device 1
reading uEnv.txt
26 bytes read in 3 ms (7.8 KiB/s)
Loaded environment from uEnv.txt
Importing environment from mmc ...
** File not found /boot/zImage **
Booting from nand ...

no devices available

no devices available
Bad Linux ARM zImage magic!

If you don't see this output, but sees a bunch of "CCCCC", this could mean that the first partition doesn't have the boot flag set.

There are two problems in this output. First, you don't have a uEnv.txt, which configure the U-Boot and secondly you don't have a linux image. But first check what is the default environment from Beaglebone. Boot the u-boot and do a pr command, the output should be like this:

U-Boot# pr
bootargs=console=ttyO0,115200n8 quiet drm.debug=7 root=ubi0:rootfs rw ubi.mtd=7,2048 rootfstype=ubifs rootwait=1
bootcmd=run findfdt; run mmcboot;setenv mmcdev 1; setenv bootpart 1:2; run mmcboot;run nandboot;

dfu_alt_info_emmc=rawemmc mmc 0 3751936
dfu_alt_info_mmc=boot part 0 1;rootfs part 0 2;MLO fat 0 1;MLO.raw mmc 0x100 0x100;u-boot.img.raw mmc 0x300 0x400;spl-os-args.raw mmc 0x80 0x80;spl-os-image.raw mmc 0x900 0x2000;spl-os-args fat 0 1;spl-os-image fat 0 1;u-boot.img fat 0 1;uEnv.txt fat 0 1
dfu_alt_info_nand=SPL part 0 1;SPL.backup1 part 0 2;SPL.backup2 part 0 3;SPL.backup3 part 0 4;u-boot part 0 5;u-boot-spl-os part 0 6;kernel part 0 8;rootfs part 0 9
dfu_alt_info_ram=kernel ram 0x80200000 0xD80000;fdt ram 0x80F80000 0x80000;ramdisk ram 0x81000000 0x4000000
findfdt=if test $board_name = A335BONE; then setenv fdtfile am335x-bone.dtb; fi; if test $board_name = A335BNLT; then setenv fdtfile am335x-boneblack.dtb; fi; if test $board_name = A33515BB; then setenv fdtfile am335x-evm.dtb; fi; if test $board_name = A335X_SK; then se
importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize
loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
loadramdisk=load mmc ${mmcdev} ${rdaddr} ramdisk.gz
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}
mmcboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootenv; then echo Loaded environment from ${bootenv};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;if run loadimage; then run mmcloa;
mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcroot=/dev/mmcblk0p2 ro
mmcrootfstype=ext4 rootwait
nandargs=setenv bootargs console=${console} ${optargs} root=${nandroot} rootfstype=${nandrootfstype}
nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} u-boot-spl-os; nand read ${loadaddr} kernel; bootz ${loadaddr} - ${fdtaddr}
nandroot=ubi0:rootfs rw ubi.mtd=7,2048
nandrootfstype=ubifs rootwait=1
netargs=setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=dhcp
netboot=echo Booting from network ...; setenv autoload no; dhcp; tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} ${fdtfile}; run netargs; bootz ${loadaddr} - ${fdtaddr}
optargs=quiet drm.debug=7
ramargs=setenv bootargs console=${console} ${optargs} root=${ramroot} rootfstype=${ramrootfstype}
ramboot=echo Booting from ramdisk ...; run ramargs; bootz ${loadaddr} ${rdaddr} ${fdtaddr}
ramroot=/dev/ram0 rw
spiargs=setenv bootargs console=${console} ${optargs} root=${spiroot} rootfstype=${spirootfstype}
spiboot=echo Booting from spi ...; run spiargs; sf probe ${spibusno}:0; sf read ${loadaddr} ${spisrcaddr} ${spiimgsize}; bootz ${loadaddr}
spiroot=/dev/mtdblock4 rw
ver=U-Boot 2014.07-rc4-00264-g23f23f2-dirty (Jul 05 2014 - 21:56:58)

Some of these configs comes from "u-boot/include/configs/am335x_evm.h". These configs can be changed, but u-boot needs to be recompiled in order to take effect. But, the most common way is change configs in a file called uEnv.txt. This file is read in boot time, and override any configuration pre-defined in beaglebone.

This is the basic uEnv.txt that your boards needs in order to boot your kernel. Create and put this file uEnv.txt in your boot partition.

loadfdt=fatload mmc 0:1 ${fdtaddr} ${fdtfile}
loaduimage=fatload mmc 0:1 ${loadaddr} ${bootfile}
uenvcmd=mmc rescan; run loaduimage; run loadfdt; run fdtboot
fdtboot=run mmc_args; run mmcargs; bootz ${loadaddr} - ${fdtaddr}
mmc_args=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}


Mainline Kernel

You can use the mainline linux for beaglebone.


$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


$ armmake distclean

Configure for BeagleBone:

$ armmake multi_v7_defconfig

Check if two remaining configs are set:

│ Symbol: MFD_TPS65217 [=n]
│ Type  : tristate
│ Prompt: TI TPS65217 Power Management / White LED chips
│   Location:
│     -> Device Drivers
│ (1)   -> Multifunction device drivers
│   Defined at drivers/mfd/Kconfig:877
│   Depends on: HAS_IOMEM [=y] && I2C [=y]
│   Selects: MFD_CORE [=y] && REGMAP_I2C [=y]

│ Symbol: REGULATOR_TPS65217 [=n]
│ Type  : tristate
│ Prompt: TI TPS65217 Power regulators
│   Location:
│     -> Device Drivers
│ (1)   -> Voltage and Current Regulator Support (REGULATOR [=y])
│   Defined at drivers/regulator/Kconfig:554
│   Depends on: REGULATOR [=y] && MFD_TPS65217 [=y]


$ armmake

After build, there are two important files. Linux kernel at arch/arm/boot/zImage and Device Tree Blob arch/arm/boot/dts/am335x-boneblack.dtb or arch/arm/boot/dts/am335x-bone.dtb (for white). So copy that to memory card.

$ sudo cp arch/arm/boot/zImage /mnt
$ sudo cp arch/arm/boot/dts/am335x-boneblack.dtb /mnt

Test your new Kernel

Now your kernel is able to boot. But finish this way:

[1.507789] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[1.516423] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[1.525636] devtmpfs: error mounting -2
[1.530467] Freeing unused kernel memory: 728K (c0b90000 - c0c46000)
[1.537240] Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
[1.551022] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.18.0-rc3-00134-gfe606df #1
[1.559008] [<c02162c0>] (unwind_backtrace) from [<c0211cc4>] (show_stack+0x10/0x14)
[1.567139] [<c0211cc4>] (show_stack) from [<c0896d64>] (dump_stack+0x8c/0x9c)
[1.574716] [<c0896d64>] (dump_stack) from [<c08964d0>] (panic+0xa0/0x218)
[1.581929] [<c08964d0>] (panic) from [<c089488c>] (cpu_die+0x0/0x80)
[1.588682] [<c089488c>] (cpu_die) from [<00000000>] ( (null))
[1.594897] ---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

This means that your board doesn't have a root file system.

Root File System

To create a root file system we need BuildRoot.

Clone the source:

$ git clone git://git.buildroot.net/buildroot

Configure buildroot for Beaglebone:

$ make beaglebone_defconfig

Let's do some tweaking.

$ make menuconfig
  • Uncheck Kernel, you just built yours.
  • Ucheck bootloaders --> u-boot, you just built yours.
  • Target options --->:
    • Floating point strategy (NEON)
    • ARM instruction set (Thumb2)
  • Toolchain --->
    • Toolchain type (External toolchain)
    • Toolchain (Linaro ARM 2014.08)
    • Toolchain origin (Pre-installed toolchain)
    • (/opt/gcc-linaro-arm-linux-gnueabihf) Toolchain path
  • Target packages --->
    • Networking applications --->
      • [*] dhcpcd
      • [*] openssh
    • Text editors and viewers --->
      • [*] nano
  • Filesystem images --->
    • ext2/3/4 variant (ext4) --->
      • (X) ext4

Now save and exit.

Build the root file system:

$ make

Finally you can flash the rootfs image to sdcard:

$ sudo dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdc2

The end:

Welcome to Buildroot
beaglebone login: