summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/lib/pbl.lds.S7
-rw-r--r--firmware/Makefile38
-rw-r--r--include/firmware.h42
3 files changed, 77 insertions, 10 deletions
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index e77b3220fc..44ad5b3353 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -101,6 +101,13 @@ SECTIONS
}
__piggydata_end = .;
+ . = ALIGN(4);
+ __pblext_start = .;
+ .pblext : {
+ *(.pblext.*)
+ }
+ __pblext_end = .;
+
.image_end : { KEEP(*(.__image_end)) }
pbl_image_size = . - BASE;
diff --git a/firmware/Makefile b/firmware/Makefile
index 87bd033f6e..f6ff5b831b 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -30,16 +30,17 @@ firmware-$(CONFIG_FIRMWARE_CCBV2_OPTEE) += ccbv2_optee.bin
# leading /, it's relative to $(srctree).
fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR))
fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir))
+fwobjdir := $(objtree)/firmware
obj-pbl-y := $(addsuffix .gen.o, $(firmware-y))
-FWNAME = $(patsubst $(obj)/%.gen.S,%,$@)
+FWNAME = $(patsubst $(obj)/%.extgen.S,%,$(patsubst $(obj)/%.gen.S,%,$@))
FWSTR = $(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))
ASM_ALIGN = $(if $(CONFIG_64BIT),3,2)
filechk_fwbin = { \
echo "/* Generated by $(src)/Makefile */" ;\
- echo " .section .rodata.$(FWSTR)" ;\
+ echo " .section $2,\"$3\"" ;\
echo " .p2align $(ASM_ALIGN)" ;\
echo ".global _fw_$(FWSTR)_start" ;\
echo "_fw_$(FWSTR)_start:" ;\
@@ -48,19 +49,48 @@ filechk_fwbin = { \
echo "_fw_$(FWSTR)_end:" ;\
}
+__fwbin_sha = { \
+ echo " .section .rodata.$(FWSTR).sha" ;\
+ echo " .p2align $(ASM_ALIGN)" ;\
+ echo ".global _fw_$(FWSTR)_sha_start" ;\
+ echo "_fw_$(FWSTR)_sha_start:" ;\
+ echo " .incbin \"$(fwobjdir)/$(FWNAME).sha.bin\"" ;\
+ echo ".global _fw_$(FWSTR)_sha_end" ;\
+ echo "_fw_$(FWSTR)_sha_end:" ;\
+}
+
+filechk_fwbin_ext = { \
+ $(filechk_fwbin) ;\
+ $(__fwbin_sha) ;\
+}
+
$(obj)/%.gen.S: FORCE
- $(call filechk,fwbin)
+ $(call filechk,fwbin,.rodata.$(FWSTR),)
+
+$(obj)/%.extgen.S: $(obj)/%.sha.bin FORCE
+ $(call filechk,fwbin_ext,.pblext.$(FWSTR),a)
+
+$(obj)/%.sha.bin: $(obj)/%.sum FORCE
+ $(call if_changed,sha256bin)
+
+$(obj)/%.sum: $(obj)/% FORCE
+ $(call if_changed,sha256sum)
+
+clean-files += *.sha.bin *.sum
# The .o files depend on the binaries directly; the .S files don't.
$(patsubst %,$(obj)/%.gen.o, $(obj-pbl-y)): $(obj)/%.gen.o: $(fwdir)/%
# The same for pbl:
$(patsubst %,$(obj)/%.gen.pbl.o, $(obj-pbl-y)): $(obj)/%.gen.pbl.o: $(fwdir)/%
+$(patsubst %,$(obj)/%.extgen.pbl.o, $(pbl-y)): $(obj)/%.extgen.pbl.o: $(fwdir)/%
-obj-pbl-y += $(patsubst %,%.gen.o, $(fw-external-y))
+pbl-y := $(addsuffix .extgen.o, $(fw-external-y))
targets := $(patsubst $(obj)/%,%, \
$(shell find $(obj) -name \*.gen.S 2>/dev/null))
+targets += $(patsubst $(obj)/%,%, \
+ $(shell find $(obj) -name \*.extgen.S 2>/dev/null))
# just to build a built-in.o. Otherwise compilation fails when no
# firmware is built.
diff --git a/include/firmware.h b/include/firmware.h
index 2583342230..2cfaeb1e6a 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -6,8 +6,11 @@
#ifndef FIRMWARE_H
#define FIRMWARE_H
+#include <pbl.h>
#include <types.h>
#include <driver.h>
+#include <debug_ll.h>
+#include <linux/kernel.h>
struct firmware_handler {
char *id; /* unique identifier for this firmware device */
@@ -57,12 +60,39 @@ static inline void firmware_set_searchpath(const char *path)
void firmwaremgr_list_handlers(void);
-#define get_builtin_firmware(name, start, size) \
- { \
- extern char _fw_##name##_start[]; \
- extern char _fw_##name##_end[]; \
- *start = (typeof(*start)) _fw_##name##_start; \
- *size = _fw_##name##_end - _fw_##name##_start; \
+static inline void firmware_ext_verify(const void *data_start, size_t data_size,
+ const void *hash_start, size_t hash_size)
+{
+ if (pbl_barebox_verify(data_start, data_size,
+ hash_start, hash_size) != 0) {
+ putc_ll('!');
+ panic("hash mismatch, refusing to decompress");
}
+}
+
+#define __get_builtin_firmware(name, offset, start, size) \
+ do { \
+ extern char _fw_##name##_start[]; \
+ extern char _fw_##name##_end[]; \
+ extern char _fw_##name##_sha_start[]; \
+ extern char _fw_##name##_sha_end[]; \
+ *start = (typeof(*start)) _fw_##name##_start; \
+ *size = _fw_##name##_end - _fw_##name##_start; \
+ if (!(offset)) \
+ break; \
+ *start += (offset); \
+ firmware_ext_verify( \
+ *start, *size, \
+ _fw_##name##_sha_start, \
+ _fw_##name##_sha_end - _fw_##name##_sha_start \
+ ); \
+ } while (0)
+
+
+#define get_builtin_firmware(name, start, size) \
+ __get_builtin_firmware(name, 0, start, size)
+
+#define get_builtin_firmware_ext(name, base, start, size) \
+ __get_builtin_firmware(name, (long)base - (long)_text, start, size)
#endif /* FIRMWARE_H */