mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-25 10:23:23 +00:00
Rename boot-wrapper to bzimage-setup
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
1cc6116790
commit
327e991477
56
Cargo.lock
generated
56
Cargo.lock
generated
@ -129,31 +129,6 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster-boot-wrapper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"linux_boot_params",
|
||||
"log",
|
||||
"uart_16550",
|
||||
"uefi",
|
||||
"uefi-services",
|
||||
"x86_64",
|
||||
"xmas-elf 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster-boot-wrapper-builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
"serde",
|
||||
"xmas-elf 0.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster-console"
|
||||
version = "0.1.0"
|
||||
@ -184,7 +159,7 @@ dependencies = [
|
||||
"intrusive-collections",
|
||||
"ktest",
|
||||
"lazy_static",
|
||||
"linux_boot_params",
|
||||
"linux-boot-params",
|
||||
"log",
|
||||
"multiboot2",
|
||||
"pod",
|
||||
@ -268,8 +243,8 @@ name = "aster-runner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"aster-boot-wrapper-builder",
|
||||
"clap",
|
||||
"linux-bzimage-builder",
|
||||
"rand",
|
||||
"xmas-elf 0.8.0",
|
||||
]
|
||||
@ -975,9 +950,34 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux_boot_params"
|
||||
name = "linux-boot-params"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "linux-bzimage-builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
"serde",
|
||||
"xmas-elf 0.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-bzimage-setup"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"linux-boot-params",
|
||||
"log",
|
||||
"uart_16550",
|
||||
"uefi",
|
||||
"uefi-services",
|
||||
"x86_64",
|
||||
"xmas-elf 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
|
@ -35,9 +35,9 @@ members = [
|
||||
"runner",
|
||||
"framework/aster-frame",
|
||||
"framework/libs/align_ext",
|
||||
"framework/libs/boot-wrapper/builder",
|
||||
"framework/libs/boot-wrapper/linux-boot-params",
|
||||
"framework/libs/boot-wrapper/wrapper",
|
||||
"framework/libs/linux-bzimage/builder",
|
||||
"framework/libs/linux-bzimage/boot-params",
|
||||
"framework/libs/linux-bzimage/setup",
|
||||
"framework/libs/ktest",
|
||||
"framework/libs/tdx-guest",
|
||||
"services/comps/block",
|
||||
|
4
Makefile
4
Makefile
@ -85,8 +85,8 @@ export CARGO := cargo
|
||||
USERMODE_TESTABLE := \
|
||||
runner \
|
||||
framework/libs/align_ext \
|
||||
framework/libs/boot-wrapper/builder \
|
||||
framework/libs/boot-wrapper/linux-boot-params \
|
||||
framework/libs/linux-bzimage/builder \
|
||||
framework/libs/linux-bzimage/boot-params \
|
||||
framework/libs/ktest \
|
||||
framework/libs/ktest-proc-macro \
|
||||
services/libs/cpio-decoder \
|
||||
|
@ -10,7 +10,7 @@ align_ext = { path = "../libs/align_ext" }
|
||||
bit_field = "0.10.1"
|
||||
bitflags = "1.3"
|
||||
bitvec = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||
linux_boot_params = { path = "../libs/boot-wrapper/linux-boot-params" }
|
||||
linux-boot-params = { path = "../libs/linux-bzimage/boot-params" }
|
||||
buddy_system_allocator = "0.9.0"
|
||||
cfg-if = "1.0"
|
||||
gimli = { version = "0.28", default-features = false, features = ["read-core"] }
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "linux_boot_params"
|
||||
name = "linux-boot-params"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "aster-boot-wrapper-builder"
|
||||
name = "linux-bzimage-builder"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
@ -1,13 +1,14 @@
|
||||
//! The linux boot wrapper builder.
|
||||
//! The linux bzImage builder.
|
||||
//!
|
||||
//! This crate is responsible for building the bzImage. It contains methods to build
|
||||
//! the wrapper binary and methods to build the bzImage.
|
||||
//! the setup binary (with source provided in another crate) and methods to build the
|
||||
//! bzImage from the setup binary and the kernel ELF.
|
||||
//!
|
||||
//! We should build the asterinas kernel as a ELF file, and feed it to the builder to
|
||||
//! generate the bzImage. The builder will generate the PE/COFF header for the wrapper
|
||||
//! and concatenate it to the ELF file to make the bzImage.
|
||||
//! We should build the asterinas kernel as an ELF file, and feed it to the builder to
|
||||
//! generate the bzImage. The builder will generate the PE/COFF header for the setup
|
||||
//! code and concatenate it to the ELF file to make the bzImage.
|
||||
//!
|
||||
//! The wrapper should be built into the ELF target and we convert it to a flat binary
|
||||
//! The setup code should be built into the ELF target and we convert it to a flat binary
|
||||
//! in the builder.
|
||||
|
||||
mod mapping;
|
||||
@ -21,15 +22,15 @@ use std::{
|
||||
|
||||
use xmas_elf::program::SegmentData;
|
||||
|
||||
use mapping::{WrapperFileOffset, WrapperVA};
|
||||
use mapping::{SetupFileOffset, SetupVA};
|
||||
|
||||
/// We need a flat binary which satisfies PA delta == File delta, and objcopy
|
||||
/// does not satisfy us well, so we should parse the ELF and do our own
|
||||
/// objcopy job.
|
||||
/// We need a flat binary which satisfies PA delta == File offset delta,
|
||||
/// and objcopy does not satisfy us well, so we should parse the ELF and
|
||||
/// do our own objcopy job.
|
||||
///
|
||||
/// Interstingly, the resulting binary should be the same as the memory
|
||||
/// dump of the kernel setup header when it's loaded by the bootloader.
|
||||
fn wrapper_to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
|
||||
fn to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
|
||||
let elf = xmas_elf::ElfFile::new(&elf_file).unwrap();
|
||||
let mut bin = Vec::<u8>::new();
|
||||
|
||||
@ -38,7 +39,7 @@ fn wrapper_to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
|
||||
let SegmentData::Undefined(header_data) = program.get_data(&elf).unwrap() else {
|
||||
panic!("Unexpected segment data type");
|
||||
};
|
||||
let dst_file_offset = usize::from(WrapperFileOffset::from(WrapperVA::from(
|
||||
let dst_file_offset = usize::from(SetupFileOffset::from(SetupVA::from(
|
||||
program.virtual_addr() as usize,
|
||||
)));
|
||||
let dst_file_length = program.file_size() as usize;
|
||||
@ -72,8 +73,8 @@ fn fill_header_field(header: &mut [u8], offset: usize, value: &[u8]) {
|
||||
fn fill_legacy_header_fields(
|
||||
header: &mut [u8],
|
||||
kernel_len: usize,
|
||||
wrapper_len: usize,
|
||||
payload_offset: WrapperVA,
|
||||
setup_len: usize,
|
||||
payload_offset: SetupVA,
|
||||
) {
|
||||
fill_header_field(
|
||||
header,
|
||||
@ -90,7 +91,7 @@ fn fill_legacy_header_fields(
|
||||
fill_header_field(
|
||||
header,
|
||||
0x260, /* init_size */
|
||||
&((wrapper_len + kernel_len) as u32).to_le_bytes(),
|
||||
&((setup_len + kernel_len) as u32).to_le_bytes(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -106,30 +107,28 @@ pub fn make_bzimage(
|
||||
image_path: &Path,
|
||||
kernel_path: &Path,
|
||||
image_type: BzImageType,
|
||||
wrapper_src: &Path,
|
||||
wrapper_out: &Path,
|
||||
setup_src: &Path,
|
||||
setup_out: &Path,
|
||||
) {
|
||||
let wrapper = match image_type {
|
||||
let setup = match image_type {
|
||||
BzImageType::Legacy32 => {
|
||||
let arch = wrapper_src
|
||||
let arch = setup_src
|
||||
.join("x86_64-i386_pm-none.json")
|
||||
.canonicalize()
|
||||
.unwrap();
|
||||
build_wrapper_with_arch(wrapper_src, wrapper_out, &WrapperBuildArch::Other(arch))
|
||||
}
|
||||
BzImageType::Efi64 => {
|
||||
build_wrapper_with_arch(wrapper_src, wrapper_out, &WrapperBuildArch::X86_64)
|
||||
build_setup_with_arch(setup_src, setup_out, &SetupBuildArch::Other(arch))
|
||||
}
|
||||
BzImageType::Efi64 => build_setup_with_arch(setup_src, setup_out, &SetupBuildArch::X86_64),
|
||||
};
|
||||
|
||||
let mut wrapper_elf = Vec::new();
|
||||
File::open(wrapper)
|
||||
let mut setup_elf = Vec::new();
|
||||
File::open(setup)
|
||||
.unwrap()
|
||||
.read_to_end(&mut wrapper_elf)
|
||||
.read_to_end(&mut setup_elf)
|
||||
.unwrap();
|
||||
let mut wrapper = wrapper_to_flat_binary(&wrapper_elf);
|
||||
let mut setup = to_flat_binary(&setup_elf);
|
||||
// Pad the header with 8-byte alignment.
|
||||
wrapper.resize((wrapper.len() + 7) & !7, 0x00);
|
||||
setup.resize((setup.len() + 7) & !7, 0x00);
|
||||
|
||||
let mut kernel = Vec::new();
|
||||
File::open(kernel_path)
|
||||
@ -138,27 +137,22 @@ pub fn make_bzimage(
|
||||
.unwrap();
|
||||
let payload = kernel;
|
||||
|
||||
let wrapper_len = wrapper.len();
|
||||
let setup_len = setup.len();
|
||||
let payload_len = payload.len();
|
||||
let payload_offset = WrapperFileOffset::from(wrapper_len);
|
||||
fill_legacy_header_fields(
|
||||
&mut wrapper,
|
||||
payload_len,
|
||||
wrapper_len,
|
||||
payload_offset.into(),
|
||||
);
|
||||
let payload_offset = SetupFileOffset::from(setup_len);
|
||||
fill_legacy_header_fields(&mut setup, payload_len, setup_len, payload_offset.into());
|
||||
|
||||
let mut kernel_image = File::create(image_path).unwrap();
|
||||
kernel_image.write_all(&wrapper).unwrap();
|
||||
kernel_image.write_all(&setup).unwrap();
|
||||
kernel_image.write_all(&payload).unwrap();
|
||||
|
||||
let image_size = wrapper_len + payload_len;
|
||||
let image_size = setup_len + payload_len;
|
||||
|
||||
if matches!(image_type, BzImageType::Efi64) {
|
||||
// Write the PE/COFF header to the start of the file.
|
||||
// Since the Linux boot header starts at 0x1f1, we can write the PE/COFF header directly to the
|
||||
// start of the file without overwriting the Linux boot header.
|
||||
let pe_header = pe_header::make_pe_coff_header(&wrapper_elf, image_size);
|
||||
let pe_header = pe_header::make_pe_coff_header(&setup_elf, image_size);
|
||||
assert!(
|
||||
pe_header.header_at_zero.len() <= 0x1f1,
|
||||
"PE/COFF header is too large"
|
||||
@ -173,15 +167,15 @@ pub fn make_bzimage(
|
||||
}
|
||||
}
|
||||
|
||||
enum WrapperBuildArch {
|
||||
enum SetupBuildArch {
|
||||
X86_64,
|
||||
Other(PathBuf),
|
||||
}
|
||||
|
||||
/// Build the wrapper binary.
|
||||
/// Build the setup binary.
|
||||
///
|
||||
/// It will return the path to the built wrapper binary.
|
||||
fn build_wrapper_with_arch(source_dir: &Path, out_dir: &Path, arch: &WrapperBuildArch) -> PathBuf {
|
||||
/// It will return the path to the built setup binary.
|
||||
fn build_setup_with_arch(source_dir: &Path, out_dir: &Path, arch: &SetupBuildArch) -> PathBuf {
|
||||
if !out_dir.exists() {
|
||||
std::fs::create_dir_all(&out_dir).unwrap();
|
||||
}
|
||||
@ -198,10 +192,10 @@ fn build_wrapper_with_arch(source_dir: &Path, out_dir: &Path, arch: &WrapperBuil
|
||||
if profile == "release" {
|
||||
cmd.arg("--release");
|
||||
}
|
||||
cmd.arg("--package").arg("aster-boot-wrapper");
|
||||
cmd.arg("--package").arg("linux-bzimage-setup");
|
||||
cmd.arg("--target").arg(match arch {
|
||||
WrapperBuildArch::X86_64 => "x86_64-unknown-none",
|
||||
WrapperBuildArch::Other(path) => path.to_str().unwrap(),
|
||||
SetupBuildArch::X86_64 => "x86_64-unknown-none",
|
||||
SetupBuildArch::Other(path) => path.to_str().unwrap(),
|
||||
});
|
||||
cmd.arg("-Zbuild-std=core,alloc,compiler_builtins");
|
||||
cmd.arg("-Zbuild-std-features=compiler-builtins-mem");
|
||||
@ -220,16 +214,16 @@ fn build_wrapper_with_arch(source_dir: &Path, out_dir: &Path, arch: &WrapperBuil
|
||||
);
|
||||
}
|
||||
|
||||
// Get the path to the wrapper binary.
|
||||
// Get the path to the setup binary.
|
||||
let arch_name = match arch {
|
||||
WrapperBuildArch::X86_64 => "x86_64-unknown-none",
|
||||
WrapperBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
|
||||
SetupBuildArch::X86_64 => "x86_64-unknown-none",
|
||||
SetupBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
|
||||
};
|
||||
|
||||
let wrapper_artifact = out_dir
|
||||
let setup_artifact = out_dir
|
||||
.join(arch_name)
|
||||
.join(profile)
|
||||
.join("aster-boot-wrapper");
|
||||
.join("linux-bzimage-setup");
|
||||
|
||||
wrapper_artifact.to_owned()
|
||||
setup_artifact.to_owned()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//! In the wrapper, VA - SETUP32_LMA == FileOffset - LEGACY_SETUP_SEC_SIZE.
|
||||
//! In the setup, VA - SETUP32_LMA == FileOffset - LEGACY_SETUP_SEC_SIZE.
|
||||
//! And the addresses are specified in the ELF file.
|
||||
//!
|
||||
//! This module centralizes the conversion between VA and FileOffset.
|
||||
@ -17,28 +17,28 @@ pub const LEGACY_SETUP_SEC_SIZE: usize = 0x200 * (LEGACY_SETUP_SECS + 1);
|
||||
pub const SETUP32_LMA: usize = 0x100000;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||
pub struct WrapperVA {
|
||||
pub struct SetupVA {
|
||||
addr: usize,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||
pub struct WrapperFileOffset {
|
||||
pub struct SetupFileOffset {
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl From<usize> for WrapperVA {
|
||||
impl From<usize> for SetupVA {
|
||||
fn from(addr: usize) -> Self {
|
||||
Self { addr }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WrapperVA> for usize {
|
||||
fn from(va: WrapperVA) -> Self {
|
||||
impl From<SetupVA> for usize {
|
||||
fn from(va: SetupVA) -> Self {
|
||||
va.addr
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for WrapperVA {
|
||||
impl Sub for SetupVA {
|
||||
type Output = usize;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
@ -46,7 +46,7 @@ impl Sub for WrapperVA {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for WrapperVA {
|
||||
impl Add<usize> for SetupVA {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
@ -56,19 +56,19 @@ impl Add<usize> for WrapperVA {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for WrapperFileOffset {
|
||||
impl From<usize> for SetupFileOffset {
|
||||
fn from(offset: usize) -> Self {
|
||||
Self { offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WrapperFileOffset> for usize {
|
||||
fn from(offset: WrapperFileOffset) -> Self {
|
||||
impl From<SetupFileOffset> for usize {
|
||||
fn from(offset: SetupFileOffset) -> Self {
|
||||
offset.offset
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for WrapperFileOffset {
|
||||
impl Sub for SetupFileOffset {
|
||||
type Output = usize;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
@ -76,7 +76,7 @@ impl Sub for WrapperFileOffset {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for WrapperFileOffset {
|
||||
impl Add<usize> for SetupFileOffset {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
@ -86,16 +86,16 @@ impl Add<usize> for WrapperFileOffset {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WrapperVA> for WrapperFileOffset {
|
||||
fn from(va: WrapperVA) -> Self {
|
||||
impl From<SetupVA> for SetupFileOffset {
|
||||
fn from(va: SetupVA) -> Self {
|
||||
Self {
|
||||
offset: va.addr + LEGACY_SETUP_SEC_SIZE - SETUP32_LMA,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WrapperFileOffset> for WrapperVA {
|
||||
fn from(offset: WrapperFileOffset) -> Self {
|
||||
impl From<SetupFileOffset> for SetupVA {
|
||||
fn from(offset: SetupFileOffset) -> Self {
|
||||
Self {
|
||||
addr: offset.offset + SETUP32_LMA - LEGACY_SETUP_SEC_SIZE,
|
||||
}
|
@ -11,7 +11,7 @@ use serde::Serialize;
|
||||
|
||||
use std::{mem::size_of, ops::Range};
|
||||
|
||||
use crate::mapping::{WrapperFileOffset, WrapperVA, LEGACY_SETUP_SEC_SIZE, SETUP32_LMA};
|
||||
use crate::mapping::{SetupFileOffset, SetupVA, LEGACY_SETUP_SEC_SIZE, SETUP32_LMA};
|
||||
|
||||
// The MS-DOS header.
|
||||
const MZ_MAGIC: u16 = 0x5a4d; // "MZ"
|
||||
@ -198,15 +198,15 @@ struct PeSectionHdr {
|
||||
flags: u32,
|
||||
}
|
||||
|
||||
struct TrojanSectionAddrInfo {
|
||||
pub text: Range<WrapperVA>,
|
||||
pub data: Range<WrapperVA>,
|
||||
pub bss: Range<WrapperVA>,
|
||||
struct ImageSectionAddrInfo {
|
||||
pub text: Range<SetupVA>,
|
||||
pub data: Range<SetupVA>,
|
||||
pub bss: Range<SetupVA>,
|
||||
/// All the readonly but loaded sections.
|
||||
pub rodata: Range<WrapperVA>,
|
||||
pub rodata: Range<SetupVA>,
|
||||
}
|
||||
|
||||
impl TrojanSectionAddrInfo {
|
||||
impl ImageSectionAddrInfo {
|
||||
fn from(elf: &xmas_elf::ElfFile) -> Self {
|
||||
let mut text_start = None;
|
||||
let mut text_end = None;
|
||||
@ -218,7 +218,7 @@ impl TrojanSectionAddrInfo {
|
||||
let mut rodata_end = None;
|
||||
for program in elf.program_iter() {
|
||||
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||
let offset = WrapperVA::from(program.virtual_addr() as usize);
|
||||
let offset = SetupVA::from(program.virtual_addr() as usize);
|
||||
let length = program.mem_size() as usize;
|
||||
if program.flags().is_execute() {
|
||||
text_start = Some(offset);
|
||||
@ -236,10 +236,10 @@ impl TrojanSectionAddrInfo {
|
||||
}
|
||||
|
||||
Self {
|
||||
text: WrapperVA::from(text_start.unwrap())..WrapperVA::from(text_end.unwrap()),
|
||||
data: WrapperVA::from(data_start.unwrap())..WrapperVA::from(data_end.unwrap()),
|
||||
bss: WrapperVA::from(bss_start.unwrap())..WrapperVA::from(bss_end.unwrap()),
|
||||
rodata: WrapperVA::from(rodata_start.unwrap())..WrapperVA::from(rodata_end.unwrap()),
|
||||
text: SetupVA::from(text_start.unwrap())..SetupVA::from(text_end.unwrap()),
|
||||
data: SetupVA::from(data_start.unwrap())..SetupVA::from(data_end.unwrap()),
|
||||
bss: SetupVA::from(bss_start.unwrap())..SetupVA::from(bss_end.unwrap()),
|
||||
rodata: SetupVA::from(rodata_start.unwrap())..SetupVA::from(rodata_end.unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ impl TrojanSectionAddrInfo {
|
||||
}
|
||||
|
||||
fn text_file_size(&self) -> usize {
|
||||
WrapperFileOffset::from(self.text.end) - WrapperFileOffset::from(self.text.start)
|
||||
SetupFileOffset::from(self.text.end) - SetupFileOffset::from(self.text.start)
|
||||
}
|
||||
|
||||
fn data_virt_size(&self) -> usize {
|
||||
@ -256,7 +256,7 @@ impl TrojanSectionAddrInfo {
|
||||
}
|
||||
|
||||
fn data_file_size(&self) -> usize {
|
||||
WrapperFileOffset::from(self.data.end) - WrapperFileOffset::from(self.data.start)
|
||||
SetupFileOffset::from(self.data.end) - SetupFileOffset::from(self.data.start)
|
||||
}
|
||||
|
||||
fn bss_virt_size(&self) -> usize {
|
||||
@ -268,23 +268,23 @@ impl TrojanSectionAddrInfo {
|
||||
}
|
||||
|
||||
fn rodata_file_size(&self) -> usize {
|
||||
WrapperFileOffset::from(self.rodata.end) - WrapperFileOffset::from(self.rodata.start)
|
||||
SetupFileOffset::from(self.rodata.end) - SetupFileOffset::from(self.rodata.start)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TrojanPeCoffHeaderBuf {
|
||||
pub struct ImagePeCoffHeaderBuf {
|
||||
pub header_at_zero: Vec<u8>,
|
||||
pub relocs: (WrapperFileOffset, Vec<u8>),
|
||||
pub relocs: (SetupFileOffset, Vec<u8>),
|
||||
}
|
||||
|
||||
pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> TrojanPeCoffHeaderBuf {
|
||||
pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> ImagePeCoffHeaderBuf {
|
||||
let elf = xmas_elf::ElfFile::new(setup_elf).unwrap();
|
||||
let mut bin = Vec::<u8>::new();
|
||||
|
||||
// The EFI application loader requires a relocation section.
|
||||
let relocs = vec![];
|
||||
// The place where we put the stub, must be after the legacy header and before 0x1000.
|
||||
let reloc_offset = WrapperFileOffset::from(0x500);
|
||||
let reloc_offset = SetupFileOffset::from(0x500);
|
||||
|
||||
// PE header
|
||||
let mut pe_hdr = PeHdr {
|
||||
@ -346,7 +346,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
},
|
||||
};
|
||||
|
||||
let addr_info = TrojanSectionAddrInfo::from(&elf);
|
||||
let addr_info = ImageSectionAddrInfo::from(&elf);
|
||||
|
||||
// PE section headers
|
||||
let mut sec_hdrs = Vec::<PeSectionHdr>::new();
|
||||
@ -354,7 +354,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
sec_hdrs.push(PeSectionHdr {
|
||||
name: [b'.', b'r', b'e', b'l', b'o', b'c', 0, 0],
|
||||
virtual_size: relocs.len() as u32,
|
||||
virtual_address: usize::from(WrapperVA::from(reloc_offset)) as u32,
|
||||
virtual_address: usize::from(SetupVA::from(reloc_offset)) as u32,
|
||||
raw_data_size: relocs.len() as u32,
|
||||
data_addr: usize::from(reloc_offset) as u32,
|
||||
relocs: 0,
|
||||
@ -373,7 +373,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
virtual_size: addr_info.text_virt_size() as u32,
|
||||
virtual_address: usize::from(addr_info.text.start) as u32,
|
||||
raw_data_size: addr_info.text_file_size() as u32,
|
||||
data_addr: usize::from(WrapperFileOffset::from(addr_info.text.start)) as u32,
|
||||
data_addr: usize::from(SetupFileOffset::from(addr_info.text.start)) as u32,
|
||||
relocs: 0,
|
||||
line_numbers: 0,
|
||||
num_relocs: 0,
|
||||
@ -390,7 +390,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
virtual_size: addr_info.data_virt_size() as u32,
|
||||
virtual_address: usize::from(addr_info.data.start) as u32,
|
||||
raw_data_size: addr_info.data_file_size() as u32,
|
||||
data_addr: usize::from(WrapperFileOffset::from(addr_info.data.start)) as u32,
|
||||
data_addr: usize::from(SetupFileOffset::from(addr_info.data.start)) as u32,
|
||||
relocs: 0,
|
||||
line_numbers: 0,
|
||||
num_relocs: 0,
|
||||
@ -424,7 +424,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
virtual_size: addr_info.rodata_virt_size() as u32,
|
||||
virtual_address: usize::from(addr_info.rodata.start) as u32,
|
||||
raw_data_size: addr_info.rodata_file_size() as u32,
|
||||
data_addr: usize::from(WrapperFileOffset::from(addr_info.rodata.start)) as u32,
|
||||
data_addr: usize::from(SetupFileOffset::from(addr_info.rodata.start)) as u32,
|
||||
relocs: 0,
|
||||
line_numbers: 0,
|
||||
num_relocs: 0,
|
||||
@ -451,7 +451,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
||||
bin.extend_from_slice(bytemuck::bytes_of(&sec_hdr));
|
||||
}
|
||||
|
||||
TrojanPeCoffHeaderBuf {
|
||||
ImagePeCoffHeaderBuf {
|
||||
header_at_zero: bin,
|
||||
relocs: (reloc_offset, relocs),
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "aster-boot-wrapper"
|
||||
name = "linux-bzimage-setup"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@ -7,7 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
linux_boot_params = { path = "../linux-boot-params" }
|
||||
linux-boot-params = { path = "../boot-params" }
|
||||
uart_16550 = "0.3.0"
|
||||
xmas-elf = "0.8.0"
|
||||
|
@ -1,19 +1,19 @@
|
||||
//! The linux boot wrapper binary.
|
||||
//! The linux bzImage setup binary.
|
||||
//!
|
||||
//! With respect to the format of the bzImage, we design our boot wrapper in the similar
|
||||
//! With respect to the format of the bzImage, we design our bzImage setup in the similar
|
||||
//! role as the setup code in the linux kernel. The setup code is responsible for
|
||||
//! initializing the machine state, decompressing and loading the kernel image into memory.
|
||||
//! So does our boot wrapper.
|
||||
//! So does our bzImage setup.
|
||||
//!
|
||||
//! The boot wrapper code is concatenated to the bzImage, and it contains both the linux
|
||||
//! boot header and the PE/COFF header to be a valid UEFI image. The wrapper also supports
|
||||
//! The bzImage setup code is concatenated to the bzImage, and it contains both the linux
|
||||
//! boot header and the PE/COFF header to be a valid UEFI image. The setup also supports
|
||||
//! the legacy 32 bit boot protocol, but the support for the legacy boot protocol does not
|
||||
//! co-exist with the UEFI boot protocol. Users can choose either one of them. By specifying
|
||||
//! the target as `x86_64-unknown-none` it supports UEFI protocols. And if the target is
|
||||
//! `x86_64-i386_pm-none` it supports the legacy boot protocol.
|
||||
//!
|
||||
//! The building process of the bzImage and the generation of the PE/COFF header is done
|
||||
//! by the linux-boot-wrapper-builder crate. And the code of the wrapper is in this crate.
|
||||
//! by the linux-bzimage-builder crate. And the code of the setup is in this crate.
|
||||
//! You should compile this crate using the functions provided in the builder.
|
||||
//!
|
||||
|
@ -10,8 +10,8 @@ use crate::console::{print_hex, print_str};
|
||||
|
||||
pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
|
||||
|
||||
#[export_name = "_trojan_entry_32"]
|
||||
extern "cdecl" fn trojan_entry(boot_params_ptr: u32) -> ! {
|
||||
#[export_name = "_bzimage_entry_32"]
|
||||
extern "cdecl" fn bzimage_entry(boot_params_ptr: u32) -> ! {
|
||||
// Safety: this init function is only called once.
|
||||
unsafe { crate::console::init() };
|
||||
|
@ -12,9 +12,10 @@ start_of_setup32:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
.extern _trojan_entry_32
|
||||
// The rust entrypoint of the bzImage
|
||||
.extern _bzimage_entry_32
|
||||
push esi # the boot_params pointer
|
||||
call _trojan_entry_32
|
||||
call _bzimage_entry_32
|
||||
|
||||
// Unreachable here.
|
||||
halt:
|
@ -8,10 +8,10 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
// This is enforced in the linker script of the wrapper.
|
||||
// This is enforced in the linker script of the setup.
|
||||
const START_OF_SETUP32_VA: usize = 0x100000;
|
||||
|
||||
/// The wrapper is a position-independent executable. We can get the loaded base
|
||||
/// The setup is a position-independent executable. We can get the loaded base
|
||||
/// address from the symbol.
|
||||
#[inline]
|
||||
pub fn get_image_loaded_offset() -> isize {
|
@ -7,6 +7,6 @@ edition = "2021"
|
||||
[dependencies]
|
||||
anyhow = "1.0.32"
|
||||
clap = { version = "4.3.19", features = ["derive"] }
|
||||
aster-boot-wrapper-builder = { path = "../framework/libs/boot-wrapper/builder" }
|
||||
linux-bzimage-builder = { path = "../framework/libs/linux-bzimage/builder" }
|
||||
rand = "0.8.5"
|
||||
xmas-elf = "0.8.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
use aster_boot_wrapper_builder::{make_bzimage, BzImageType};
|
||||
use linux_bzimage_builder::{make_bzimage, BzImageType};
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
@ -102,8 +102,8 @@ pub fn create_bootdev_image(
|
||||
BootProtocol::LinuxEfiHandover64 => BzImageType::Efi64,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let wrapper_src = Path::new("framework/libs/boot-wrapper/wrapper");
|
||||
let wrapper_out = Path::new("target/aster-boot-wrapper");
|
||||
let wrapper_src = Path::new("framework/libs/linux-bzimage/setup");
|
||||
let wrapper_out = Path::new("target/linux-bzimage-setup");
|
||||
// Make the `bzImage`-compatible kernel image and place it in the boot directory.
|
||||
let target_path = iso_root.join("boot").join("asterinaz");
|
||||
println!("[aster-runner] Building bzImage.");
|
||||
|
Reference in New Issue
Block a user