new file mode 100644
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_BLOB_H
+#define _LINUX_BLOB_H
+
+#include <linux/compiler_types.h>
+#include <linux/types.h>
+
+struct blob {
+ const char *const path;
+ const u8 *data;
+ const u8 __private *end;
+};
+
+#define DECLARE_BLOB(_symbol) extern const struct blob _symbol
+
+static inline size_t blob_size(const struct blob *blob)
+{
+ return ACCESS_PRIVATE(blob, end) - blob->data;
+}
+
+#endif /* _LINUX_BLOB_H */
new file mode 100644
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Build linkable blobs
+#
+
+blobs := $(addprefix $(obj)/, $(blobs))
+
+blob-stem = $(subst -,_,$(subst .blob,,$(basename $(patsubst $(obj)/%,%,$@))))
+blob-symbol = $(or $($(target-stem)-symbol),$(blob-stem))
+
+blob-flags = -DBLOB_SYMBOL="$(blob-symbol)" -DBLOB_INPUT=$<
+
+quiet_cmd_blob = BLOB $@
+ cmd_blob = $(CC) $(c_flags) $(blob-flags) -c -o $@ $(srctree)/scripts/blob-wrap.c
+
+$(blobs): $(obj)/%.blob.o: $(obj)/% $(srctree)/scripts/blob-wrap.c FORCE
+ $(call if_changed_dep,blob)
+
+targets += $(blobs)
@@ -440,6 +440,12 @@ ifneq ($(need-dtbslist)$(dtb-y)$(dtb-)$(filter %.dtb %.dtb.o %.dtbo.o,$(targets)
include $(srctree)/scripts/Makefile.dtbs
endif
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
+blobs := $(sort $(blobs))
+ifneq ($(blobs),)
+include $(srctree)/scripts/Makefile.blobs
+endif
+
# Build
# ---------------------------------------------------------------------------
@@ -25,7 +25,7 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
# directory
__clean-files := \
- $(clean-files) $(targets) $(hostprogs) $(userprogs) \
+ $(clean-files) $(targets) $(hostprogs) $(userprogs) $(blobs) \
$(extra-y) $(extra-m) $(extra-) \
$(always-y) $(always-m) $(always-) \
$(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \
new file mode 100644
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/args.h>
+#include <linux/blob.h>
+#include <linux/stringify.h>
+
+#define BLOB_SYMBOL_DATA CONCATENATE(_blob_data_, BLOB_SYMBOL)
+#define BLOB_SYMBOL_END CONCATENATE(_blob_end_, BLOB_SYMBOL)
+
+asm (
+" .pushsection .rodata, \"a\" \n"
+" .global " __stringify(BLOB_SYMBOL_DATA) " \n"
+ __stringify(BLOB_SYMBOL_DATA) ": \n"
+" .incbin \"" __stringify(BLOB_INPUT) "\" \n"
+" .global " __stringify(BLOB_SYMBOL_END) " \n"
+ __stringify(BLOB_SYMBOL_END) ": \n"
+" .popsection \n"
+);
+
+extern const u8 BLOB_SYMBOL_DATA;
+extern const u8 BLOB_SYMBOL_END;
+
+const struct blob BLOB_SYMBOL = {
+ .path = __stringify(BLOB_INPUT),
+ .data = &BLOB_SYMBOL_DATA,
+ .end = &BLOB_SYMBOL_END,
+};
Various subsystems embed non-code build artifacts into the kernel, for example the initramfs, /proc/config.gz, vDSO image, etc. Currently each user has their own implementation for that. Add a common "blob" framework to provide this functionality. It provides standard kbuild and C APIs to embed and later access non-code build artifacts into the kernel image or modules. Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de> --- This is currently lacking a MAINTAINERS entry. Due to its closeness to kbuild I would tend to add it there. But I can also maintain it on its own. --- include/linux/blob.h | 21 +++++++++++++++++++++ scripts/Makefile.blobs | 19 +++++++++++++++++++ scripts/Makefile.build | 6 ++++++ scripts/Makefile.clean | 2 +- scripts/blob-wrap.c | 27 +++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-)