aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2021-02-21 14:19:26 +0000
committerDaniel Golle <daniel@makrotopia.org>2021-02-24 01:35:20 +0000
commit330bd380e8b691833c8dcc9b579b51851cbd4b0f (patch)
treea6e6859d1888644af99fe332eef67eead435aa9c
parente6aac8d98f5663be99163f9e61dad23ad657b7ed (diff)
downloadupstream-330bd380e8b691833c8dcc9b579b51851cbd4b0f.tar.gz
upstream-330bd380e8b691833c8dcc9b579b51851cbd4b0f.tar.bz2
upstream-330bd380e8b691833c8dcc9b579b51851cbd4b0f.zip
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>
-rw-r--r--config/Config-images.in21
-rw-r--r--include/image-commands.mk27
-rw-r--r--include/kernel-defaults.mk26
-rwxr-xr-xscripts/mkits.sh28
-rwxr-xr-xscripts/target-metadata.pl1
-rw-r--r--target/Config.in3
6 files changed, 100 insertions, 6 deletions
diff --git a/config/Config-images.in b/config/Config-images.in
index 957d3af18f..080fee2cce 100644
--- a/config/Config-images.in
+++ b/config/Config-images.in
@@ -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
@@ -56,11 +58,20 @@ menu "Target Images"
Kernel uses specified external cpio as INITRAMFS_SOURCE.
config TARGET_INITRAMFS_FORCE
- bool "Force"
- depends on TARGET_ROOTFS_INITRAMFS
- default n
- help
- Ignore the initramfs passed by the bootloader.
+ bool "Force"
+ depends on TARGET_ROOTFS_INITRAMFS
+ default n
+ 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"
diff --git a/include/image-commands.mk b/include/image-commands.mk
index 3377680a07..d4ec51ca7c 100644
--- a/include/image-commands.mk
+++ b/include/image-commands.mk
@@ -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 $@
diff --git a/include/kernel-defaults.mk b/include/kernel-defaults.mk
index 8293956f6b..4b39296f8c 100644
--- a/include/kernel-defaults.mk
+++ b/include/kernel-defaults.mk
@@ -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
diff --git a/scripts/mkits.sh b/scripts/mkits.sh
index 59ff3a2d15..ecaba8e965 100755
--- a/scripts/mkits.sh
+++ b/scripts/mkits.sh
@@ -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}
};
};
};"
diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl
index 78f77b16d5..4128d54461 100755
--- a/scripts/target-metadata.pl
+++ b/scripts/target-metadata.pl
@@ -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";
diff --git a/target/Config.in b/target/Config.in
index 43de4710df..9dbc5ffe46 100644
--- a/target/Config.in
+++ b/target/Config.in
@@ -51,6 +51,9 @@ config USES_DEVICETREE
config USES_INITRAMFS
bool
+config USES_SEPERATE_INITRAMFS
+ bool
+
config USES_SQUASHFS
bool