diff --git a/Cargo.lock b/Cargo.lock index 79dc2328d..e2a10dcbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,7 +170,7 @@ dependencies = [ "core2", "cpio-decoder", "getset", - "hashbrown 0.14.3", + "hashbrown", "id-alloc", "inherit-methods-macro", "int-to-c-enum", @@ -662,15 +662,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.14.3" @@ -723,7 +714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -832,9 +823,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libflate" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" dependencies = [ "adler32", "core2", @@ -845,12 +836,12 @@ dependencies = [ [[package]] name = "libflate_lz77" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" dependencies = [ "core2", - "hashbrown 0.13.2", + "hashbrown", "rle-decode-fast", ] @@ -864,6 +855,7 @@ version = "0.1.0" dependencies = [ "bitflags 1.3.2", "bytemuck", + "libflate", "serde", "xmas-elf 0.9.1", ] @@ -874,6 +866,8 @@ version = "0.1.0" dependencies = [ "bitflags 2.4.1", "cfg-if", + "core2", + "libflate", "linux-boot-params", "log", "uart_16550", @@ -905,7 +899,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -1353,9 +1347,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -1521,9 +1515,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] diff --git a/Makefile b/Makefile index 8b87b5d77..256194a16 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,7 @@ endif ifeq ($(BOOT_PROTOCOL), linux-efi-handover64) CARGO_OSDK_ARGS += --grub-mkrescue=/usr/bin/grub-mkrescue CARGO_OSDK_ARGS += --grub-boot-protocol="linux" +CARGO_OSDK_ARGS += --encoding gzip else ifeq ($(BOOT_PROTOCOL), linux-legacy32) CARGO_OSDK_ARGS += --linux-x86-legacy-boot CARGO_OSDK_ARGS += --grub-boot-protocol="linux" diff --git a/osdk/Cargo.lock b/osdk/Cargo.lock index b3c262f08..6aa20461e 100644 --- a/osdk/Cargo.lock +++ b/osdk/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -11,6 +29,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anstream" version = "0.6.12" @@ -194,6 +218,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -203,6 +236,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -213,6 +255,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + [[package]] name = "difflib" version = "0.4.0" @@ -279,6 +327,10 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "heck" @@ -320,12 +372,37 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libflate" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" +dependencies = [ + "core2", + "hashbrown", + "rle-decode-fast", +] + [[package]] name = "linux-bzimage-builder" version = "0.1.0" dependencies = [ "bitflags", "bytemuck", + "libflate", "serde", "xmas-elf", ] @@ -342,6 +419,12 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "predicates" version = "3.1.0" @@ -425,6 +508,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "ryu" version = "1.0.17" @@ -464,9 +553,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -513,9 +602,9 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "toml" -version = "0.8.10" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" dependencies = [ "indexmap", "serde", @@ -526,18 +615,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.22.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" dependencies = [ "indexmap", "serde", @@ -668,3 +757,23 @@ name = "zero" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fe21bcc34ca7fe6dd56cc2cb1261ea59d6b93620215aefb5ea6032265527784" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/osdk/src/cli.rs b/osdk/src/cli.rs index 2514f4f8e..33e29b80d 100644 --- a/osdk/src/cli.rs +++ b/osdk/src/cli.rs @@ -17,6 +17,8 @@ use crate::{ }, }; +use linux_bzimage_builder::PayloadEncoding; + pub fn main() { let load_config = |common_args: &CommonArgs| { let manifest = TomlManifest::load(); @@ -358,4 +360,11 @@ pub struct CommonArgs { global = true )] pub qemu_args: Vec, + #[arg( + long = "encoding", + help = "Denote the encoding format for kernel self-decompression", + value_name = "FORMAT", + global = true + )] + pub encoding: Option, } diff --git a/osdk/src/commands/build/bin.rs b/osdk/src/commands/build/bin.rs index 6e6991fac..10d907307 100644 --- a/osdk/src/commands/build/bin.rs +++ b/osdk/src/commands/build/bin.rs @@ -7,7 +7,9 @@ use std::{ process::Command, }; -use linux_bzimage_builder::{legacy32_rust_target_json, make_bzimage, BzImageType}; +use linux_bzimage_builder::{ + legacy32_rust_target_json, make_bzimage, BzImageType, PayloadEncoding, +}; use crate::{ arch::Arch, @@ -23,6 +25,7 @@ pub fn make_install_bzimage( target_dir: impl AsRef, aster_elf: &AsterBin, linux_x86_legacy_boot: bool, + encoding: PayloadEncoding, ) -> AsterBin { let target_name = get_current_crate_info().name; let image_type = if linux_x86_legacy_boot { @@ -55,7 +58,13 @@ pub fn make_install_bzimage( let install_path = install_dir.as_ref().join(target_name); info!("Building bzImage"); println!("install_path: {:?}", install_path); - make_bzimage(&install_path, image_type, aster_elf.path(), &setup_bin); + make_bzimage( + &install_path, + image_type, + aster_elf.path(), + &setup_bin, + encoding, + ); AsterBin::new( &install_path, @@ -162,6 +171,10 @@ fn install_setup_with_arch( cmd.arg("install").arg("linux-bzimage-setup"); cmd.arg("--force"); cmd.arg("--root").arg(install_dir.as_ref()); + if std::env::var("AUTO_TEST").is_ok() || std::env::var("OSDK_INTEGRATION_TEST").is_ok() { + cmd.arg("--path") + .arg("../../../ostd/libs/linux-bzimage/setup"); + } // Remember to upgrade this version if new version of linux-bzimage-setup is released. const LINUX_BZIMAGE_SETUP_VERSION: &str = "0.1.0"; cmd.arg("--version").arg(LINUX_BZIMAGE_SETUP_VERSION); diff --git a/osdk/src/commands/build/grub.rs b/osdk/src/commands/build/grub.rs index fd9594497..96edb0ec3 100644 --- a/osdk/src/commands/build/grub.rs +++ b/osdk/src/commands/build/grub.rs @@ -57,6 +57,7 @@ pub fn create_bootdev_image( &target_dir, aster_bin, action.build.linux_x86_legacy_boot, + config.build.encoding.clone(), ); } _ => { diff --git a/osdk/src/config/mod.rs b/osdk/src/config/mod.rs index dea0b64fa..8cf8f4800 100644 --- a/osdk/src/config/mod.rs +++ b/osdk/src/config/mod.rs @@ -16,7 +16,10 @@ mod test; use std::{env, path::PathBuf}; -use scheme::{Action, ActionScheme, BootScheme, Build, GrubScheme, QemuScheme, Scheme}; +use linux_bzimage_builder::PayloadEncoding; +use scheme::{ + Action, ActionScheme, BootProtocol, BootScheme, Build, GrubScheme, QemuScheme, Scheme, +}; use crate::{ arch::{get_default_arch, Arch}, @@ -88,6 +91,11 @@ fn apply_args_after_finalize(action: &mut Action, args: &CommonArgs) { impl Config { pub fn new(scheme: &Scheme, common_args: &CommonArgs) -> Self { + let check_compatibility = |protocol: BootProtocol, encoding: PayloadEncoding| { + if protocol != BootProtocol::Linux && encoding != PayloadEncoding::Raw { + panic!("The encoding format is not allowed to be specified if the boot protocol is not {:#?}", BootProtocol::Linux); + } + }; let target_arch = common_args.target_arch.unwrap_or(get_default_arch()); let default_scheme = ActionScheme { boot: scheme.boot.clone(), @@ -95,12 +103,18 @@ impl Config { qemu: scheme.qemu.clone(), build: scheme.build.clone(), }; + let build = { + let mut build = scheme.build.clone().unwrap_or_default().finalize(); + build.apply_common_args(common_args); + build + }; let run = { let mut run = scheme.run.clone().unwrap_or_default(); run.inherit(&default_scheme); apply_args_before_finalize(&mut run, common_args); let mut run = run.finalize(target_arch); apply_args_after_finalize(&mut run, common_args); + check_compatibility(run.grub.boot_protocol, run.build.encoding.clone()); run }; let test = { @@ -109,6 +123,7 @@ impl Config { apply_args_before_finalize(&mut test, common_args); let mut test = test.finalize(target_arch); apply_args_after_finalize(&mut test, common_args); + check_compatibility(test.grub.boot_protocol, test.build.encoding.clone()); test }; Self { @@ -117,7 +132,7 @@ impl Config { .clone() .unwrap_or_else(|| env::current_dir().unwrap()), target_arch, - build: scheme.build.clone().unwrap_or_default().finalize(), + build, run, test, } diff --git a/osdk/src/config/scheme/action.rs b/osdk/src/config/scheme/action.rs index efd9e7ab1..2c05c74bf 100644 --- a/osdk/src/config/scheme/action.rs +++ b/osdk/src/config/scheme/action.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 +use linux_bzimage_builder::PayloadEncoding; + use super::{inherit_optional, Boot, BootScheme, Grub, GrubScheme, Qemu, QemuScheme}; use crate::{cli::CommonArgs, config::Arch}; @@ -23,6 +25,7 @@ pub struct BuildScheme { pub linux_x86_legacy_boot: bool, #[serde(default)] pub strip_elf: bool, + pub encoding: Option, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -38,6 +41,7 @@ pub struct Build { pub linux_x86_legacy_boot: bool, #[serde(default)] pub strip_elf: bool, + pub encoding: PayloadEncoding, } impl Default for Build { @@ -49,6 +53,7 @@ impl Default for Build { override_configs: Vec::new(), linux_x86_legacy_boot: false, strip_elf: false, + encoding: PayloadEncoding::default(), } } } @@ -71,6 +76,9 @@ impl Build { if common_args.strip_elf { self.strip_elf = true; } + if let Some(encoding) = common_args.encoding.clone() { + self.encoding.clone_from(&encoding); + } } } @@ -91,6 +99,9 @@ impl BuildScheme { if parent.strip_elf { self.strip_elf = true; } + if self.encoding.is_none() { + self.encoding.clone_from(&parent.encoding); + } } pub fn finalize(self) -> Build { @@ -101,6 +112,7 @@ impl BuildScheme { override_configs: Vec::new(), linux_x86_legacy_boot: self.linux_x86_legacy_boot, strip_elf: self.strip_elf, + encoding: self.encoding.unwrap_or_default(), } } } diff --git a/ostd/libs/linux-bzimage/builder/Cargo.toml b/ostd/libs/linux-bzimage/builder/Cargo.toml index 44e7c09b9..42363175b 100644 --- a/ostd/libs/linux-bzimage/builder/Cargo.toml +++ b/ostd/libs/linux-bzimage/builder/Cargo.toml @@ -11,5 +11,6 @@ repository = "https://github.com/asterinas/asterinas" [dependencies] bytemuck = { version = "1.14.0", features = ["derive"] } bitflags = "1.3" +libflate = "2.1.0" serde = { version = "1.0.192", features = ["derive"] } xmas-elf = "0.9.1" diff --git a/ostd/libs/linux-bzimage/builder/src/encoder.rs b/ostd/libs/linux-bzimage/builder/src/encoder.rs new file mode 100644 index 000000000..eaff979a7 --- /dev/null +++ b/ostd/libs/linux-bzimage/builder/src/encoder.rs @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MPL-2.0 + +//! This module is used to compress kernel ELF. + +use std::{ + ffi::{OsStr, OsString}, + io::Write, + str::FromStr, +}; + +use libflate::{gzip, zlib}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum PayloadEncoding { + #[default] + #[serde(rename = "raw")] + Raw, + #[serde(rename = "gzip")] + Gzip, + #[serde(rename = "zlib")] + Zlib, +} + +impl FromStr for PayloadEncoding { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "raw" => Ok(Self::Raw), + "gzip" => Ok(Self::Gzip), + "zlib" => Ok(Self::Zlib), + _ => Err(format!("Invalid encoding format: {}", s)), + } + } +} + +impl From for PayloadEncoding { + fn from(os_string: OsString) -> Self { + PayloadEncoding::from_str(&os_string.to_string_lossy()).unwrap() + } +} + +impl From<&OsStr> for PayloadEncoding { + fn from(os_str: &OsStr) -> Self { + PayloadEncoding::from_str(&os_str.to_string_lossy()).unwrap() + } +} + +/// Encoding the kernel ELF using the provided format. +pub fn encode_kernel(kernel: Vec, encoding: PayloadEncoding) -> Vec { + match encoding { + PayloadEncoding::Raw => kernel, + PayloadEncoding::Gzip => { + let mut encoder = gzip::Encoder::new(Vec::new()).unwrap(); + encoder.write_all(&kernel).unwrap(); + encoder.finish().into_result().unwrap() + } + PayloadEncoding::Zlib => { + let mut encoder = zlib::Encoder::new(Vec::new()).unwrap(); + encoder.write_all(&kernel).unwrap(); + encoder.finish().into_result().unwrap() + } + } +} diff --git a/ostd/libs/linux-bzimage/builder/src/lib.rs b/ostd/libs/linux-bzimage/builder/src/lib.rs index 6d7758d19..90330729c 100644 --- a/ostd/libs/linux-bzimage/builder/src/lib.rs +++ b/ostd/libs/linux-bzimage/builder/src/lib.rs @@ -13,6 +13,7 @@ //! The setup code should be built into the ELF target and we convert it to a flat binary //! in the builder. +pub mod encoder; mod mapping; mod pe_header; @@ -22,6 +23,8 @@ use std::{ path::Path, }; +use encoder::encode_kernel; +pub use encoder::PayloadEncoding; use mapping::{SetupFileOffset, SetupVA}; use xmas_elf::program::SegmentData; @@ -39,13 +42,15 @@ pub enum BzImageType { /// - `target_image_path`: The path to the target bzImage; /// - `image_type`: The type of the bzImage that we are building; /// - `kernel_path`: The path to the kernel ELF; -/// - `setup_elf_path`: The path to the setup ELF. +/// - `setup_elf_path`: The path to the setup ELF; +/// - `encoding`: The encoding format for compressing the kernel ELF. /// pub fn make_bzimage( target_image_path: &Path, image_type: BzImageType, kernel_path: &Path, setup_elf_path: &Path, + encoding: PayloadEncoding, ) { let mut setup_elf = Vec::new(); File::open(setup_elf_path) @@ -61,7 +66,10 @@ pub fn make_bzimage( .unwrap() .read_to_end(&mut kernel) .unwrap(); - let payload = kernel; + let payload = match image_type { + BzImageType::Legacy32 => kernel, + BzImageType::Efi64 => encode_kernel(kernel, encoding), + }; let setup_len = setup.len(); let payload_len = payload.len(); diff --git a/ostd/libs/linux-bzimage/setup/Cargo.toml b/ostd/libs/linux-bzimage/setup/Cargo.toml index 621829afb..b572eddf6 100644 --- a/ostd/libs/linux-bzimage/setup/Cargo.toml +++ b/ostd/libs/linux-bzimage/setup/Cargo.toml @@ -14,6 +14,8 @@ path = "src/main.rs" [dependencies] cfg-if = "1.0.0" +core2 = { version = "0.4.0", default-features = false, features = ["nightly"] } +libflate = { version = "2.1.0", default-features = false } linux-boot-params = { path = "../boot-params", version = "0.1.0" } uart_16550 = "0.3.0" xmas-elf = "0.8.0" diff --git a/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/decoder.rs b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/decoder.rs new file mode 100644 index 000000000..0b90cf5b5 --- /dev/null +++ b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/decoder.rs @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MPL-2.0 + +//! This module is used to decompress payload. + +extern crate alloc; + +pub use alloc::vec::Vec; +use core::convert::TryFrom; + +use core2::io::Read; +use libflate::{gzip, zlib}; + +enum MagicNumber { + Elf, + Gzip, + Zlib, +} + +impl TryFrom<&[u8]> for MagicNumber { + type Error = &'static str; + + fn try_from(slice: &[u8]) -> Result { + match *slice { + [0x7F, 0x45, 0x4C, 0x46, ..] => Ok(Self::Elf), + [0x1F, 0x8B, ..] => Ok(Self::Gzip), + [0x78, 0x9C, ..] => Ok(Self::Zlib), + _ => Err("Unsupported payload type"), + } + } +} + +/// Checking the encoding format and matching decoding methods to decode payload. +pub fn decode_payload(payload: &[u8]) -> Vec { + let mut kernel = Vec::new(); + let magic = MagicNumber::try_from(payload).unwrap(); + match magic { + MagicNumber::Elf => { + kernel = payload.to_vec(); + } + MagicNumber::Gzip => { + let mut decoder = gzip::Decoder::new(payload).unwrap(); + decoder.read_to_end(&mut kernel).unwrap(); + } + MagicNumber::Zlib => { + let mut decoder = zlib::Decoder::new(payload).unwrap(); + decoder.read_to_end(&mut kernel).unwrap(); + } + } + kernel +} diff --git a/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/efi.rs b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/efi.rs index f8d76464e..9e47476f5 100644 --- a/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/efi.rs +++ b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/efi.rs @@ -8,6 +8,7 @@ use uefi::{ }; use super::{ + decoder::decode_payload, paging::{Ia32eFlags, PageNumber, PageTableCreator}, relocation::apply_rela_dyn_relocations, }; @@ -55,9 +56,11 @@ fn efi_phase_boot( uefi_services::println!("[EFI stub] Relocations applied."); - uefi_services::println!("[EFI stub] Loading payload."); let payload = unsafe { crate::get_payload(&*boot_params_ptr) }; - crate::loader::load_elf(payload); + let kernel = decode_payload(payload); + + uefi_services::println!("[EFI stub] Loading payload."); + crate::loader::load_elf(&kernel); uefi_services::println!("[EFI stub] Exiting EFI boot services."); let memory_type = { diff --git a/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/mod.rs b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/mod.rs index d4662166a..7620e1b50 100644 --- a/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/mod.rs +++ b/ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/mod.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 +mod decoder; mod efi; mod paging; mod relocation;