image: allow building FIT and uImage with ramdisk

Instead of embedding the initrd cpio archive into the kernel, allow
for having an external ramdisk added to the FIT or uImage.
This is useful to overcome kernel size limitations present in many
stock bootloaders, as the ramdisk is then loaded seperately and doesn't
add to the kernel size. Hence we can have larger ramdisks to host ie.
installers with all binaries to flash included (or a web-based
firmware selector).
In terms of performance and total size the differences are neglectible.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle 2021-02-21 14:19:26 +00:00
parent e6aac8d98f
commit 330bd380e8
6 changed files with 100 additions and 6 deletions

View File

@ -35,9 +35,11 @@ menu "Target Images"
bool "lzma"
config TARGET_INITRAMFS_COMPRESSION_LZO
depends on !TARGET_ROOTFS_INITRAMFS_SEPERATE
bool "lzo"
config TARGET_INITRAMFS_COMPRESSION_LZ4
depends on !TARGET_ROOTFS_INITRAMFS_SEPERATE
bool "lz4"
config TARGET_INITRAMFS_COMPRESSION_XZ
@ -62,6 +64,15 @@ menu "Target Images"
help
Ignore the initramfs passed by the bootloader.
config TARGET_ROOTFS_INITRAMFS_SEPERATE
bool "seperate ramdisk"
depends on TARGET_ROOTFS_INITRAMFS && !TARGET_INITRAMFS_FORCE
default y if USES_SEPERATE_INITRAMFS
help
Generate seperate initrd.cpio instead of embedding it.
This is useful for generating images with a dedicated
ramdisk e.g. in U-Boot's uImage and uImage.FIT formats.
comment "Root filesystem archives"
config TARGET_ROOTFS_CPIOGZ

View File

@ -196,11 +196,22 @@ define Build/eva-image
mv $@.new $@
endef
define Build/initrd_compression
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),.bzip2) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),.gzip) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZMA),.lzma) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_XZ),.xz) \
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_ZSTD),.zstd)
endef
define Build/fit
$(TOPDIR)/scripts/mkits.sh \
-D $(DEVICE_NAME) -o $@.its -k $@ \
$(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \
$(if $(findstring with-rootfs,$(word 3,$(1))),-r $(IMAGE_ROOTFS)) \
$(if $(findstring with-initrd,$(word 3,$(1))), \
$(if $(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPERATE), \
-i $(KERNEL_BUILD_DIR)/initrd.cpio$(strip $(call Build/initrd_compression)))) \
-a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
$(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
@ -450,6 +461,22 @@ define Build/uImage
mv $@.new $@
endef
define Build/uImage-with-ramdisk
mkimage \
-A $(LINUX_KARCH) \
-O linux \
-T kernel \
-C $(word 1,$(1)) \
-a $(KERNEL_LOADADDR) \
-e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
-i $(KERNEL_BUILD_DIR)/initrd.cpio.$(strip $(call Build/initrd_compression)) \
-n '$(if $(UIMAGE_NAME),$(UIMAGE_NAME),$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION))' \
$(if $(UIMAGE_MAGIC),-M $(UIMAGE_MAGIC)) \
$(wordlist 2,$(words $(1)),$(1)) \
-d $@ $@.new
mv $@.new $@
endef
define Build/xor-image
$(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1)
mv $@.xor $@

View File

@ -48,6 +48,13 @@ else
endif
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPERATE),y)
define Kernel/SetInitramfs/PreConfigure
grep -v -e CONFIG_BLK_DEV_INITRD $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config
echo 'CONFIG_BLK_DEV_INITRD=y' >> $(LINUX_DIR)/.config
echo 'CONFIG_INITRAMFS_SOURCE=""' >> $(LINUX_DIR)/.config
endef
else
ifeq ($(strip $(CONFIG_EXTERNAL_CPIO)),"")
define Kernel/SetInitramfs/PreConfigure
grep -v -e INITRAMFS -e CONFIG_RD_ -e CONFIG_BLK_DEV_INITRD $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config
@ -60,14 +67,19 @@ ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
echo 'CONFIG_INITRAMFS_SOURCE="$(call qstrip,$(CONFIG_EXTERNAL_CPIO))"' >> $(LINUX_DIR)/.config
endef
endif
endif
define Kernel/SetInitramfs
rm -f $(LINUX_DIR)/.config.prev
mv $(LINUX_DIR)/.config $(LINUX_DIR)/.config.old
$(call Kernel/SetInitramfs/PreConfigure)
ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPERATE),y)
echo 'CONFIG_INITRAMFS_ROOT_UID=$(shell id -u)' >> $(LINUX_DIR)/.config
echo 'CONFIG_INITRAMFS_ROOT_GID=$(shell id -g)' >> $(LINUX_DIR)/.config
echo "$(if $(CONFIG_TARGET_INITRAMFS_FORCE),CONFIG_INITRAMFS_FORCE=y,# CONFIG_INITRAMFS_FORCE is not set)" >> $(LINUX_DIR)/.config
else
echo "# CONFIG_INITRAMFS_FORCE is not set" >> $(LINUX_DIR)/.config
endif
echo "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_NONE),CONFIG_INITRAMFS_COMPRESSION_NONE=y,# CONFIG_INITRAMFS_COMPRESSION_NONE is not set)" >> $(LINUX_DIR)/.config
echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),CONFIG_INITRAMFS_COMPRESSION_GZIP=y\nCONFIG_RD_GZIP=y,# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set\n# CONFIG_RD_GZIP is not set)" >> $(LINUX_DIR)/.config
echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),CONFIG_INITRAMFS_COMPRESSION_BZIP2=y\nCONFIG_RD_BZIP2=y,# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set\n# CONFIG_RD_BZIP2 is not set)" >> $(LINUX_DIR)/.config
@ -147,6 +159,20 @@ define Kernel/CompileImage/Initramfs
$(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(TARGET_DIR)/init
$(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(TARGET_DIR)/init)
rm -rf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/usr/initramfs_data.cpio*
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPERATE),y)
ifeq ($(CONFIG_EXTERNAL_CPIO),y)
$(CP) $(CONFIG_EXTERNAL_CPIO) $(KERNEL_BUILD_DIR)/initrd.cpio
else
( cd $(TARGET_DIR); find . | cpio -o -H newc -R root:root > $(KERNEL_BUILD_DIR)/initrd.cpio )
endif
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),bzip2 -9 -c < $(KERNEL_BUILD_DIR)/initrd.cpio > $(KERNEL_BUILD_DIR)/initrd.cpio.bzip2)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),gzip -f -S .gzip -9n $(KERNEL_BUILD_DIR)/initrd.cpio)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZMA),$(STAGING_DIR_HOST)/bin/lzma e -lc1 -lp2 -pb2 $(KERNEL_BUILD_DIR)/initrd.cpio $(KERNEL_BUILD_DIR)/initrd.cpio.lzma)
# ? $(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZO),)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_XZ),$(STAGING_DIR_HOST)/bin/xz -9 -fz --check=crc32 $(KERNEL_BUILD_DIR)/initrd.cpio)
# ? $(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZ4),)
$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_ZSTD),$(STAGING_DIR_HOST)/bin/zstd -T0 -f -o $(KERNEL_BUILD_DIR)/initrd.cpio.zstd $(KERNEL_BUILD_DIR)/initrd.cpio)
endif
+$(KERNEL_MAKE) $(KERNEL_MAKEOPTS_IMAGE) $(if $(KERNELNAME),$(KERNELNAME),all)
$(call Kernel/CopyImage,-initramfs)
endef

View File

@ -24,6 +24,7 @@ usage() {
printf "\n\t-a ==> set load address to 'addr' (hex)"
printf "\n\t-e ==> set entry point to 'entry' (hex)"
printf "\n\t-f ==> set device tree compatible string"
printf "\n\t-i ==> include initrd Blob 'initrd'"
printf "\n\t-v ==> set kernel version to 'version'"
printf "\n\t-k ==> include kernel image 'kernel'"
printf "\n\t-D ==> human friendly Device Tree Blob 'name'"
@ -37,10 +38,11 @@ usage() {
FDTNUM=1
ROOTFSNUM=1
INITRDNUM=1
HASH=sha1
LOADABLES=
while getopts ":A:a:c:C:D:d:e:f:k:n:o:v:r:S" OPTION
while getopts ":A:a:c:C:D:d:e:f:i:k:n:o:v:r:S" OPTION
do
case $OPTION in
A ) ARCH=$OPTARG;;
@ -51,6 +53,7 @@ do
d ) DTB=$OPTARG;;
e ) ENTRY_ADDR=$OPTARG;;
f ) COMPATIBLE=$OPTARG;;
i ) INITRD=$OPTARG;;
k ) KERNEL=$OPTARG;;
n ) FDTNUM=$OPTARG;;
o ) OUTPUT=$OPTARG;;
@ -96,6 +99,27 @@ if [ -n "${DTB}" ]; then
FDT_PROP="fdt = \"fdt@$FDTNUM\";"
fi
if [ -n "${INITRD}" ]; then
INITRD_NODE="
initrd@$INITRDNUM {
description = \"${ARCH_UPPER} OpenWrt ${DEVICE} initrd\";
${COMPATIBLE_PROP}
data = /incbin/(\"${INITRD}\");
type = \"ramdisk\";
arch = \"${ARCH}\";
os = \"linux\";
hash@1 {
algo = \"crc32\";
};
hash@2 {
algo = \"${HASH}\";
};
};
"
INITRD_PROP="ramdisk=\"initrd@${INITRDNUM}\";"
fi
if [ -n "${ROOTFS}" ]; then
dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync
ROOTFS_NODE="
@ -141,6 +165,7 @@ DATA="/dts-v1/;
algo = \"$HASH\";
};
};
${INITRD_NODE}
${FDT_NODE}
${ROOTFS_NODE}
};
@ -153,6 +178,7 @@ ${ROOTFS_NODE}
${FDT_PROP}
${LOADABLES:+loadables = ${LOADABLES};}
${COMPATIBLE_PROP}
${INITRD_PROP}
};
};
};"

View File

@ -33,6 +33,7 @@ sub target_config_features(@) {
/^fpu$/ and $ret .= "\tselect HAS_FPU\n";
/^spe_fpu$/ and $ret .= "\tselect HAS_SPE_FPU\n";
/^ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n";
/^seperate_ramdisk$/ and $ret .= "\tselect USES_INITRAMFS\n\tselect USES_SEPERATE_INITRAMFS\n";
/^powerpc64$/ and $ret .= "\tselect powerpc64\n";
/^nommu$/ and $ret .= "\tselect NOMMU\n";
/^mips16$/ and $ret .= "\tselect HAS_MIPS16\n";

View File

@ -51,6 +51,9 @@ config USES_DEVICETREE
config USES_INITRAMFS
bool
config USES_SEPERATE_INITRAMFS
bool
config USES_SQUASHFS
bool