1
0
Fork 0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-05-03 22:29:06 +02:00

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" bool "lzma"
config TARGET_INITRAMFS_COMPRESSION_LZO config TARGET_INITRAMFS_COMPRESSION_LZO
depends on !TARGET_ROOTFS_INITRAMFS_SEPERATE
bool "lzo" bool "lzo"
config TARGET_INITRAMFS_COMPRESSION_LZ4 config TARGET_INITRAMFS_COMPRESSION_LZ4
depends on !TARGET_ROOTFS_INITRAMFS_SEPERATE
bool "lz4" bool "lz4"
config TARGET_INITRAMFS_COMPRESSION_XZ config TARGET_INITRAMFS_COMPRESSION_XZ
@ -56,11 +58,20 @@ menu "Target Images"
Kernel uses specified external cpio as INITRAMFS_SOURCE. Kernel uses specified external cpio as INITRAMFS_SOURCE.
config TARGET_INITRAMFS_FORCE config TARGET_INITRAMFS_FORCE
bool "Force" bool "Force"
depends on TARGET_ROOTFS_INITRAMFS depends on TARGET_ROOTFS_INITRAMFS
default n default n
help help
Ignore the initramfs passed by the bootloader. 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" comment "Root filesystem archives"

View File

@ -196,11 +196,22 @@ define Build/eva-image
mv $@.new $@ mv $@.new $@
endef 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 define Build/fit
$(TOPDIR)/scripts/mkits.sh \ $(TOPDIR)/scripts/mkits.sh \
-D $(DEVICE_NAME) -o $@.its -k $@ \ -D $(DEVICE_NAME) -o $@.its -k $@ \
$(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \ $(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-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)) \ -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
$(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \ $(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \
-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \ -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
@ -450,6 +461,22 @@ define Build/uImage
mv $@.new $@ mv $@.new $@
endef 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 define Build/xor-image
$(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1) $(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1)
mv $@.xor $@ mv $@.xor $@

View File

@ -48,6 +48,13 @@ else
endif endif
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) 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)),"") ifeq ($(strip $(CONFIG_EXTERNAL_CPIO)),"")
define Kernel/SetInitramfs/PreConfigure define Kernel/SetInitramfs/PreConfigure
grep -v -e INITRAMFS -e CONFIG_RD_ -e CONFIG_BLK_DEV_INITRD $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config 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 echo 'CONFIG_INITRAMFS_SOURCE="$(call qstrip,$(CONFIG_EXTERNAL_CPIO))"' >> $(LINUX_DIR)/.config
endef endef
endif endif
endif
define Kernel/SetInitramfs define Kernel/SetInitramfs
rm -f $(LINUX_DIR)/.config.prev rm -f $(LINUX_DIR)/.config.prev
mv $(LINUX_DIR)/.config $(LINUX_DIR)/.config.old mv $(LINUX_DIR)/.config $(LINUX_DIR)/.config.old
$(call Kernel/SetInitramfs/PreConfigure) $(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_UID=$(shell id -u)' >> $(LINUX_DIR)/.config
echo 'CONFIG_INITRAMFS_ROOT_GID=$(shell id -g)' >> $(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 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 "$(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_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 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 $(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(TARGET_DIR)/init
$(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(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* 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) +$(KERNEL_MAKE) $(KERNEL_MAKEOPTS_IMAGE) $(if $(KERNELNAME),$(KERNELNAME),all)
$(call Kernel/CopyImage,-initramfs) $(call Kernel/CopyImage,-initramfs)
endef endef

View File

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

View File

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

View File

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