Allow embedding an FDT blob in the kernel image, this is mostly
useful to run new kernels on boards with old bootloaders.
Signed-off-by: Alban Bedel <[email protected]>
---
drivers/of/Kconfig | 16 ++++++++++++++++
drivers/of/Makefile | 8 ++++++++
drivers/of/fdt.c | 8 ++++++++
drivers/of/fdt_blob.S | 17 +++++++++++++++++
4 files changed, 49 insertions(+)
create mode 100644 drivers/of/fdt_blob.S
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 1a13f5b..97c5d18 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -83,4 +83,20 @@ config OF_RESERVED_MEM
config OF_RESOLVE
bool
+config OF_BUILTIN_FDT
+ bool "Include a FDT blob in the kernel"
+ help
+ Include a FDT blob in the kernel to use as default when
+ no blob has been passed by the bootloader. This is useful
+ to use devicetree on boards with old bootloaders.
+
+ If unsure, say N.
+
+config OF_BUILTIN_FDT_BLOB
+ string "FDT Blob name"
+ depends on OF_BUILTIN_FDT
+ help
+ Name of the FDT blob to build in the kernel, from one of the
+ dtbs available for the current platform.
+
endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ca9209c..b96c6e9 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -14,6 +14,14 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_MTD) += of_mtd.o
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
obj-$(CONFIG_OF_RESOLVE) += resolver.o
+obj-$(CONFIG_OF_BUILTIN_FDT) += fdt_blob.o
CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt
CFLAGS_fdt_address.o = -I$(src)/../../scripts/dtc/libfdt
+
+# The FDT blob to include
+FDT_BLOB := arch/$(ARCH)/boot/dts/$(CONFIG_OF_BUILTIN_FDT_BLOB:"%"=%).dtb
+# Undefine ARCH to avoid breaking the FDT path
+AFLAGS_fdt_blob.o += -U$(ARCH) -DFDT_BLOB=$(FDT_BLOB)
+# This dependency can't be automatically tracked
+$(obj)/fdt_blob.o: $(obj)/../../$(FDT_BLOB)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index d1ffca8..ffb86a7 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -26,6 +26,9 @@
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
+extern char __fdt_blob_start[];
+extern unsigned long __fdt_blob_size;
+
/*
* of_fdt_limit_memory - limit the number of regions in the /memory node
* @limit: maximum entries
@@ -1064,6 +1067,11 @@ void __init unflatten_and_copy_device_tree(void)
int size;
void *dt;
+#ifdef CONFIG_OF_BUILTIN_FDT
+ if (!initial_boot_params && __fdt_blob_size > 0)
+ initial_boot_params = __fdt_blob_start;
+#endif
+
if (!initial_boot_params) {
pr_warn("No valid device tree found, continuing without\n");
return;
diff --git a/drivers/of/fdt_blob.S b/drivers/of/fdt_blob.S
new file mode 100644
index 0000000..fcaa2aa
--- /dev/null
+++ b/drivers/of/fdt_blob.S
@@ -0,0 +1,17 @@
+#include <linux/stringify.h>
+#include <asm-generic/vmlinux.lds.h>
+
+.align 4
+.section .init.fdt_blob,"a"
+.globl VMLINUX_SYMBOL(__fdt_blob_start)
+VMLINUX_SYMBOL(__fdt_blob_start):
+.incbin __stringify(FDT_BLOB)
+__fdt_blob_end:
+.section .init.fdt_blob.info,"a"
+.globl VMLINUX_SYMBOL(__fdt_blob_size)
+VMLINUX_SYMBOL(__fdt_blob_size):
+#ifdef CONFIG_64BIT
+ .quad __fdt_blob_end - __fdt_blob_start
+#else
+ .long __fdt_blob_end - __fdt_blob_start
+#endif
--
2.0.0
Hi,
On Fri, Nov 07, 2014 at 11:14:09AM +0000, Alban Bedel wrote:
> Allow embedding an FDT blob in the kernel image, this is mostly
> useful to run new kernels on boards with old bootloaders.
I am very much not keen on embedding a DTB within a kernel. It's far
nicer for the two to remain separate blobs, with a small shim to set up
the DTB address.
On ARM we have appended DTB for this purpose, which is at least better
than embedding the DT inside of the kernel.
What architecture and bootloader are you using that necessitate this?
Thanks,
Mark.
> Signed-off-by: Alban Bedel <[email protected]>
> ---
> drivers/of/Kconfig | 16 ++++++++++++++++
> drivers/of/Makefile | 8 ++++++++
> drivers/of/fdt.c | 8 ++++++++
> drivers/of/fdt_blob.S | 17 +++++++++++++++++
> 4 files changed, 49 insertions(+)
> create mode 100644 drivers/of/fdt_blob.S
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 1a13f5b..97c5d18 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -83,4 +83,20 @@ config OF_RESERVED_MEM
> config OF_RESOLVE
> bool
>
> +config OF_BUILTIN_FDT
> + bool "Include a FDT blob in the kernel"
> + help
> + Include a FDT blob in the kernel to use as default when
> + no blob has been passed by the bootloader. This is useful
> + to use devicetree on boards with old bootloaders.
> +
> + If unsure, say N.
> +
> +config OF_BUILTIN_FDT_BLOB
> + string "FDT Blob name"
> + depends on OF_BUILTIN_FDT
> + help
> + Name of the FDT blob to build in the kernel, from one of the
> + dtbs available for the current platform.
> +
> endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index ca9209c..b96c6e9 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -14,6 +14,14 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
> obj-$(CONFIG_OF_MTD) += of_mtd.o
> obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> obj-$(CONFIG_OF_RESOLVE) += resolver.o
> +obj-$(CONFIG_OF_BUILTIN_FDT) += fdt_blob.o
>
> CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt
> CFLAGS_fdt_address.o = -I$(src)/../../scripts/dtc/libfdt
> +
> +# The FDT blob to include
> +FDT_BLOB := arch/$(ARCH)/boot/dts/$(CONFIG_OF_BUILTIN_FDT_BLOB:"%"=%).dtb
> +# Undefine ARCH to avoid breaking the FDT path
> +AFLAGS_fdt_blob.o += -U$(ARCH) -DFDT_BLOB=$(FDT_BLOB)
> +# This dependency can't be automatically tracked
> +$(obj)/fdt_blob.o: $(obj)/../../$(FDT_BLOB)
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index d1ffca8..ffb86a7 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -26,6 +26,9 @@
> #include <asm/setup.h> /* for COMMAND_LINE_SIZE */
> #include <asm/page.h>
>
> +extern char __fdt_blob_start[];
> +extern unsigned long __fdt_blob_size;
> +
> /*
> * of_fdt_limit_memory - limit the number of regions in the /memory node
> * @limit: maximum entries
> @@ -1064,6 +1067,11 @@ void __init unflatten_and_copy_device_tree(void)
> int size;
> void *dt;
>
> +#ifdef CONFIG_OF_BUILTIN_FDT
> + if (!initial_boot_params && __fdt_blob_size > 0)
> + initial_boot_params = __fdt_blob_start;
> +#endif
> +
> if (!initial_boot_params) {
> pr_warn("No valid device tree found, continuing without\n");
> return;
> diff --git a/drivers/of/fdt_blob.S b/drivers/of/fdt_blob.S
> new file mode 100644
> index 0000000..fcaa2aa
> --- /dev/null
> +++ b/drivers/of/fdt_blob.S
> @@ -0,0 +1,17 @@
> +#include <linux/stringify.h>
> +#include <asm-generic/vmlinux.lds.h>
> +
> +.align 4
> +.section .init.fdt_blob,"a"
> +.globl VMLINUX_SYMBOL(__fdt_blob_start)
> +VMLINUX_SYMBOL(__fdt_blob_start):
> +.incbin __stringify(FDT_BLOB)
> +__fdt_blob_end:
> +.section .init.fdt_blob.info,"a"
> +.globl VMLINUX_SYMBOL(__fdt_blob_size)
> +VMLINUX_SYMBOL(__fdt_blob_size):
> +#ifdef CONFIG_64BIT
> + .quad __fdt_blob_end - __fdt_blob_start
> +#else
> + .long __fdt_blob_end - __fdt_blob_start
> +#endif
> --
> 2.0.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
On Fri, 7 Nov 2014 12:09:33 +0000
Mark Rutland <[email protected]> wrote:
> Hi,
>
> On Fri, Nov 07, 2014 at 11:14:09AM +0000, Alban Bedel wrote:
> > Allow embedding an FDT blob in the kernel image, this is mostly
> > useful to run new kernels on boards with old bootloaders.
>
> I am very much not keen on embedding a DTB within a kernel. It's far
> nicer for the two to remain separate blobs, with a small shim to set
> up the DTB address.
>
> On ARM we have appended DTB for this purpose, which is at least better
> than embedding the DT inside of the kernel.
I looked at that but that seemed quiet complicated to implement, not to
mention that it needed quiet a lot of arch specific code. On the other
hand having the DTB built in like this was trivial and would be portable
to every architecture, so that seemed like the best way to me.
> What architecture and bootloader are you using that necessitate this?
MIPS with an antic u-boot version patched by the board vendor to use
some non standard image format. Updating the boot loader is currently
not an option because of the lack of documentation for the board/SoC.
Alban
On Fri, Nov 7, 2014 at 6:59 AM, Alban <[email protected]> wrote:
> On Fri, 7 Nov 2014 12:09:33 +0000
> Mark Rutland <[email protected]> wrote:
>
>> Hi,
>>
>> On Fri, Nov 07, 2014 at 11:14:09AM +0000, Alban Bedel wrote:
>> > Allow embedding an FDT blob in the kernel image, this is mostly
>> > useful to run new kernels on boards with old bootloaders.
>>
>> I am very much not keen on embedding a DTB within a kernel. It's far
>> nicer for the two to remain separate blobs, with a small shim to set
>> up the DTB address.
>>
>> On ARM we have appended DTB for this purpose, which is at least better
>> than embedding the DT inside of the kernel.
>
> I looked at that but that seemed quiet complicated to implement, not to
> mention that it needed quiet a lot of arch specific code. On the other
> hand having the DTB built in like this was trivial and would be portable
> to every architecture, so that seemed like the best way to me.
>
>> What architecture and bootloader are you using that necessitate this?
>
> MIPS with an antic u-boot version patched by the board vendor to use
> some non standard image format. Updating the boot loader is currently
> not an option because of the lack of documentation for the board/SoC.
MIPS and a few other arches already have built-in dtb support. We
don't need another way to do it, but I would welcome any clean-up that
makes it arch independent and available to any arch.
While Mark is right, I could envision other uses such as embedding
overlay dtbs in the kernel either for add-on boards or just as fixups.
Rob
On Fri, Nov 07, 2014 at 02:56:32PM +0000, Rob Herring wrote:
> On Fri, Nov 7, 2014 at 6:59 AM, Alban <[email protected]> wrote:
> > On Fri, 7 Nov 2014 12:09:33 +0000
> > Mark Rutland <[email protected]> wrote:
> >
> >> Hi,
> >>
> >> On Fri, Nov 07, 2014 at 11:14:09AM +0000, Alban Bedel wrote:
> >> > Allow embedding an FDT blob in the kernel image, this is mostly
> >> > useful to run new kernels on boards with old bootloaders.
> >>
> >> I am very much not keen on embedding a DTB within a kernel. It's far
> >> nicer for the two to remain separate blobs, with a small shim to set
> >> up the DTB address.
> >>
> >> On ARM we have appended DTB for this purpose, which is at least better
> >> than embedding the DT inside of the kernel.
> >
> > I looked at that but that seemed quiet complicated to implement, not to
> > mention that it needed quiet a lot of arch specific code. On the other
> > hand having the DTB built in like this was trivial and would be portable
> > to every architecture, so that seemed like the best way to me.
> >
> >> What architecture and bootloader are you using that necessitate this?
> >
> > MIPS with an antic u-boot version patched by the board vendor to use
> > some non standard image format. Updating the boot loader is currently
> > not an option because of the lack of documentation for the board/SoC.
>
> MIPS and a few other arches already have built-in dtb support. We
> don't need another way to do it, but I would welcome any clean-up that
> makes it arch independent and available to any arch.
>
> While Mark is right, I could envision other uses such as embedding
> overlay dtbs in the kernel either for add-on boards or just as fixups.
I don't see how embedding a DTB in this manner helps with overlays and
fixups.
I'm rather worried about this turning into a shoddy board file, and
making it painful to build/distribute/boot a generic kernel for an
arbitrary platform.
On arm64 the kernel and DTB have always been separate, and I'm not keen
on allowing the two to be tightly coupled in this way. There are already
container formats (e.g. FIT) that can be used to hold both if that's
what the bootloader desires.
Thanks,
Mark.
On Fri, 7 Nov 2014 12:14:09 +0100
, Alban Bedel <[email protected]>
wrote:
> Allow embedding an FDT blob in the kernel image, this is mostly
> useful to run new kernels on boards with old bootloaders.
>
> Signed-off-by: Alban Bedel <[email protected]>
The kernel already supports linking in .dtb files. All you need to do is
add <filename>.dtb.o in the build objects.
> ---
> drivers/of/Kconfig | 16 ++++++++++++++++
> drivers/of/Makefile | 8 ++++++++
> drivers/of/fdt.c | 8 ++++++++
> drivers/of/fdt_blob.S | 17 +++++++++++++++++
> 4 files changed, 49 insertions(+)
> create mode 100644 drivers/of/fdt_blob.S
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 1a13f5b..97c5d18 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -83,4 +83,20 @@ config OF_RESERVED_MEM
> config OF_RESOLVE
> bool
>
> +config OF_BUILTIN_FDT
> + bool "Include a FDT blob in the kernel"
> + help
> + Include a FDT blob in the kernel to use as default when
> + no blob has been passed by the bootloader. This is useful
> + to use devicetree on boards with old bootloaders.
> +
> + If unsure, say N.
> +
> +config OF_BUILTIN_FDT_BLOB
> + string "FDT Blob name"
> + depends on OF_BUILTIN_FDT
> + help
> + Name of the FDT blob to build in the kernel, from one of the
> + dtbs available for the current platform.
> +
I'm not keen on making this a generic option. ARM and PowerPC already
have the mechanism for attaching a dtb, and they do not build it into
the kernel. Each architecture that wants to use this needs to enable it
separately.
g.
> endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index ca9209c..b96c6e9 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -14,6 +14,14 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
> obj-$(CONFIG_OF_MTD) += of_mtd.o
> obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> obj-$(CONFIG_OF_RESOLVE) += resolver.o
> +obj-$(CONFIG_OF_BUILTIN_FDT) += fdt_blob.o
>
> CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt
> CFLAGS_fdt_address.o = -I$(src)/../../scripts/dtc/libfdt
> +
> +# The FDT blob to include
> +FDT_BLOB := arch/$(ARCH)/boot/dts/$(CONFIG_OF_BUILTIN_FDT_BLOB:"%"=%).dtb
> +# Undefine ARCH to avoid breaking the FDT path
> +AFLAGS_fdt_blob.o += -U$(ARCH) -DFDT_BLOB=$(FDT_BLOB)
> +# This dependency can't be automatically tracked
> +$(obj)/fdt_blob.o: $(obj)/../../$(FDT_BLOB)
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index d1ffca8..ffb86a7 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -26,6 +26,9 @@
> #include <asm/setup.h> /* for COMMAND_LINE_SIZE */
> #include <asm/page.h>
>
> +extern char __fdt_blob_start[];
> +extern unsigned long __fdt_blob_size;
> +
> /*
> * of_fdt_limit_memory - limit the number of regions in the /memory node
> * @limit: maximum entries
> @@ -1064,6 +1067,11 @@ void __init unflatten_and_copy_device_tree(void)
> int size;
> void *dt;
>
> +#ifdef CONFIG_OF_BUILTIN_FDT
> + if (!initial_boot_params && __fdt_blob_size > 0)
> + initial_boot_params = __fdt_blob_start;
> +#endif
> +
> if (!initial_boot_params) {
> pr_warn("No valid device tree found, continuing without\n");
> return;
> diff --git a/drivers/of/fdt_blob.S b/drivers/of/fdt_blob.S
> new file mode 100644
> index 0000000..fcaa2aa
> --- /dev/null
> +++ b/drivers/of/fdt_blob.S
> @@ -0,0 +1,17 @@
> +#include <linux/stringify.h>
> +#include <asm-generic/vmlinux.lds.h>
> +
> +.align 4
> +.section .init.fdt_blob,"a"
> +.globl VMLINUX_SYMBOL(__fdt_blob_start)
> +VMLINUX_SYMBOL(__fdt_blob_start):
> +.incbin __stringify(FDT_BLOB)
> +__fdt_blob_end:
> +.section .init.fdt_blob.info,"a"
> +.globl VMLINUX_SYMBOL(__fdt_blob_size)
> +VMLINUX_SYMBOL(__fdt_blob_size):
> +#ifdef CONFIG_64BIT
> + .quad __fdt_blob_end - __fdt_blob_start
> +#else
> + .long __fdt_blob_end - __fdt_blob_start
> +#endif
> --
> 2.0.0
>