jampy81
Posts: 1
Joined: Mon Jan 25, 2016 10:45 pm

device tree overlays and U-Boot

Mon Jan 25, 2016 10:59 pm

AFAIK U-Boot does not support device tree overlays.

So, is it possible to merge the main device tree dtb and desired overlays to a single .dtb so that U-Boot can use it? If yes, how is it done?

I'm trying to get a I2C RTC working and need to boot via U-Boot.

see also my related Stackexchange question: http://unix.stackexchange.com/q/256264

Thanks!

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Tue Jan 26, 2016 8:40 am

I have written a utility that can do that - I used it to test the overlay mechanism during its development. It needs a bit of polishing before the source code is released, time I don't have at the moment, but I'm happy to make a Pi binary available in the meantime if that helps.

chaosjug
Posts: 18
Joined: Wed Nov 05, 2014 8:24 pm

Re: device tree overlays and U-Boot

Wed Jan 27, 2016 7:33 pm

If you just want to enable I2C RTC you could also just write a small dts-file and compile it:

Code: Select all

#include "bcm2708-rpi-b-plus.dts"

&i2c1 {
	status = "okay";
	pcf8563: [email protected] {
		compatible = "nxp,pcf8563";
		reg = <0x51>;
		status = "okay";
	};
};
You'll obviously have to pick the correct RTC part from i2c-rtc-overlay.dts (and change disable to okay).
And at least I found no way to use the i2c_arm alias, so you might need to change i2c0 to i2c1 depending on your device.

Edit: As PhilE noted below, i2c1 is the right i2c for a b+
Last edited by chaosjug on Sat Jan 30, 2016 3:09 pm, edited 1 time in total.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Wed Jan 27, 2016 8:12 pm

The aliases are created by the firmware, which is too late in this case. Only early Model Bs used i2c0 for user I2C, so your example using the b-plus dts should definitely say &i2c1.

samskiter
Posts: 24
Joined: Wed Aug 12, 2015 6:18 pm

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 10:36 am

While u-boot doesn't directly support overlays - start.elf still does and you can have u-boot effectively 'pass through' the flattened device tree that start.elf creates. I've just managed to get this working (last night) I have a little detail here that you might find useful: viewtopic.php?f=29&t=137599 and perhaps a blog post on the way once I get all my ducks in a row.

This was also pretty useful: http://dius.com.au/2015/08/19/raspberry-pi-uboot/

I would appreciate if anyone could help me work out why start.elf was loading the FDT to somewhere other that 0x100 (in my case to: 0x17fed200)

Thanks,

Sam

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 10:45 am

The slot at 0x100 is limited to just under 16KB (0x3f00), and there have been situations where the fully resolved DTB exceeds that. I modified the loader to remove that limit by putting the DTB at the end of memory, in the same way that the initramfs followkernel option does. You can force a specific location using the device_tree_address config.txt setting.

samskiter
Posts: 24
Joined: Wed Aug 12, 2015 6:18 pm

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 11:07 am

Thanks for your reply PhilE - I've since been using device_tree_address to correct the location...

I'm still a bit confused though because a) my resolved device tree is reported as "size 2d35" which is under the 16KB limit and b) inspecting the memory at 0x17fed200 shows as completely empty - so my device tree seems to vanish...

edit: re: a) I just reread your post and realised you mean that the device tree is now ALWAYS placed at the end of memory, regardless of size.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 11:24 am

The code to load the DTB high is not conditional on its size. Making it so is possible, but it would mean that some problems would only be detected when the DTB reaches the threshold, and I much prefer systems to fail consistently.

samskiter
Posts: 24
Joined: Wed Aug 12, 2015 6:18 pm

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 1:16 pm

Thanks again, inspecting 0x000, I see that the device tree should be loaded at 0x17fed200 but that appears to be empty. Seems that U-boot is being relocated pretty close to that (0x17F4B000) so potentially stomping over the device tree.

So that I can adjust U-boot, could you give me any more information about the rules used to locate the device tree? will it always be at 0x17fed200 or is it size dependent??

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 1:58 pm

The DTB start address is size dependent. The aim is to copy the DTB as high as possible. Once the kernel starts it will "unflatten" the DTB into allocated memory and then re-use the space.
1
ARM memory starts at 0 in the VPU physical address space. The GPU memory sits at the top. This is how it works:

Code: Select all

ARMMEM_END = MEM_SIZE - GPU_MEM

// Leave 64KB for GRUB
free_end = ALIGN_DOWN(ARMMEM_END - 0x10000, 0x1000)

// Leave space for initramfs, if there is one
free_end = ALIGN_DOWN(free_end - initramfs_size, 0x1000)

device_tree_address = ALIGN_DOWN(free_end - device_tree_size, 0x100)
Don't forget that the address of the DTB is passed in register r2 to the kernel/U-boot entry point, with r0 holding 0 and r1 being 3138 (the BCM2708 machine id).

swarren
Posts: 45
Joined: Tue Mar 01, 2016 5:56 am

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 8:47 pm

Has this feature been tested on a system with 1GB RAM and a config.txt setting the VC memory size as small as possible (e.g. 32M) and no initrd?

The Linux kernel splits RAM into two sections; lowmem that is 1:1 mapped in kernel VA space and highmem that is not. The DT must reside in lowmem, since the early kernel boot code can only access lowmem, yet needs to access the DT. On a system with only 512M or less, everything is lowmem. In a 1GB system, a good chunk of RAM is highmem so can't contain the DT.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Thu Mar 03, 2016 9:55 pm

That would be true on a system with a 1/3 kernel/user split, but we use a 2/2 split so it's all low mem.

TheDJVG
Posts: 4
Joined: Thu Mar 03, 2016 7:55 pm

Re: device tree overlays and U-Boot

Fri Mar 11, 2016 9:09 pm

Has anyone found a way to view the u-boot output and kernel boot output over pins 14/15? I'm able to start u-boot without any problems but I can't see the kernel booting process over serial.

I've tried merging the device tree files (bcm2710-rpi-3-b.dts and pi3-disable-bt-overlay.dts) and started the kernel with "console=serial0 or serial1 or ttyAMA0 or ttyS0" but no luck. I might be doing something wrong but I don't know what.

swarren
Posts: 45
Joined: Tue Mar 01, 2016 5:56 am

Re: device tree overlays and U-Boot

Thu Apr 07, 2016 4:58 am

PhilE wrote:That would be true on a system with a 1/3 kernel/user split, but we use a 2/2 split so it's all low mem.
That's presumably a configuration quirk specific to the Pi Foundation's kernel, and is not true for mainline Linux?

Sorry for the late reply; I guess I wasn't subscribed to this thread.

Synoia
Posts: 7
Joined: Mon Jun 06, 2016 9:16 pm

Re: device tree overlays and U-Boot

Mon Sep 12, 2016 8:46 pm

How would u-boot discover the length of the device tree?

Synoia
Posts: 7
Joined: Mon Jun 06, 2016 9:16 pm

Re: device tree overlays and U-Boot

Mon Sep 12, 2016 8:48 pm

TheDJVG wrote:Has anyone found a way to view the u-boot output and kernel boot output over pins 14/15? I'm able to start u-boot without any problems but I can't see the kernel booting process over serial.

I've tried merging the device tree files (bcm2710-rpi-3-b.dts and pi3-disable-bt-overlay.dts) and started the kernel with "console=serial0 or serial1 or ttyAMA0 or ttyS0" but no luck. I might be doing something wrong but I don't know what.
You need one of the USB to R Pi pin-to-serial devices. The PI pin voltage swing is too low for a serial port.

Synoia
Posts: 7
Joined: Mon Jun 06, 2016 9:16 pm

Re: device tree overlays and U-Boot

Mon Sep 12, 2016 8:49 pm

PhilE wrote:The DTB start address is size dependent. The aim is to copy the DTB as high as possible. Once the kernel starts it will "unflatten" the DTB into allocated memory and then re-use the space.
1
ARM memory starts at 0 in the VPU physical address space. The GPU memory sits at the top. This is how it works:

Code: Select all

ARMMEM_END = MEM_SIZE - GPU_MEM

// Leave 64KB for GRUB
free_end = ALIGN_DOWN(ARMMEM_END - 0x10000, 0x1000)

// Leave space for initramfs, if there is one
free_end = ALIGN_DOWN(free_end - initramfs_size, 0x1000)

device_tree_address = ALIGN_DOWN(free_end - device_tree_size, 0x100)
Don't forget that the address of the DTB is passed in register r2 to the kernel/U-boot entry point, with r0 holding 0 and r1 being 3138 (the BCM2708 machine id).

How would u-boot find the length of the DTB?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Mon Sep 12, 2016 8:53 pm

The Flattened Device Tree format, which is what is generated by dtc and stored in DTB files and overlays, starts with a header including the length:

Code: Select all

struct boot_param_header {
        u32     magic;                  /* magic word 0xd00dfeed */
        u32     totalsize;              /* total size of DT block */
        u32     off_dt_struct;          /* offset to structure */
        u32     off_dt_strings;         /* offset to strings */
        u32     off_mem_rsvmap;         /* offset to memory reserve map
                                           */
        u32     version;                /* format version */
        u32     last_comp_version;      /* last compatible version */

        /* version 2 fields below */
        u32     boot_cpuid_phys;        /* Which physical CPU id we're
                                           booting on */
        /* version 3 fields below */
        u32     size_dt_strings;        /* size of the strings block */

        /* version 17 fields below */
        u32	size_dt_struct;		/* size of the DT structure block */
};
i.e. you just need to check the magic, then read the second word to get the length.

Synoia
Posts: 7
Joined: Mon Jun 06, 2016 9:16 pm

Re: device tree overlays and U-Boot

Mon Sep 19, 2016 6:14 pm

PhilE wrote:The Flattened Device Tree format, which is what is generated by dtc and stored in DTB files and overlays, starts with a header including the length:

Code: Select all

struct boot_param_header {
        u32     magic;                  /* magic word 0xd00dfeed */
        u32     totalsize;              /* total size of DT block */
        u32     off_dt_struct;          /* offset to structure */
        u32     off_dt_strings;         /* offset to strings */
        u32     off_mem_rsvmap;         /* offset to memory reserve map
                                           */
        u32     version;                /* format version */
        u32     last_comp_version;      /* last compatible version */

        /* version 2 fields below */
        u32     boot_cpuid_phys;        /* Which physical CPU id we're
                                           booting on */
        /* version 3 fields below */
        u32     size_dt_strings;        /* size of the strings block */

        /* version 17 fields below */
        u32	size_dt_struct;		/* size of the DT structure block */
};
i.e. you just need to check the magic, then read the second word to get the length.
Can you post the definitions of the structures referenced in this header, or a github (or similar) repository?

Thx

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Mon Sep 19, 2016 8:36 pm


ahmedawad
Posts: 42
Joined: Mon Apr 18, 2016 11:44 am
Location: Bremen, DE

Re: device tree overlays and U-Boot

Wed May 24, 2017 2:35 pm

Please can you summarize how to get U-boot to work correctly fine with RPI3, I mean by correctly is " Having the device tree in the config.txt read by U-boot" ?

For a noob like me, I did the following steps:

1- I downloaded the last Jessie image.
2- git clone -b v2017.05-rc1 git://git.denx.de/u-boot.git
3- cd u-boot , make rpi_3_32b_defconfig , make -j4
4- I get the u-boot.bin , then copy it to /boot
5- add kernel=u-boot.bin to config.txt
6- prepare boot.txt with the following:

Code: Select all

fatload mmc 0:1 ${kernel_addr_r} kernel7.img
fatload mmc 0:1 ${fdt_addr_r} bcm2710-rpi-3-b.dtb
setenv bootargs earlyprintk dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk0p3 rootfstype=ext4 rootwait
bootz ${kernel_addr_r} - ${fdt_addr_r}
7- execute

Code: Select all

mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n "rpi3 boot script" -d boot.txt boot.scr
8- cp boot.scr /boot
when reboot, the image and kernel starts, but none of the dtoverlay in my config.txt get read by the kernel, even the hdmi resolution is not set correctly.

Please help and thanks in advance.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Wed May 24, 2017 2:48 pm

The way I would expect it to work now is using a feature of the new stub files to store the DTB address where u-boot can read it; that feature was developed in a collaboration with swarren. Having said that, I've not used u-boot and we don't provide support for it.

swarren
Posts: 45
Joined: Tue Mar 01, 2016 5:56 am

Re: device tree overlays and U-Boot

Thu May 25, 2017 1:41 pm

@ahmedawad,

U-Boot sets environment variable $fdt_addr to the address of the DTB provided by the firmware. If you want to pass that to the kernel, you need to (a) pass that value to bootz rather than the address of any DTB that U-Boot loaded, (b) not load a DTB from U-Boot. For example, your boot script might be (untested):

Code: Select all

fatload mmc 0:1 ${kernel_addr_r} kernel7.img
setenv bootargs earlyprintk dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk0p3 rootfstype=ext4 rootwait
bootz ${kernel_addr_r} - ${fdt_addr}
Reference: http://git.denx.de/?p=u-boot.git;a=blob ... aster#l257

One other comment: With the boot script you described, U-Boot isn't really doing anything useful; it's just passing through the existing DTB and loading a kernel that the firmware could load directly itself. All this can be configured from config.txt more easily than via a U-Boot script (i.e. just editing the .txt file rather than having to run mkimage on an edited script file). It would be simplest not to use U-Boot in this case. Of course, perhaps you're just working on getting baseline U-Boot functionality working so you can later make use of its other features; if so, ignore this paragraph.

ahmedawad
Posts: 42
Joined: Mon Apr 18, 2016 11:44 am
Location: Bremen, DE

Re: device tree overlays and U-Boot

Fri May 26, 2017 7:39 am

swarren wrote:@ahmedawad,
For example, your boot script might be (untested):

Code: Select all

fatload mmc 0:1 ${kernel_addr_r} kernel7.img
setenv bootargs earlyprintk dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk0p3 rootfstype=ext4 rootwait
bootz ${kernel_addr_r} - ${fdt_addr}
Reference: http://git.denx.de/?p=u-boot.git;a=blob ... aster#l257
Thanks @PhilE and @swarren for your replies. However, I tried your script and not to load bcm2710-rpi-3-b.dtb in boot.scr but when Uboot starts, still the dtoverlays are not detected. In /u-boot/include/configs/rpi.h --> the fdt_addr_r is set to 0x100. I am confused, could it be memory overlap?. I am trying to inspect U-boot just it would be useful as many applications can use it.

Many thanks in advance!

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2444
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: device tree overlays and U-Boot

Fri May 26, 2017 8:00 am

Reading the link swarren sent, u-boot sets "fdt_addr" to the DT address passed to the kernel. "fdt_addr_r" is the old constant value of 0x100, which is where the kernel used to put its ATAGs or DTB. Unfortunately the gap from 0x100 to where the kernel starts is only 32KB, and the decompressor seems to use memory starting at 0x4000, leaving only 16KB for the DTB - not enough in many cases, so the RPi firmware switched to loading the DTB high above the kernel and the u-boot startup code now stores the value passed to the "kernel" in the variable "fdt_addr".

Does u-boot let you print output from your script? I would suggest displaying "fdt_addr" and "fdt_addr_r" to see if they are sensible.

Return to “Device Tree”