Building for BeagleBone
Contents
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
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.
U-Boot
Mainline U-boot
You can use the mainline u-boot for beaglebone.
Get:
$ git clone git://git.denx.de/u-boot.git
Clean:
$ armmake distclean
Configure for BeagleBone:
$ armmake am335x_evm_config
Build:
$ 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 MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 *** 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! U-Boot#
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
arch=arm
baudrate=115200
board=am335x
board_name=A335BNLT
board_rev=0A5A
boot_fdt=try
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;
bootcount=1
bootdelay=1
bootdir=/boot
bootenv=uEnv.txt
bootfile=zImage
bootm_size=0x10000000
bootpart=1:2
console=ttyO0,115200n8
cpu=armv7
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
eth1addr=c8:a0:30:a6:2c:6f
ethact=cpsw
ethaddr=c8:a0:30:a6:2c:6d
fdt_addr_r=0x88000000
fdtaddr=0x88000000
fdtfile=am335x-boneblack.dtb
filesize=1a
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
kernel_addr_r=0x82000000
loadaddr=0x82000000
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;
mmcdev=1
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
mtdids=nand0=omap2-nand.0
mtdparts=mtdparts=omap2-nand.0:128k(SPL),128k(SPL.backup1),128k(SPL.backup2),128k(SPL.backup3),1792k(u-boot),128k(u-boot-spl-os),128k(u-boot-env),5m(kernel),-(rootfs)
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}
nfsopts=nolock
optargs=quiet drm.debug=7
partitions=uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
ramargs=setenv bootargs console=${console} ${optargs} root=${ramroot} rootfstype=${ramrootfstype}
ramboot=echo Booting from ramdisk ...; run ramargs; bootz ${loadaddr} ${rdaddr} ${fdtaddr}
ramdisk_addr_r=0x88080000
ramroot=/dev/ram0 rw
ramrootfstype=ext2
rdaddr=0x88080000
rootpath=/export/rootfs
soc=am33xx
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}
spibusno=0
spiimgsize=0x362000
spiroot=/dev/mtdblock4 rw
spirootfstype=jffs2
spisrcaddr=0xe0000
static_ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off
stderr=serial
stdin=serial
stdout=serial
usbnet_devaddr=c8:a0:30:a6:2c:6f
vendor=ti
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.
Kernel
Mainline Kernel
You can use the mainline linux for beaglebone.
Get:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Clean:
$ 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]
Build:
$ 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