Dave Dave - 1 month ago 18
Linux Question

Modifying the device tree for the Beaglebone Black

I have used Yocto to create a small linux image for the Beaglebone Black. I think I have most everything working like I want it, except I need access to UARTs 2 and 4. When I was using the standard Debian image, I did this with device tree overlays and capemgr. However, I found that the kernel built with Yocto doesn't have capemgr.

My options seem to be:

  1. get the kernel to build with capemgr, or

  2. modify the device tree file with the necessary changes.

Option 2 seems much easier.

The device tree overlays for the UARTs are here and here. I have gone about trying to include those in a couple ways.

  1. I decompiled the device tree blob I had been using and tried to
    include these files from there.

  2. I downloaded the full set of dts files and tried to include the
    UART device tree overlays in am335x-boneblack.dts.

Both approaches yield an error something like this:

Error: am335x-boneblack.dts:1.1-2 syntax error
FATAL ERROR: Unable to parse input tree

However, I noticed that I get a similar error when trying to compile am335x-boneblack.dts even without modifying it, so I'm likely not even doing that right. (Using the command dtc -I dts -O dtb -o result.dtb am335x-boneblack.dts)

Obviously I don't know what I'm doing. I suspect the device tree overlays have to be modified in some way to be used in the way I'm trying to use them. Or maybe I'm not doing the include right (just adding a #include to the top of the file).

Does anybody have any ideas what I might be doing wrong? Is what I'm trying to do even possible?


So I got this working by taking my device tree blob, decompiling it, and merging in sections from the device tree overlay files, and recompiling. I realized I needed uarts 1 and 2 instead of 2 and 4, so this is slightly different than my original problem.

To decompile the device tree blob:

dtc -I dtb -O dts -o am335x-boneblack.dts am335x-boneblack.dtb

I used the existing uart0 as an example to show me the right sections to work in.

I added a section for uart1 and uart2 in the pinmux section under the section for uart0. It now looks like this:

pinmux_uart0_pins {
    pinctrl-single,pins = <0x170 0x30 0x174 0x0>;
    linux,phandle = <0x27>;
    phandle = <0x27>;

bb_uart1_pins: pinmux_bb_uart1_pins {
    pinctrl-single,pins = <
        0x184 0x20 /* P9.24 uart1_txd.uart1_txd  OUTPUT  */
        0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd  INPUT  */

bb_uart2_pins: pinmux_bb_uart2_pins {
    pinctrl-single,pins = <
        0x150 0x21  /okay* spi0_sclk.uart2_rxd | MODE1 */
        0x154 0x01  /* spi0_d0.uart2_txd | MODE1 */

Then later, the serial sections need to be enabled and told what pins to use. I modified existing uart sections, and it now looks like this:

serial@44e09000 {
    compatible = "ti,omap3-uart";
    ti,hwmods = "uart1";
    clock-frequency = <0x2dc6c00>;
    reg = <0x44e09000 0x2000>;
    interrupts = <0x48>;
    status = "okay";
    dmas = <0x26 0x1a 0x26 0x1b>;
    dma-names = "tx", "rx";
    pinctrl-names = "default";
    pinctrl-0 = <0x27>;

serial@48022000 {
    compatible = "ti,omap3-uart";
    ti,hwmods = "uart2";
    clock-frequency = <0x2dc6c00>;
    reg = <0x48022000 0x2000>;
    interrupts = <0x49>;
    status = "okay";
    dmas = <0x26 0x1c 0x26 0x1d>;
    dma-names = "tx", "rx";
    pinctrl-names = "default";
    pinctrl-0 = <&bb_uart1_pins>;

serial@48024000 {
    compatible = "ti,omap3-uart";
    ti,hwmods = "uart3";
    clock-frequency = <0x2dc6c00>;
    reg = <0x48024000 0x2000>;
    interrupts = <0x4a>;
    status = "okay";
    dmas = <0x26 0x1e 0x26 0x1f>;
    dma-names = "tx", "rx";
    pinctrl-names = "default";
    pinctrl-0 = <&bb_uart2_pins>;

To recompile the device tree:

dtc -I dts -O dtb -o am335x-boneblack.dtb am335x-boneblack.dts

In short, I managed to get this working despite having little to no idea how device trees work.

I also needed to disable hdmi which I did by setting status equal to "disabled" in the hdmi section.