mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 10:53:25 +00:00
Utilize libflate crate to compress and decompress payload
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
930b0d208d
commit
6752baf166
@ -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"
|
||||
|
65
ostd/libs/linux-bzimage/builder/src/encoder.rs
Normal file
65
ostd/libs/linux-bzimage/builder/src/encoder.rs
Normal file
@ -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<Self, Self::Err> {
|
||||
match s {
|
||||
"raw" => Ok(Self::Raw),
|
||||
"gzip" => Ok(Self::Gzip),
|
||||
"zlib" => Ok(Self::Zlib),
|
||||
_ => Err(format!("Invalid encoding format: {}", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OsString> 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<u8>, encoding: PayloadEncoding) -> Vec<u8> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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"
|
||||
|
50
ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/decoder.rs
Normal file
50
ostd/libs/linux-bzimage/setup/src/x86/amd64_efi/decoder.rs
Normal file
@ -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<Self, Self::Error> {
|
||||
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<u8> {
|
||||
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
|
||||
}
|
@ -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 = {
|
||||
|
@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
mod decoder;
|
||||
mod efi;
|
||||
mod paging;
|
||||
mod relocation;
|
||||
|
Reference in New Issue
Block a user