Adventures in devicetree land

| tagged with
  • devicetree
  • kernel
  • beagleboard
  • linaro

Adventures in devicetree land

Building kernel with following script,

#!/bin/bash

set -o errexit

makeopts="ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- $MAKEOPTS"

make $makeopts all
make $makeopts uImage
make $makeopts modules
cp arch/arm/boot/uImage /media/boot/uImage
sudo make $makeopts modules_install MOD_INSTALL_PATH=/media/rootfs
echo "Syncing..."
sync
echo "Done."
exit 0

Beagleboard thinks it only has 16M of memory with both v3.0 and v2.6.39 kernels,

[    0.000000] Linux version 2.6.39 (ben@ben-laptop) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu3) ) #3 SMP Thu Aug 18 11:18:57 EDT 2011
[    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: OMAP3 Beagle Board
.
.
.
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Memory: 16MB = 16MB total
[    0.000000] Memory: 5116k/5116k available, 11268k 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     : 0xffc00000 - 0xffe00000   (   2 MB)
[    0.000000]     vmalloc : 0xc1800000 - 0xf8000000   ( 872 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc1000000   (  16 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .init : 0xc0008000 - 0xc0053000   ( 300 kB)
[    0.000000]       .text : 0xc0053000 - 0xc060ad50   (5856 kB)
[    0.000000]       .data : 0xc060c000 - 0xc068faa8   ( 527 kB)

Resulting in OOM pretty early in boot. Yet bootloader realizes correct amount,

OMAP3630/3730-GP ES2.0, CPU-OPP2, L3-165MHz, Max CPU Clock 1 Ghz
OMAP3 Beagle board + LPDDR/NAND
I2C:   ready
DRAM:  512 MiB
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0

Passing mem=512M to kernel doesn’t help.

Perhaps problem is in devicetree. Downloaded dtc from git://git.jdl.com/software/dtc.git since version in kernel tree (in scripts/dtc) doesn’t build. Decoded devicetree,

[1125 ben@ben-laptop dtc(master)] $ ./dtc -I dtb -O dts /media/boot/board.dtb 
DTC: dtb->dts  on file "/media/boot/board.dtb"
/dts-v1/;

/ {
        #address-cells = <0x1>;
        #size-cells = <0x1>;
        model = "TI OMAP3 BeagleBoard";
        compatible = "ti,omap3-beagle";

        chosen {
        };

        aliases {
        };

        memory {
                device_type = "memory";
                reg = <0x0 0x0>;
        };
};

Hmm, not sure what this means. Where is actual devicetree source for the beagleboard? Googling turns up many recent mentions https://patchwork.kernel.org/patch/932472/ of arch/arm/boot/dts in kernel tree, but this does not exist in v2.6.39 nor v3.0. It seems like the devicetree branch of a random repository has this directory with an omap3-beagle.dts. It includes skeleton.dtsi which claims that the bootloader will populate the memory node,

/*
    * Skeleton device tree; the bare minimum needed to boot; just include and
    * add a compatible value.  The bootloader will typically populate the memory
    * node.
    */

/ {
        #address-cells = <1>;
        #size-cells = <1>;
        chosen { };
        aliases { };
        memory { device_type = "memory"; reg = <0 0>; };
};

Perhaps I built a kernel without devicetree support. Judging by the Linaro devicetree HOWTO(https://wiki.linaro.org/Resources/HowTo/KernelDeviceTree) v2.6.39 doesn’t support devicetrees (CONFIG_USE_OF doesn’t exist). Checkout v3.0. Ahh, I saved my original v3.0 .config and indeed CONFIG_USE_OF isn’t set. Damn. I wonder how the bootloader passed the memory amount to the kernel prior to devicetrees. Apparently this mechanism doesn’t work if the bootloader is configured to use devicetrees.

After enabling CONFIG_USE_OF the machine hangs after “Uncompressing Linux… done, booting the kernel.” Bah.

Ahhh, after chatting with landley in Freenode’s #edev I realized that CONFIG_EARLY_PRINTK isn’t enabled. It’s hidden behind CONFIG_LL_DEBUG in the Kernel Hacking category.

Bingo! I have an error message,

Uncompressing Linux... done, booting the kernel.

Error: unrecognized/unsupported device tree compatible list:
[ 'ti,omap3-beagle' ]

Available machine support:

ID (hex)	NAME
000001c4	Generic OMAP24xx
000001fe	OMAP2420 H4 board
00000384	OMAP2430 sdp2430 board
00000397	OMAP24xx Apollon
0000060a	OMAP3 Beagle Board
0000091a	OMAP3 Devkit8000
00000667	OMAP LDP board
000006ed	OMAP Logic 3530 LV SOM board
00000882	Logic OMAP3 Torpedo board
00000706	Gumstix Overo
000005ff	OMAP3 EVM
000006e1	Pandora Handheld Console
00000472	OMAP3430 3430SDP board
000006bf	Nokia N810 WiMAX
0000060c	Nokia N810
000004f7	Nokia N800
00000c94	Nokia RM-680 board
000007a3	Nokia RX-51 board
000009a0	OMAP Zoom3 board
000007af	OMAP Zoom2 board
000009a1	OMAP 3630SDP board
00000925	Compulab CM-T35
00000abe	Compulab CM-T3517
00000a9d	IGEP OMAP3 module
00000928	IGEP v2 board
00000959	OMAP3 touchbook Board
00000870	OMAP4430 4430SDP board
00000ae7	OMAP4 Panda board
00000898	OMAP3517/AM3517 EVM
00000aa2	OMAP3 STALKER
00000af0	ti8168evm

Please check your kernel config and/or bootloader.

Hmm, now what does that mean?

It seems that the machine_desc (defined in the board file) should provide a dt_compat list which defines the devicetree compatibility tags which that board file can boot. This isn’t defined in v3.0’s board-omap3beagle.c. Looking at the Linaro tree it appears these were added in 9d51c816. Cherry-picked.

It Works!