Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d2acfbf authored by David Woodhouse's avatar David Woodhouse Committed by David Woodhouse
Browse files

firmware: Add CONFIG_EXTRA_FIRMWARE option



This allows arbitrary firmware files to be included in the static kernel
where the firmware loader can find them without requiring userspace to
be alive.

(Updated and CONFIG_EXTRA_FIRMWARE_DIR added with lots of help from
Johannes Berg).

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
parent 5658c769
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf

# Objects we will link into vmlinux / subdirs we need to visit
init-y		:= init/
drivers-y	:= drivers/ sound/
drivers-y	:= drivers/ sound/ firmware/
net-y		:= net/
libs-y		:= lib/
core-y		:= usr/
+39 −0
Original line number Diff line number Diff line
@@ -34,6 +34,45 @@ config FW_LOADER
	  require userspace firmware loading support, but a module built outside
	  the kernel tree does.

config EXTRA_FIRMWARE
	string "External firmware blobs to build into the kernel binary"
	depends on FW_LOADER
	help
	  This option allows firmware to be built into the kernel, for the
	  cases where the user either cannot or doesn't want to provide it from
	  userspace at runtime (for example, when the firmware in question is
	  required for accessing the boot device, and the user doesn't want to
	  use an initrd).

	  This option is a string, and takes the (space-separated) names of the
	  firmware files -- the same names which appear in MODULE_FIRMWARE()
	  and request_firmware() in the source. These files should exist under
	  the directory specified by the EXTRA_FIRMWARE_DIR option, which is
	  by default the firmware/ subdirectory of the kernel source tree.

	  So, for example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin",
	  copy the usb8388.bin file into the firmware/ directory, and build the
	  kernel. Then any request_firmware("usb8388.bin") will be
	  satisfied internally without needing to call out to userspace.

	  WARNING: If you include additional firmware files into your binary
	  kernel image which are not available under the terms of the GPL,
	  then it may be a violation of the GPL to distribute the resulting
	  image -- since it combines both GPL and non-GPL work. You should
	  consult a lawyer of your own before distributing such an image.

config EXTRA_FIRMWARE_DIR
	string "Firmware blobs root directory"
	depends on EXTRA_FIRMWARE != ""
	default "firmware"
	help
	  This option controls the directory in which the kernel build system
	  looks for the firmware files listed in the EXTRA_FIRMWARE option.
	  The default is the firmware/ directory in the kernel source tree,
	  but by changing this option you can point it elsewhere, such as
	  the /lib/firmware/ directory or another separate directory
	  containing firmware files.

config DEBUG_DRIVER
	bool "Driver Core verbose debug messages"
	depends on DEBUG_KERNEL

firmware/Makefile

0 → 100644
+88 −0
Original line number Diff line number Diff line
#
# kbuild file for firmware/
#

# Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a
# leading /, it's relative to $(srctree).
fwdir := $(subst ",,$(CONFIG_EXTRA_FIRMWARE_DIR))
fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir))

fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE))

firmware-y    := $(fw-external-y) $(fw-shipped-y)
firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y) $(fw-shipped-))))

quiet_cmd_mkdir = MKDIR   $(patsubst $(objtree)/%,%,$@)
      cmd_mkdir = mkdir -p $@

quiet_cmd_ihex  = IHEX    $@
      cmd_ihex  = $(OBJCOPY) -Iihex -Obinary $< $@

quiet_cmd_fwbin = MK_FW   $@
      cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)";		     \
		  FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst	     \
				firmware/%.gen.S,%,$@))))";		     \
		  ASM_WORD=$(if $(CONFIG_64BIT),.quad,.long);		     \
		  ASM_ALIGN=$(if $(CONFIG_64BIT),3,2);			     \
		  PROGBITS=$(if $(CONFIG_ARM),%,@)progbits;		     \
		  echo "/* Generated by firmware/Makefile */"		> $@;\
		  echo "    .section .rodata"				>>$@;\
		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
		  echo "_fw_$${FWSTR}_bin:"				>>$@;\
		  echo "    .incbin \"$(2)\""				>>$@;\
		  echo "_fw_end:"					>>$@;\
		  echo "   .section .rodata.str,\"aMS\",$${PROGBITS},1"	>>$@;\
		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
		  echo "_fw_$${FWSTR}_name:"				>>$@;\
		  echo "    .string \"$$FWNAME\""			>>$@;\
		  echo "    .section .builtin_fw,\"a\",$${PROGBITS}"	>>$@;\
		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
		  echo "    $${ASM_WORD} _fw_$${FWSTR}_name"		>>$@;\
		  echo "    $${ASM_WORD} _fw_$${FWSTR}_bin"		>>$@;\
		  echo "    $${ASM_WORD} _fw_end - _fw_$${FWSTR}_bin"	>>$@;

# One of these files will change, or come into existence, whenever
# the configuration changes between 32-bit and 64-bit. The .S files
# need to change when that happens.
wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \
		include/config/ppc32.h include/config/ppc64.h \
		include/config/superh32.h include/config/superh64.h \
		include/config/x86_32.h include/config/x86_64.h)

# Workaround for make < 3.81, where .SECONDEXPANSION doesn't work.
# It'll end up depending on these targets, so make them a PHONY rule which
# depends on _all_ the directories in $(firmware-dirs), and it'll work out OK.
PHONY += $(objtree)/$$(%) $(objtree)/$(obj)/$$(%)
$(objtree)/$$(%) $(objtree)/$(obj)/$$(%): $(firmware-dirs)
	@true

# For the $$(dir %) trick, where we need % to be expanded first.
.SECONDEXPANSION:

$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) \
		| $(objtree)/$$(dir %)
	$(call cmd,fwbin,$(patsubst %.gen.S,%,$@))
$(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \
		include/config/builtin/firmware/dir.h | $(objtree)/$$(dir %)
	$(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@))

# The .o files depend on the binaries directly; the .S files don't.
$(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: %
$(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/%

$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
	$(call cmd,ihex)

$(firmware-dirs):
	$(call cmd,mkdir)

obj-y := $(patsubst %,%.gen.o, $(firmware-y))

# Remove .S files and binaries created from ihex
# (during 'make clean' .config isn't included so they're all in $(fw-shipped-))
targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \
				$(shell find $(obj) -name \*.gen.S 2>/dev/null))

# Without this, built-in.o won't be created when it's empty, and the
# final vmlinux link will fail.
obj-n := dummy