2

We run a customized version of U-Boot on an ARM-based embedded system and would like to load Linux 4.3 with a device tree blob. The system features 1GB of RAM of which the top 128MB are reserved for persistent storage. I use tftp to copy the kernel and the DTB into certain memory locations (kernel: 0x02000000, DTB: 0x02400000), and for now I’d like to ignore the initramfs. So I call bootm 0x2000000 - 0x2400000.

What happens is that the DTB is relocated to the very end of the available U-Boot memory, to 0x37b60000 (virtual: 0xf7b60000). Linux fails to boot because it cannot access that address. It seems to be an issue about highmem/lowmem that I don’t understand, and lowmem ends at 760MB (virtual 0xef800000). Isn’t highmem supposed to be mapped dynamically when needed? (CONFIG_HIGHMEM is set.)

What is the clean and proper way to solve this – cause U-Boot to use a lower location (how?) or change the Linux config to be able to access high memory (how?)?

Note: using fdt_high=0xffffffff (and initrd_high=0xffffffff) Linux boots just fine as relocation is suppressed.

U-Boot with debug information:

DRAM:  Monitor len: 00044358
Ram size: 40000000
Ram top: 40000000
Reserving 131072k for protected RAM at 38000000
TLB table from 37ff0000 to 37ff4000
Reserving 272k for U-Boot at: 37fab000
Reserving 4352k for malloc() at: 37b6b000
Reserving 80 Bytes for Board Info at: 37b6afb0
Reserving 160 Bytes for Global Data at: 37b6af10

RAM Configuration:
Bank #0: 00000000 1 GiB

DRAM:  1 GiB
New Stack Pointer is: 37b6aef0
Relocation Offset is: 33fab000
Relocating to 37fab000, new gd at 37b6af10, sp at 37b6aef0

[…]

*  fdt: cmdline image address = 0x02400000
## Checking for 'FDT'/'FDT Image' at 02400000
*  fdt: raw FDT blob
## Flattened Device Tree blob at 02400000
   Booting using the fdt blob at 0x2400000
   of_flat_tree at 0x02400000 size 0x0000493c
   Loading Multi-File Image ... OK
## device tree at 02400000 ... 0240493b (len=31036 [0x793C])
   Loading Device Tree to 37b60000, end 37b6793b ... OK
0

So one of the ways to fix this is to make use of a few additional environment variables. If we look in include/configs/ti_armv7_common.h we have:

/*
 * We setup defaults based on constraints from the Linux kernel, which should
 * also be safe elsewhere.  We have the default load at 32MB into DDR (for
 * the kernel), FDT above 128MB (the maximum location for the end of the
 * kernel), and the ramdisk 512KB above that (allowing for hopefully never
 * seen large trees).  We say all of this must be within the first 256MB
 * as that will normally be within the kernel lowmem and thus visible via
 * bootm_size and we only run on platforms with 256MB or more of memory.
 */
#define DEFAULT_LINUX_BOOT_ENV \
        "loadaddr=0x82000000\0" \
        "kernel_addr_r=0x82000000\0" \
        "fdtaddr=0x88000000\0" \
        "fdt_addr_r=0x88000000\0" \
        "rdaddr=0x88080000\0" \
        "ramdisk_addr_r=0x88080000\0" \
        "scriptaddr=0x80000000\0" \
        "pxefile_addr_r=0x80100000\0" \
        "bootm_size=0x10000000\0"

So for the problem you're describing you would want to re-use bootm_size=0x10000000 to ensure that we keep the device tree within the first 256MB which is going to be kernel visible lowmem (with default kernel settings today at least, the size of kernel lowmem is configurable).

Another equally useful solution here is to simply place the device tree and ramdisk into memory where you know they will be safe and use fdt_high=0xffffffff and initrd_high=0xffffffff to disable relocation. The main use of relocation is to make sure that things will be safe in the generic case (where U-Boot could be handed a random kernel and device tree and ramdisk and simply not know how big everything is). In a production case like this you can figure out some always safe and correct values, load there and not move them another time.

  • Cheers! Both suggested solutions work, and they make a lot of sense, too. Thank you also for the good explanation inside the header file which I assume has been authored by you. – Hans W. Heckel Jan 29 '16 at 8:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.