linux-kernel - 如何将设备树 blob 添加到 Linux x86 内核启动?

标签 linux-kernel x86 embedded-linux bootloader device-tree

我的定制开发板基于x86,如果不使用供应商内核驱动程序,连接到它的电子元件之一(主要通过SPI)无法轻松控制(如果我不使用它供应商将无济于事) .该模块需要一些从设备树中获取的配置参数。我相信这个模块主要用在设备树很常见的 ARM 平台上。

在 x86 上,通常不需要设备树,因此在 Linux 内核编译期间默认禁用它。我更改了配置以启用它,但我找不到将设备树 BLOB 放入启动镜像的方法。只有one DTS file对于内核源代码中的 x86 架构,但它似乎根本没有被使用,所以它没有帮助。

来自 kernel documentation , 我知道我需要把它放在 setup_data x86 real-mode kernel header 的字段,但我不明白怎么做,什么时候做 (在内核构建时?构建引导加载程序时?)。我应该破解 arch/x86/boot/header.S 直接存档?

现在,我已经用硬编码值替换了模块配置,但使用设备树会更好。

最佳答案

在 x86 上,引导加载程序在调用内核入口点之前将设备树二进制数据 (DTB) 添加到 setup_data 结构的链表中。 DTB 可以从存储设备加载或嵌入到引导加载程序镜像中。

下面的代码展示了它是如何在 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;
}

关于linux-kernel - 如何将设备树 blob 添加到 Linux x86 内核启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35419238/

相关文章:

c - 我如何找到我正在运行的 CPU/内核?

c++ - 如何在 GDB 中编写一个引用指针的表达式?

linux - 如何为arm-v7交叉编译qt应用程序

android - 如何修复 Android 内核中 C 函数的隐式类型声明

gcc - Linux kernel 5.4 GCC 9.1.0 不显示代码覆盖率

assembly - 在 MASM 上构建 16 位代码而不是 32 位代码

c - 函数 getgrgid() 在无人调用时返回 NULL

embedded - RTOS 和嵌入式 Linux 有什么区别?

linux - SMP linux 中的互斥所有者

windows - md5sum 在 linux 和 windows 上不同