How to add device tree blob to Linux x86 kernel boot?
Asked Answered
A

1

7

My custom development board is based on x86 and one of the electronic component which is connected to it (through SPI mainly) cannot be controlled easily without using the vendor kernel driver (and the vendor won't help if I don't use it). This module requires some configuration parameters that it gets from the device tree. I believe this module is mostly used on ARM platforms where device trees are common.

On x86, the device tree is generally not needed so it is disabled by default during Linux kernel compilation. I changed the configuration in order to enable it, but I cannot find the way to put the device tree BLOB into the boot image. There is only one DTS file for the x86 architecture in the kernel sources but it doesn't seem to be used at all so it doesn't help.

From the kernel documentation, I understand I need to put it in the setup_data field of the x86 real-mode kernel header, but I don't understand how to do that and when (at kernel build time? when building the bootloader?). Am I supposed to hack the arch/x86/boot/header.S file directly?

Right now, I've replaced the module configuration by hard-coded values, but using the device tree would be better.

Aardwolf answered 15/2, 2016 at 21:15 Comment(3)
You may check OLPC and CE4100 platforms which are x86 and using Device Tree. But I suggest to consult vendor to switch to built-in device property API and use some platform code in your case.Ketubim
support may be available in main line also, have a look here lxr.free-electrons.com/source/arch/x86/kernel/devicetree.c for arm's it is given here crashcourse.ca/wiki/index.php/Kernel_parsing_of_device_trees, may be a replica of steps can be made from the second link to first oneNisan
Good to read, however maybe not so helpful in this particular case, is the following QA: #46096340, #54769341 and #39119221Ketubim
S
2

On x86, the boot loader adds the Device Tree binary data (DTB) to the linked list of setup_data structures before calling the kernel entry point. The DTB can be loaded from a storage device or embedded into the boot loader image.

The following code shows how it's implemented in U-Boot.

http://git.denx.de/?p=u-boot.git;a=blob;f=arch/x86/lib/zimage.c:

static int setup_device_tree(struct setup_header *hdr, const void *fdt_blob)
{
        int bootproto = get_boot_protocol(hdr);
        struct setup_data *sd;
        int size;

        if (bootproto < 0x0209)
                return -ENOTSUPP;

        if (!fdt_blob)
                return 0;

        size = fdt_totalsize(fdt_blob);
        if (size < 0)
                return -EINVAL;

        size += sizeof(struct setup_data);
        sd = (struct setup_data *)malloc(size);
        if (!sd) {
                printf("Not enough memory for DTB setup data\n");
                return -ENOMEM;
        }

        sd->next = hdr->setup_data;
        sd->type = SETUP_DTB;
        sd->len = fdt_totalsize(fdt_blob);
        memcpy(sd->data, fdt_blob, sd->len);
        hdr->setup_data = (unsigned long)sd;

        return 0;
}
Skeg answered 17/12, 2018 at 23:12 Comment(5)
@ignorinov Thanks for your answer. Do you know any x86 boot loaders that allow this and support being loaded by BIOS (which u-boot does not AFAIK)?Panic
@Tey': You are welcome. According to doc/README.x86, it supports being loaded by BIOS: "U-Boot supports booting as a 32-bit or 64-bit EFI payload, e.g. with UEFI. This is enabled with CONFIG_EFI_STUB to boot from both 32-bit and 64-bit UEFI BIOS. U-Boot can also run as an EFI application, with CONFIG_EFI_APP".Skeg
I guess my terminology is misleading: by "BIOS", I meant legacy BIOS (not UEFI).Panic
To load U-Boot from legacy BIOS, you need to write a first stage loader (similar to Stage 1 of GRUB) that loads U-Boot from consecutive blocks of the storage device and copies it to the preferred address using legacy BIOS calls. GRUB also supports devicetree, but I'm not sure if it works on x86: gnu.org/software/grub/manual/grub/html_node/…Skeg
Intel Edison, which is using U-Boot as a chained boot loader, exactly does what @Aardwolf is asking for.Ketubim

© 2022 - 2024 — McMap. All rights reserved.