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 (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!