mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Rename trojan to wrapper and add docs
This commit is contained in:
parent
12d01ca1e4
commit
e71c2701d6
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -956,6 +956,16 @@ dependencies = [
|
|||||||
"rle-decode-fast",
|
"rle-decode-fast",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-boot-wrapper-builder"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"bytemuck",
|
||||||
|
"serde",
|
||||||
|
"xmas-elf 0.9.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux_boot_params"
|
name = "linux_boot_params"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -36,8 +36,8 @@ members = [
|
|||||||
"framework/aster-frame",
|
"framework/aster-frame",
|
||||||
"framework/aster-frame/src/arch/x86/boot/linux_boot/setup",
|
"framework/aster-frame/src/arch/x86/boot/linux_boot/setup",
|
||||||
"framework/libs/align_ext",
|
"framework/libs/align_ext",
|
||||||
"framework/libs/boot-trojan/builder",
|
"framework/libs/boot-wrapper/builder",
|
||||||
"framework/libs/boot-trojan/trojan",
|
"framework/libs/boot-wrapper/wrapper",
|
||||||
"framework/libs/ktest",
|
"framework/libs/ktest",
|
||||||
"framework/libs/tdx-guest",
|
"framework/libs/tdx-guest",
|
||||||
"services/comps/block",
|
"services/comps/block",
|
||||||
|
4
Makefile
4
Makefile
@ -85,8 +85,8 @@ export CARGO := cargo
|
|||||||
USERMODE_TESTABLE := \
|
USERMODE_TESTABLE := \
|
||||||
runner \
|
runner \
|
||||||
framework/libs/align_ext \
|
framework/libs/align_ext \
|
||||||
framework/libs/boot-trojan/builder \
|
framework/libs/boot-wrapper/builder \
|
||||||
framework/libs/boot-trojan/linux-boot-params \
|
framework/libs/boot-wrapper/linux-boot-params \
|
||||||
framework/libs/ktest \
|
framework/libs/ktest \
|
||||||
framework/libs/ktest-proc-macro \
|
framework/libs/ktest-proc-macro \
|
||||||
services/libs/cpio-decoder \
|
services/libs/cpio-decoder \
|
||||||
|
@ -10,7 +10,7 @@ align_ext = { path = "../libs/align_ext" }
|
|||||||
bit_field = "0.10.1"
|
bit_field = "0.10.1"
|
||||||
bitflags = "1.3"
|
bitflags = "1.3"
|
||||||
bitvec = { version = "1.0", default-features = false, features = ["alloc"] }
|
bitvec = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||||
linux_boot_params = { path = "../libs/boot-trojan/linux-boot-params" }
|
linux_boot_params = { path = "../libs/boot-wrapper/linux-boot-params" }
|
||||||
buddy_system_allocator = "0.9.0"
|
buddy_system_allocator = "0.9.0"
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
gimli = { version = "0.28", default-features = false, features = ["read-core"] }
|
gimli = { version = "0.28", default-features = false, features = ["read-core"] }
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
#![no_main]
|
|
||||||
|
|
||||||
use linux_boot_params::BootParams;
|
|
||||||
|
|
||||||
mod console;
|
|
||||||
mod loader;
|
|
||||||
|
|
||||||
// Unfortunately, the entrypoint is not defined here in the main.rs file.
|
|
||||||
// See the exported functions in the x86 module for details.
|
|
||||||
mod x86;
|
|
||||||
|
|
||||||
fn get_payload(boot_params: &BootParams) -> &'static [u8] {
|
|
||||||
let hdr = &boot_params.hdr;
|
|
||||||
// The payload_offset field is not recorded in the relocation table, so we need to
|
|
||||||
// calculate the loaded offset manually.
|
|
||||||
let loaded_offset = x86::relocation::get_image_loaded_offset();
|
|
||||||
let payload_offset = (loaded_offset + hdr.payload_offset as isize) as usize;
|
|
||||||
let payload_length = hdr.payload_length as usize;
|
|
||||||
// Safety: the payload_offset and payload_length is valid if we assume that the
|
|
||||||
// boot_params struct is correct.
|
|
||||||
unsafe { core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length as usize) }
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aster-boot-trojan-builder"
|
name = "aster-boot-wrapper-builder"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
@ -1,3 +1,15 @@
|
|||||||
|
//! The linux boot wrapper builder.
|
||||||
|
//!
|
||||||
|
//! This crate is responsible for building the bzImage. It contains methods to build
|
||||||
|
//! the wrapper binary and methods to build the bzImage.
|
||||||
|
//!
|
||||||
|
//! We should build the jinux 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.
|
||||||
|
//!
|
||||||
|
//! The wrapper should be built into the ELF target and we convert it to a flat binary
|
||||||
|
//! in the builder.
|
||||||
|
|
||||||
mod mapping;
|
mod mapping;
|
||||||
mod pe_header;
|
mod pe_header;
|
||||||
|
|
||||||
@ -9,7 +21,7 @@ use std::{
|
|||||||
|
|
||||||
use xmas_elf::program::SegmentData;
|
use xmas_elf::program::SegmentData;
|
||||||
|
|
||||||
use mapping::{TrojanFileOffset, TrojanVA};
|
use mapping::{WrapperFileOffset, WrapperVA};
|
||||||
|
|
||||||
/// We need a flat binary which satisfies PA delta == File delta, and objcopy
|
/// 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
|
/// does not satisfy us well, so we should parse the ELF and do our own
|
||||||
@ -26,7 +38,7 @@ fn trojan_to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
|
|||||||
let SegmentData::Undefined(header_data) = program.get_data(&elf).unwrap() else {
|
let SegmentData::Undefined(header_data) = program.get_data(&elf).unwrap() else {
|
||||||
panic!("Unexpected segment data type");
|
panic!("Unexpected segment data type");
|
||||||
};
|
};
|
||||||
let dst_file_offset = usize::from(TrojanFileOffset::from(TrojanVA::from(
|
let dst_file_offset = usize::from(WrapperFileOffset::from(WrapperVA::from(
|
||||||
program.virtual_addr() as usize,
|
program.virtual_addr() as usize,
|
||||||
)));
|
)));
|
||||||
let dst_file_length = program.file_size() as usize;
|
let dst_file_length = program.file_size() as usize;
|
||||||
@ -61,7 +73,7 @@ fn fill_legacy_header_fields(
|
|||||||
header: &mut [u8],
|
header: &mut [u8],
|
||||||
kernel_len: usize,
|
kernel_len: usize,
|
||||||
trojan_len: usize,
|
trojan_len: usize,
|
||||||
payload_offset: TrojanVA,
|
payload_offset: WrapperVA,
|
||||||
) {
|
) {
|
||||||
fill_header_field(
|
fill_header_field(
|
||||||
header,
|
header,
|
||||||
@ -84,10 +96,10 @@ fn fill_legacy_header_fields(
|
|||||||
|
|
||||||
pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_out: &Path) {
|
pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_out: &Path) {
|
||||||
#[cfg(feature = "trojan64")]
|
#[cfg(feature = "trojan64")]
|
||||||
let trojan = build_trojan_with_arch(trojan_src, trojan_out, &TrojanBuildArch::X86_64);
|
let wrapper = build_trojan_with_arch(trojan_src, trojan_out, &TrojanBuildArch::X86_64);
|
||||||
|
|
||||||
#[cfg(not(feature = "trojan64"))]
|
#[cfg(not(feature = "trojan64"))]
|
||||||
let trojan = {
|
let wrapper = {
|
||||||
let arch = trojan_src
|
let arch = trojan_src
|
||||||
.join("x86_64-i386_pm-none.json")
|
.join("x86_64-i386_pm-none.json")
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
@ -96,13 +108,13 @@ pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_o
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut trojan_elf = Vec::new();
|
let mut trojan_elf = Vec::new();
|
||||||
File::open(trojan)
|
File::open(wrapper)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read_to_end(&mut trojan_elf)
|
.read_to_end(&mut trojan_elf)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut trojan = trojan_to_flat_binary(&trojan_elf);
|
let mut wrapper = trojan_to_flat_binary(&trojan_elf);
|
||||||
// Pad the header with 8-byte alignment.
|
// Pad the header with 8-byte alignment.
|
||||||
trojan.resize((trojan.len() + 7) & !7, 0x00);
|
wrapper.resize((wrapper.len() + 7) & !7, 0x00);
|
||||||
|
|
||||||
let mut kernel = Vec::new();
|
let mut kernel = Vec::new();
|
||||||
File::open(kernel_path)
|
File::open(kernel_path)
|
||||||
@ -111,13 +123,13 @@ pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_o
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let payload = kernel;
|
let payload = kernel;
|
||||||
|
|
||||||
let trojan_len = trojan.len();
|
let trojan_len = wrapper.len();
|
||||||
let payload_len = payload.len();
|
let payload_len = payload.len();
|
||||||
let payload_offset = TrojanFileOffset::from(trojan_len);
|
let payload_offset = WrapperFileOffset::from(trojan_len);
|
||||||
fill_legacy_header_fields(&mut trojan, payload_len, trojan_len, payload_offset.into());
|
fill_legacy_header_fields(&mut wrapper, payload_len, trojan_len, payload_offset.into());
|
||||||
|
|
||||||
let mut kernel_image = File::create(path).unwrap();
|
let mut kernel_image = File::create(path).unwrap();
|
||||||
kernel_image.write_all(&trojan).unwrap();
|
kernel_image.write_all(&wrapper).unwrap();
|
||||||
kernel_image.write_all(&payload).unwrap();
|
kernel_image.write_all(&payload).unwrap();
|
||||||
|
|
||||||
let image_size = trojan_len + payload_len;
|
let image_size = trojan_len + payload_len;
|
||||||
@ -151,13 +163,17 @@ enum TrojanBuildArch {
|
|||||||
Other(PathBuf),
|
Other(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the trojan binary.
|
||||||
|
///
|
||||||
|
/// It will return the path to the built trojan binary.
|
||||||
fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildArch) -> PathBuf {
|
fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildArch) -> PathBuf {
|
||||||
if !out_dir.exists() {
|
if !out_dir.exists() {
|
||||||
std::fs::create_dir_all(&out_dir).unwrap();
|
std::fs::create_dir_all(&out_dir).unwrap();
|
||||||
}
|
}
|
||||||
let out_dir = std::fs::canonicalize(out_dir).unwrap();
|
let out_dir = std::fs::canonicalize(out_dir).unwrap();
|
||||||
|
|
||||||
// Relocations are fewer in release mode. But with release mode it crashes.
|
// Relocations are fewer in release mode. That's why the release mode is more stable than
|
||||||
|
// the debug mode.
|
||||||
let profile = "release";
|
let profile = "release";
|
||||||
|
|
||||||
let cargo = std::env::var("CARGO").unwrap();
|
let cargo = std::env::var("CARGO").unwrap();
|
||||||
@ -167,7 +183,7 @@ fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildA
|
|||||||
if profile == "release" {
|
if profile == "release" {
|
||||||
cmd.arg("--release");
|
cmd.arg("--release");
|
||||||
}
|
}
|
||||||
cmd.arg("--package").arg("aster-boot-trojan");
|
cmd.arg("--package").arg("aster-boot-wrapper");
|
||||||
cmd.arg("--target").arg(match arch {
|
cmd.arg("--target").arg(match arch {
|
||||||
TrojanBuildArch::X86_64 => "x86_64-unknown-none",
|
TrojanBuildArch::X86_64 => "x86_64-unknown-none",
|
||||||
TrojanBuildArch::Other(path) => path.to_str().unwrap(),
|
TrojanBuildArch::Other(path) => path.to_str().unwrap(),
|
||||||
@ -189,7 +205,7 @@ fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildA
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the path to the trojan binary.
|
// Get the path to the wrapper binary.
|
||||||
let arch_name = match arch {
|
let arch_name = match arch {
|
||||||
TrojanBuildArch::X86_64 => "x86_64-unknown-none",
|
TrojanBuildArch::X86_64 => "x86_64-unknown-none",
|
||||||
TrojanBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
|
TrojanBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
|
||||||
@ -198,7 +214,7 @@ fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildA
|
|||||||
let trojan_artifact = out_dir
|
let trojan_artifact = out_dir
|
||||||
.join(arch_name)
|
.join(arch_name)
|
||||||
.join(profile)
|
.join(profile)
|
||||||
.join("aster-boot-trojan");
|
.join("aster-boot-wrapper");
|
||||||
|
|
||||||
trojan_artifact.to_owned()
|
trojan_artifact.to_owned()
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
//! In the trojan, VA - SETUP32_LMA == FileOffset - LEGACY_SETUP_SEC_SIZE.
|
//! In the wrapper, VA - SETUP32_LMA == FileOffset - LEGACY_SETUP_SEC_SIZE.
|
||||||
//! And the addresses are specified in the ELF file.
|
//! And the addresses are specified in the ELF file.
|
||||||
|
//!
|
||||||
|
//! This module centralizes the conversion between VA and FileOffset.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::PartialOrd,
|
cmp::PartialOrd,
|
||||||
@ -15,28 +17,28 @@ pub const LEGACY_SETUP_SEC_SIZE: usize = 0x200 * (LEGACY_SETUP_SECS + 1);
|
|||||||
pub const SETUP32_LMA: usize = 0x100000;
|
pub const SETUP32_LMA: usize = 0x100000;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||||
pub struct TrojanVA {
|
pub struct WrapperVA {
|
||||||
addr: usize,
|
addr: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||||
pub struct TrojanFileOffset {
|
pub struct WrapperFileOffset {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for TrojanVA {
|
impl From<usize> for WrapperVA {
|
||||||
fn from(addr: usize) -> Self {
|
fn from(addr: usize) -> Self {
|
||||||
Self { addr }
|
Self { addr }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrojanVA> for usize {
|
impl From<WrapperVA> for usize {
|
||||||
fn from(va: TrojanVA) -> Self {
|
fn from(va: WrapperVA) -> Self {
|
||||||
va.addr
|
va.addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub for TrojanVA {
|
impl Sub for WrapperVA {
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
fn sub(self, rhs: Self) -> Self::Output {
|
||||||
@ -44,7 +46,7 @@ impl Sub for TrojanVA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<usize> for TrojanVA {
|
impl Add<usize> for WrapperVA {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
@ -54,19 +56,19 @@ impl Add<usize> for TrojanVA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for TrojanFileOffset {
|
impl From<usize> for WrapperFileOffset {
|
||||||
fn from(offset: usize) -> Self {
|
fn from(offset: usize) -> Self {
|
||||||
Self { offset }
|
Self { offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrojanFileOffset> for usize {
|
impl From<WrapperFileOffset> for usize {
|
||||||
fn from(offset: TrojanFileOffset) -> Self {
|
fn from(offset: WrapperFileOffset) -> Self {
|
||||||
offset.offset
|
offset.offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub for TrojanFileOffset {
|
impl Sub for WrapperFileOffset {
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
fn sub(self, rhs: Self) -> Self::Output {
|
||||||
@ -74,7 +76,7 @@ impl Sub for TrojanFileOffset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<usize> for TrojanFileOffset {
|
impl Add<usize> for WrapperFileOffset {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
@ -84,16 +86,16 @@ impl Add<usize> for TrojanFileOffset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrojanVA> for TrojanFileOffset {
|
impl From<WrapperVA> for WrapperFileOffset {
|
||||||
fn from(va: TrojanVA) -> Self {
|
fn from(va: WrapperVA) -> Self {
|
||||||
Self {
|
Self {
|
||||||
offset: va.addr + LEGACY_SETUP_SEC_SIZE - SETUP32_LMA,
|
offset: va.addr + LEGACY_SETUP_SEC_SIZE - SETUP32_LMA,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrojanFileOffset> for TrojanVA {
|
impl From<WrapperFileOffset> for WrapperVA {
|
||||||
fn from(offset: TrojanFileOffset) -> Self {
|
fn from(offset: WrapperFileOffset) -> Self {
|
||||||
Self {
|
Self {
|
||||||
addr: offset.offset + SETUP32_LMA - LEGACY_SETUP_SEC_SIZE,
|
addr: offset.offset + SETUP32_LMA - LEGACY_SETUP_SEC_SIZE,
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use std::{mem::size_of, ops::Range};
|
use std::{mem::size_of, ops::Range};
|
||||||
|
|
||||||
use crate::mapping::{TrojanFileOffset, TrojanVA, LEGACY_SETUP_SEC_SIZE, SETUP32_LMA};
|
use crate::mapping::{WrapperFileOffset, WrapperVA, LEGACY_SETUP_SEC_SIZE, SETUP32_LMA};
|
||||||
|
|
||||||
// The MS-DOS header.
|
// The MS-DOS header.
|
||||||
const MZ_MAGIC: u16 = 0x5a4d; // "MZ"
|
const MZ_MAGIC: u16 = 0x5a4d; // "MZ"
|
||||||
@ -199,11 +199,11 @@ struct PeSectionHdr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct TrojanSectionAddrInfo {
|
struct TrojanSectionAddrInfo {
|
||||||
pub text: Range<TrojanVA>,
|
pub text: Range<WrapperVA>,
|
||||||
pub data: Range<TrojanVA>,
|
pub data: Range<WrapperVA>,
|
||||||
pub bss: Range<TrojanVA>,
|
pub bss: Range<WrapperVA>,
|
||||||
/// All the readonly but loaded sections.
|
/// All the readonly but loaded sections.
|
||||||
pub rodata: Range<TrojanVA>,
|
pub rodata: Range<WrapperVA>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrojanSectionAddrInfo {
|
impl TrojanSectionAddrInfo {
|
||||||
@ -218,7 +218,7 @@ impl TrojanSectionAddrInfo {
|
|||||||
let mut rodata_end = None;
|
let mut rodata_end = None;
|
||||||
for program in elf.program_iter() {
|
for program in elf.program_iter() {
|
||||||
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||||
let offset = TrojanVA::from(program.virtual_addr() as usize);
|
let offset = WrapperVA::from(program.virtual_addr() as usize);
|
||||||
let length = program.mem_size() as usize;
|
let length = program.mem_size() as usize;
|
||||||
if program.flags().is_execute() {
|
if program.flags().is_execute() {
|
||||||
text_start = Some(offset);
|
text_start = Some(offset);
|
||||||
@ -236,10 +236,10 @@ impl TrojanSectionAddrInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
text: TrojanVA::from(text_start.unwrap())..TrojanVA::from(text_end.unwrap()),
|
text: WrapperVA::from(text_start.unwrap())..WrapperVA::from(text_end.unwrap()),
|
||||||
data: TrojanVA::from(data_start.unwrap())..TrojanVA::from(data_end.unwrap()),
|
data: WrapperVA::from(data_start.unwrap())..WrapperVA::from(data_end.unwrap()),
|
||||||
bss: TrojanVA::from(bss_start.unwrap())..TrojanVA::from(bss_end.unwrap()),
|
bss: WrapperVA::from(bss_start.unwrap())..WrapperVA::from(bss_end.unwrap()),
|
||||||
rodata: TrojanVA::from(rodata_start.unwrap())..TrojanVA::from(rodata_end.unwrap()),
|
rodata: WrapperVA::from(rodata_start.unwrap())..WrapperVA::from(rodata_end.unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ impl TrojanSectionAddrInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn text_file_size(&self) -> usize {
|
fn text_file_size(&self) -> usize {
|
||||||
TrojanFileOffset::from(self.text.end) - TrojanFileOffset::from(self.text.start)
|
WrapperFileOffset::from(self.text.end) - WrapperFileOffset::from(self.text.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data_virt_size(&self) -> usize {
|
fn data_virt_size(&self) -> usize {
|
||||||
@ -256,7 +256,7 @@ impl TrojanSectionAddrInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn data_file_size(&self) -> usize {
|
fn data_file_size(&self) -> usize {
|
||||||
TrojanFileOffset::from(self.data.end) - TrojanFileOffset::from(self.data.start)
|
WrapperFileOffset::from(self.data.end) - WrapperFileOffset::from(self.data.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bss_virt_size(&self) -> usize {
|
fn bss_virt_size(&self) -> usize {
|
||||||
@ -268,13 +268,13 @@ impl TrojanSectionAddrInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rodata_file_size(&self) -> usize {
|
fn rodata_file_size(&self) -> usize {
|
||||||
TrojanFileOffset::from(self.rodata.end) - TrojanFileOffset::from(self.rodata.start)
|
WrapperFileOffset::from(self.rodata.end) - WrapperFileOffset::from(self.rodata.start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TrojanPeCoffHeaderBuf {
|
pub struct TrojanPeCoffHeaderBuf {
|
||||||
pub header_at_zero: Vec<u8>,
|
pub header_at_zero: Vec<u8>,
|
||||||
pub relocs: (TrojanFileOffset, Vec<u8>),
|
pub relocs: (WrapperFileOffset, 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) -> TrojanPeCoffHeaderBuf {
|
||||||
@ -284,7 +284,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
|||||||
// The EFI application loader requires a relocation section.
|
// The EFI application loader requires a relocation section.
|
||||||
let relocs = vec![];
|
let relocs = vec![];
|
||||||
// The place where we put the stub, must be after the legacy header and before 0x1000.
|
// The place where we put the stub, must be after the legacy header and before 0x1000.
|
||||||
let reloc_offset = TrojanFileOffset::from(0x500);
|
let reloc_offset = WrapperFileOffset::from(0x500);
|
||||||
|
|
||||||
// PE header
|
// PE header
|
||||||
let mut pe_hdr = PeHdr {
|
let mut pe_hdr = PeHdr {
|
||||||
@ -354,7 +354,7 @@ pub(crate) fn make_pe_coff_header(setup_elf: &[u8], image_size: usize) -> Trojan
|
|||||||
sec_hdrs.push(PeSectionHdr {
|
sec_hdrs.push(PeSectionHdr {
|
||||||
name: [b'.', b'r', b'e', b'l', b'o', b'c', 0, 0],
|
name: [b'.', b'r', b'e', b'l', b'o', b'c', 0, 0],
|
||||||
virtual_size: relocs.len() as u32,
|
virtual_size: relocs.len() as u32,
|
||||||
virtual_address: usize::from(TrojanVA::from(reloc_offset)) as u32,
|
virtual_address: usize::from(WrapperVA::from(reloc_offset)) as u32,
|
||||||
raw_data_size: relocs.len() as u32,
|
raw_data_size: relocs.len() as u32,
|
||||||
data_addr: usize::from(reloc_offset) as u32,
|
data_addr: usize::from(reloc_offset) as u32,
|
||||||
relocs: 0,
|
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_size: addr_info.text_virt_size() as u32,
|
||||||
virtual_address: usize::from(addr_info.text.start) as u32,
|
virtual_address: usize::from(addr_info.text.start) as u32,
|
||||||
raw_data_size: addr_info.text_file_size() as u32,
|
raw_data_size: addr_info.text_file_size() as u32,
|
||||||
data_addr: usize::from(TrojanFileOffset::from(addr_info.text.start)) as u32,
|
data_addr: usize::from(WrapperFileOffset::from(addr_info.text.start)) as u32,
|
||||||
relocs: 0,
|
relocs: 0,
|
||||||
line_numbers: 0,
|
line_numbers: 0,
|
||||||
num_relocs: 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_size: addr_info.data_virt_size() as u32,
|
||||||
virtual_address: usize::from(addr_info.data.start) as u32,
|
virtual_address: usize::from(addr_info.data.start) as u32,
|
||||||
raw_data_size: addr_info.data_file_size() as u32,
|
raw_data_size: addr_info.data_file_size() as u32,
|
||||||
data_addr: usize::from(TrojanFileOffset::from(addr_info.data.start)) as u32,
|
data_addr: usize::from(WrapperFileOffset::from(addr_info.data.start)) as u32,
|
||||||
relocs: 0,
|
relocs: 0,
|
||||||
line_numbers: 0,
|
line_numbers: 0,
|
||||||
num_relocs: 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_size: addr_info.rodata_virt_size() as u32,
|
||||||
virtual_address: usize::from(addr_info.rodata.start) as u32,
|
virtual_address: usize::from(addr_info.rodata.start) as u32,
|
||||||
raw_data_size: addr_info.rodata_file_size() as u32,
|
raw_data_size: addr_info.rodata_file_size() as u32,
|
||||||
data_addr: usize::from(TrojanFileOffset::from(addr_info.rodata.start)) as u32,
|
data_addr: usize::from(WrapperFileOffset::from(addr_info.rodata.start)) as u32,
|
||||||
relocs: 0,
|
relocs: 0,
|
||||||
line_numbers: 0,
|
line_numbers: 0,
|
||||||
num_relocs: 0,
|
num_relocs: 0,
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aster-boot-trojan"
|
name = "aster-boot-wrapper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
42
framework/libs/boot-wrapper/wrapper/src/main.rs
Normal file
42
framework/libs/boot-wrapper/wrapper/src/main.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//! The linux boot wrapper binary.
|
||||||
|
//!
|
||||||
|
//! With respect to the format of the bzImage, we design our boot wrapper 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.
|
||||||
|
//!
|
||||||
|
//! 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 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.
|
||||||
|
//! You should compile this crate using the functions provided in the builder.
|
||||||
|
//!
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use linux_boot_params::BootParams;
|
||||||
|
|
||||||
|
mod console;
|
||||||
|
mod loader;
|
||||||
|
|
||||||
|
// Unfortunately, the entrypoint is not defined here in the main.rs file.
|
||||||
|
// See the exported functions in the x86 module for details.
|
||||||
|
mod x86;
|
||||||
|
|
||||||
|
fn get_payload(boot_params: &BootParams) -> &'static [u8] {
|
||||||
|
let hdr = &boot_params.hdr;
|
||||||
|
// The payload_offset field is not recorded in the relocation table, so we need to
|
||||||
|
// calculate the loaded offset manually.
|
||||||
|
let loaded_offset = x86::relocation::get_image_loaded_offset();
|
||||||
|
let payload_offset = (loaded_offset + hdr.payload_offset as isize) as usize;
|
||||||
|
let payload_length = hdr.payload_length as usize;
|
||||||
|
// Safety: the payload_offset and payload_length is valid if we assume that the
|
||||||
|
// boot_params struct is correct.
|
||||||
|
unsafe { core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length as usize) }
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
// This is enforced in the linker script.
|
// This is enforced in the linker script.
|
||||||
const START_OF_SETUP32_VA: usize = 0x100000;
|
const START_OF_SETUP32_VA: usize = 0x100000;
|
||||||
|
|
||||||
/// The trojan is a position-independent executable. We can get the loaded base
|
/// The wrapper is a position-independent executable. We can get the loaded base
|
||||||
/// address from the symbol.
|
/// address from the symbol.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_image_loaded_offset() -> isize {
|
pub fn get_image_loaded_offset() -> isize {
|
@ -7,6 +7,6 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.32"
|
anyhow = "1.0.32"
|
||||||
clap = { version = "4.3.19", features = ["derive"] }
|
clap = { version = "4.3.19", features = ["derive"] }
|
||||||
aster-boot-trojan-builder = { path = "../framework/libs/boot-trojan/builder" }
|
aster-boot-wrapper-builder = { path = "../framework/libs/boot-wrapper/builder" }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
xmas-elf = "0.8.0"
|
xmas-elf = "0.8.0"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use aster_boot_trojan_builder::make_bzimage;
|
use aster_boot_wrapper_builder::make_bzimage;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
@ -93,8 +93,8 @@ pub fn create_bootdev_image(
|
|||||||
|
|
||||||
let target_path = match protocol {
|
let target_path = match protocol {
|
||||||
BootProtocol::Linux => {
|
BootProtocol::Linux => {
|
||||||
let trojan_src = Path::new("framework/libs/boot-trojan/trojan");
|
let trojan_src = Path::new("framework/libs/boot-wrapper/wrapper");
|
||||||
let trojan_out = Path::new("target/aster-boot-trojan");
|
let trojan_out = Path::new("target/aster-boot-wrapper");
|
||||||
// Make the `bzImage`-compatible kernel image and place it in the boot directory.
|
// Make the `bzImage`-compatible kernel image and place it in the boot directory.
|
||||||
let target_path = iso_root.join("boot").join("asterinaz");
|
let target_path = iso_root.join("boot").join("asterinaz");
|
||||||
println!("[aster-runner] Building bzImage.");
|
println!("[aster-runner] Building bzImage.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user