Add INITRAMFS_SKIP_GZIP option to make initramfs encoding/decoding faster

This commit is contained in:
Ruize Tang 2024-12-15 22:28:02 +08:00 committed by Tate, Hongliang Tian
parent b472737771
commit c4229e3c2f
3 changed files with 59 additions and 12 deletions

View File

@ -112,6 +112,12 @@ ifeq ($(ENABLE_KVM), 1)
CARGO_OSDK_ARGS += --qemu-args="-accel kvm"
endif
# Skip GZIP to make encoding and decoding of initramfs faster
ifeq ($(INITRAMFS_SKIP_GZIP),1)
CARGO_OSDK_INITRAMFS_OPTION := --initramfs=$(realpath test/build/initramfs.cpio)
CARGO_OSDK_ARGS += $(CARGO_OSDK_INITRAMFS_OPTION)
endif
# Pass make variables to all subdirectory makes
export
@ -243,7 +249,7 @@ ktest: initramfs $(CARGO_OSDK)
@# Exclude linux-bzimage-setup from ktest since it's hard to be unit tested
@for dir in $(OSDK_CRATES); do \
[ $$dir = "ostd/libs/linux-bzimage/setup" ] && continue; \
(cd $$dir && OVMF=off cargo osdk test) || exit 1; \
(cd $$dir && OVMF=off cargo osdk test $(CARGO_OSDK_INITRAMFS_OPTION)) || exit 1; \
tail --lines 10 qemu.log | grep -q "^\\[ktest runner\\] All crates tested." \
|| (echo "Test failed" && exit 1); \
done

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
use core2::io::{Cursor, Read};
use cpio_decoder::{CpioDecoder, FileType};
use lending_iterator::LendingIterator;
use libflate::gzip::Decoder as GZipDecoder;
@ -14,17 +15,47 @@ use super::{
};
use crate::{fs::path::is_dot, prelude::*};
struct BoxedReader<'a>(Box<dyn Read + 'a>);
impl<'a> BoxedReader<'a> {
pub fn new(reader: Box<dyn Read + 'a>) -> Self {
BoxedReader(reader)
}
}
impl Read for BoxedReader<'_> {
fn read(&mut self, buf: &mut [u8]) -> core2::io::Result<usize> {
self.0.read(buf)
}
}
/// Unpack and prepare the rootfs from the initramfs CPIO buffer.
pub fn init(initramfs_buf: &[u8]) -> Result<()> {
init_root_mount();
procfs::init();
println!("[kernel] unpacking the initramfs.cpio.gz to rootfs ...");
let reader = {
let mut initramfs_suffix = "";
let reader = match &initramfs_buf[..4] {
// Gzip magic number: 0x1F 0x8B
&[0x1F, 0x8B, _, _] => {
initramfs_suffix = ".gz";
let gzip_decoder = GZipDecoder::new(initramfs_buf)
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid gzip buffer"))?;
BoxedReader::new(Box::new(gzip_decoder))
}
_ => BoxedReader::new(Box::new(Cursor::new(initramfs_buf))),
};
println!(
"[kernel] unpacking the initramfs.cpio{} to rootfs ...",
initramfs_suffix
);
reader
};
let mut decoder = CpioDecoder::new(reader);
let fs = FsResolver::new();
let mut decoder = CpioDecoder::new(
GZipDecoder::new(initramfs_buf)
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid gzip buffer"))?,
);
loop {
let Some(entry_result) = decoder.next() else {

View File

@ -9,7 +9,12 @@ ATOMIC_WGET := $(CUR_DIR)/../tools/atomic_wget.sh
BUILD_DIR := $(CUR_DIR)/build
INITRAMFS := $(BUILD_DIR)/initramfs
INITRAMFS_FILELIST := $(BUILD_DIR)/initramfs.filelist
INITRAMFS_SKIP_GZIP ?= 0
ifeq ($(INITRAMFS_SKIP_GZIP),1)
INITRAMFS_IMAGE := $(BUILD_DIR)/initramfs.cpio
else
INITRAMFS_IMAGE := $(BUILD_DIR)/initramfs.cpio.gz
endif
EXT2_IMAGE := $(BUILD_DIR)/ext2.img
EXFAT_IMAGE := $(BUILD_DIR)/exfat.img
INITRAMFS_EMPTY_DIRS := \
@ -107,7 +112,7 @@ $(INITRAMFS)/usr/local:
.PHONY: $(INITRAMFS)/test
$(INITRAMFS)/test:
@make --no-print-directory -C apps
@$(MAKE) --no-print-directory -C apps
$(INITRAMFS)/benchmark: | $(INITRAMFS)/benchmark/bin
@cp -rf $(CUR_DIR)/benchmark/* $@
@ -134,11 +139,11 @@ $(INITRAMFS_EMPTY_DIRS):
.PHONY: $(SYSCALL_TEST_DIR)
$(SYSCALL_TEST_DIR):
@make --no-print-directory -C syscall_test
@$(MAKE) --no-print-directory -C syscall_test
.PHONY: $(INITRAMFS_IMAGE)
$(INITRAMFS_IMAGE): $(INITRAMFS_FILELIST)
@if ! cmp -s $(INITRAMFS_FILELIST) $(INITRAMFS_FILELIST).previous ; then \
@if ! cmp -s $(INITRAMFS_FILELIST) $(INITRAMFS_FILELIST).previous || ! test -f $@; then \
echo "Generating the initramfs image..."; \
cp -f $(INITRAMFS_FILELIST) $(INITRAMFS_FILELIST).previous; \
( \
@ -148,7 +153,12 @@ $(INITRAMFS_IMAGE): $(INITRAMFS_FILELIST)
# `$(INITRAMFS)` in the second column. This prunes the first \
# column and passes the second column to `cpio`. \
cut -d " " -f 2- $(INITRAMFS_FILELIST) | \
cpio -o -H newc | gzip \
cpio -o -H newc | \
if [ "$(INITRAMFS_SKIP_GZIP)" != 1 ]; then \
gzip; \
else \
cat; \
fi \
) > $@; \
fi
@ -175,11 +185,11 @@ build: $(INITRAMFS_IMAGE) $(EXT2_IMAGE) $(EXFAT_IMAGE)
.PHONY: format
format:
@make --no-print-directory -C apps format
@$(MAKE) --no-print-directory -C apps format
.PHONY: check
check:
@make --no-print-directory -C apps check
@$(MAKE) --no-print-directory -C apps check
.PHONY: clean
clean: