mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Fix boot phase mappings
This commit is contained in:
parent
ebbe451cc4
commit
97323f612b
18
Cargo.lock
generated
18
Cargo.lock
generated
@ -392,9 +392,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.3.3"
|
version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitvec"
|
name = "bitvec"
|
||||||
@ -1028,7 +1028,7 @@ version = "0.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b624a7b3f704734d98d21455b617607eb7043d4509d1c34bf9e7ff7dd47b31a"
|
checksum = "4b624a7b3f704734d98d21455b617607eb7043d4509d1c34bf9e7ff7dd47b31a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.3.3",
|
"bitflags 2.4.1",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"log",
|
"log",
|
||||||
"ptr_meta",
|
"ptr_meta",
|
||||||
@ -1515,7 +1515,7 @@ version = "0.26.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07ead9f748a4646479b850add36b527113a80e80a7e0f44d7b0334291850dcc5"
|
checksum = "07ead9f748a4646479b850add36b527113a80e80a7e0f44d7b0334291850dcc5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.3.3",
|
"bitflags 2.4.1",
|
||||||
"log",
|
"log",
|
||||||
"ptr_meta",
|
"ptr_meta",
|
||||||
"ucs2",
|
"ucs2",
|
||||||
@ -1541,7 +1541,7 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62642516099c6441a5f41b0da8486d5fc3515a0603b0fdaea67b31600e22082e"
|
checksum = "62642516099c6441a5f41b0da8486d5fc3515a0603b0fdaea67b31600e22082e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.3.3",
|
"bitflags 2.4.1",
|
||||||
"ptr_meta",
|
"ptr_meta",
|
||||||
"uguid",
|
"uguid",
|
||||||
]
|
]
|
||||||
@ -1552,7 +1552,7 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "864ac69eadd877bfb34e7814be1928122ed0057d9f975169a56ee496aa7bdfd7"
|
checksum = "864ac69eadd877bfb34e7814be1928122ed0057d9f975169a56ee496aa7bdfd7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.3.3",
|
"bitflags 2.4.1",
|
||||||
"ptr_meta",
|
"ptr_meta",
|
||||||
"uguid",
|
"uguid",
|
||||||
]
|
]
|
||||||
@ -1737,12 +1737,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.14.10"
|
version = "0.14.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "100555a863c0092238c2e0e814c1096c1e5cf066a309c696a87e907b5f8c5d69"
|
checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.4.1",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"volatile",
|
"volatile",
|
||||||
]
|
]
|
||||||
|
@ -39,9 +39,14 @@ __linux32_boot:
|
|||||||
.org 0x200
|
.org 0x200
|
||||||
.global __linux64_boot_tag
|
.global __linux64_boot_tag
|
||||||
__linux64_boot_tag:
|
__linux64_boot_tag:
|
||||||
lea rax, [rip + __linux64_boot] // jump into Rust code
|
// We switch back to 32-bit mode to call the 32-bit entry point.
|
||||||
call rax
|
lgdt [boot_gdtr]
|
||||||
jmp halt // unreachable here
|
mov eax, 0xb002b002 // magic for boot_params
|
||||||
|
mov ebx, esi // struct boot_params *
|
||||||
|
sub rsp, 8
|
||||||
|
mov dword ptr [rsp], offset __linux32_boot
|
||||||
|
mov dword ptr [rsp + 4], 24
|
||||||
|
retf
|
||||||
|
|
||||||
// The multiboot & multiboot2 entry point.
|
// The multiboot & multiboot2 entry point.
|
||||||
.code32
|
.code32
|
||||||
|
@ -12,10 +12,12 @@ uart_16550 = "0.3.0"
|
|||||||
xmas-elf = "0.8.0"
|
xmas-elf = "0.8.0"
|
||||||
|
|
||||||
[target.x86_64-unknown-none.dependencies]
|
[target.x86_64-unknown-none.dependencies]
|
||||||
|
bitflags = "2.4.1"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
uefi = "0.26.0"
|
uefi = "0.26.0"
|
||||||
uefi-services = "0.23.0"
|
uefi-services = "0.23.0"
|
||||||
|
x86_64 = "0.14.11"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["debug_print"]
|
default = []
|
||||||
debug_print = []
|
debug_print = []
|
||||||
|
@ -6,7 +6,7 @@ fn main() {
|
|||||||
let linker_script = if target_arch == "x86_64-unknown-none" {
|
let linker_script = if target_arch == "x86_64-unknown-none" {
|
||||||
source_dir.join("src/x86/amd64_efi/linker.ld")
|
source_dir.join("src/x86/amd64_efi/linker.ld")
|
||||||
} else if target_arch == "x86_64-i386_pm-none" {
|
} else if target_arch == "x86_64-i386_pm-none" {
|
||||||
source_dir.join("src/arch/legacy_i386/linker.ld")
|
source_dir.join("src/x86/legacy_i386/linker.ld")
|
||||||
} else {
|
} else {
|
||||||
panic!("Unsupported target_arch: {}", target_arch);
|
panic!("Unsupported target_arch: {}", target_arch);
|
||||||
};
|
};
|
||||||
|
@ -1,43 +1,61 @@
|
|||||||
use xmas_elf::program::{ProgramHeader, SegmentData};
|
use xmas_elf::program::{ProgramHeader, SegmentData};
|
||||||
|
|
||||||
pub fn load_elf(file: &[u8]) -> u32 {
|
/// TODO: remove this and use copy_from_slice instead
|
||||||
|
///
|
||||||
|
/// We use a custom memcpy because the standard library's compiler's builtin memcpy
|
||||||
|
/// fails for some unknown reason.
|
||||||
|
unsafe fn memcpy(dst: *mut u8, src: *const u8, size: usize) {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < size {
|
||||||
|
*dst.add(i) = *src.add(i);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_elf(file: &[u8]) {
|
||||||
let elf = xmas_elf::ElfFile::new(file).unwrap();
|
let elf = xmas_elf::ElfFile::new(file).unwrap();
|
||||||
|
|
||||||
for ph in elf.program_iter() {
|
for ph in elf.program_iter() {
|
||||||
let ProgramHeader::Ph64(program) = ph else {
|
let ProgramHeader::Ph64(program) = ph else {
|
||||||
panic!("[setup] Unexpected program header type!");
|
panic!("[setup] Unexpected program header type! Jinux should be 64-bit ELF binary.");
|
||||||
};
|
};
|
||||||
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||||
let SegmentData::Undefined(header_data) = program.get_data(&elf).unwrap() else {
|
load_segment(&elf, program);
|
||||||
panic!("[setup] Unexpected segment data type!");
|
|
||||||
};
|
|
||||||
// Safety: the physical address from the ELF file is valid
|
|
||||||
let dst_slice = unsafe {
|
|
||||||
core::slice::from_raw_parts_mut(
|
|
||||||
program.physical_addr as *mut u8,
|
|
||||||
program.mem_size as usize,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
/* crate::println!(
|
|
||||||
"[setup loader debug] loading ELF segment at {:#x}, size = {:#x}",
|
|
||||||
program.physical_addr,
|
|
||||||
program.mem_size,
|
|
||||||
); */
|
|
||||||
#[cfg(feature = "debug_print")]
|
|
||||||
unsafe {
|
|
||||||
use crate::console::{print_hex, print_str};
|
|
||||||
print_str("[setup loader debug] loading ELF segment at ");
|
|
||||||
print_hex(program.physical_addr as u64);
|
|
||||||
print_str(", size = ");
|
|
||||||
print_hex(program.mem_size as u64);
|
|
||||||
print_str("\n");
|
|
||||||
}
|
|
||||||
dst_slice[..program.file_size as usize].copy_from_slice(header_data);
|
|
||||||
let zero_slice = &mut dst_slice[program.file_size as usize..];
|
|
||||||
zero_slice.fill(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Return the Linux Boot Protocol entry point defined by Asterinas.
|
|
||||||
crate::x86::ASTER_ENTRY_POINT
|
fn load_segment(file: &xmas_elf::ElfFile, program: &xmas_elf::program::ProgramHeader64) {
|
||||||
|
let SegmentData::Undefined(header_data) = program.get_data(&file).unwrap() else {
|
||||||
|
panic!("[setup] Unexpected segment data type!");
|
||||||
|
};
|
||||||
|
// Safety: the physical address from the ELF file is valid
|
||||||
|
let dst_slice = unsafe {
|
||||||
|
core::slice::from_raw_parts_mut(program.physical_addr as *mut u8, program.mem_size as usize)
|
||||||
|
};
|
||||||
|
/* crate::println!(
|
||||||
|
"[setup loader debug] loading ELF segment at {:#x}, size = {:#x}",
|
||||||
|
program.physical_addr,
|
||||||
|
program.mem_size,
|
||||||
|
); */
|
||||||
|
#[cfg(feature = "debug_print")]
|
||||||
|
unsafe {
|
||||||
|
use crate::console::{print_hex, print_str};
|
||||||
|
print_str("[setup loader debug] loading ELF segment at ");
|
||||||
|
print_hex(program.physical_addr as u64);
|
||||||
|
print_str(", size = ");
|
||||||
|
print_hex(program.mem_size as u64);
|
||||||
|
print_str("\n");
|
||||||
|
}
|
||||||
|
// Safety: the ELF file is valid
|
||||||
|
// dst_slice[..program.file_size as usize].copy_from_slice(header_data);
|
||||||
|
unsafe {
|
||||||
|
memcpy(
|
||||||
|
dst_slice.as_mut_ptr(),
|
||||||
|
header_data.as_ptr(),
|
||||||
|
program.file_size as usize,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let zero_slice = &mut dst_slice[program.file_size as usize..];
|
||||||
|
zero_slice.fill(0);
|
||||||
}
|
}
|
||||||
|
@ -5,47 +5,19 @@ use linux_boot_params::BootParams;
|
|||||||
|
|
||||||
mod console;
|
mod console;
|
||||||
mod loader;
|
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;
|
mod x86;
|
||||||
|
|
||||||
use console::{print_hex, print_str};
|
fn get_payload(boot_params: &BootParams) -> &'static [u8] {
|
||||||
|
let hdr = &boot_params.hdr;
|
||||||
/// The entrypoint of the trojan. The architecture-specific entrypoint will call this function.
|
// The payload_offset field is not recorded in the relocation table, so we need to
|
||||||
fn trojan_entry(boot_params_ptr: usize) -> ! {
|
// calculate the loaded offset manually.
|
||||||
// println!("[setup] bzImage loaded at {:#x}", x86::relocation::get_image_loaded_offset());
|
let loaded_offset = x86::relocation::get_image_loaded_offset();
|
||||||
unsafe {
|
let payload_offset = (loaded_offset + hdr.payload_offset as isize) as usize;
|
||||||
print_str("[setup] bzImage loaded at ");
|
let payload_length = hdr.payload_length as usize;
|
||||||
print_hex(x86::relocation::get_image_loaded_offset() as u64);
|
// Safety: the payload_offset and payload_length is valid if we assume that the
|
||||||
print_str("\n");
|
// boot_params struct is correct.
|
||||||
}
|
unsafe { core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length as usize) }
|
||||||
|
|
||||||
// Safety: the boot_params_ptr is a valid pointer to be borrowed.
|
|
||||||
let boot_params = unsafe { &*(boot_params_ptr as *const BootParams) };
|
|
||||||
// Safety: the payload_offset and payload_length is valid.
|
|
||||||
let payload = unsafe {
|
|
||||||
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;
|
|
||||||
core::slice::from_raw_parts_mut(payload_offset as *mut u8, payload_length as usize)
|
|
||||||
};
|
|
||||||
|
|
||||||
// println!("[setup] loading ELF payload at {:#x}", payload as *const _ as *const u8 as usize);
|
|
||||||
unsafe {
|
|
||||||
print_str("[setup] loading ELF payload at ");
|
|
||||||
print_hex(payload as *const _ as *const u8 as u64);
|
|
||||||
print_str("\n");
|
|
||||||
}
|
|
||||||
let entrypoint = loader::load_elf(payload);
|
|
||||||
|
|
||||||
// println!("[setup] jumping to payload entrypoint at {:#x}", entrypoint);
|
|
||||||
unsafe {
|
|
||||||
print_str("[setup] jumping to payload entrypoint at ");
|
|
||||||
print_hex(entrypoint as u64);
|
|
||||||
print_str("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safety: the entrypoint and the ptr is valid.
|
|
||||||
unsafe { x86::call_aster_entrypoint(entrypoint.into(), boot_params_ptr.try_into().unwrap()) };
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::fmt::Write;
|
|
||||||
use uefi::{
|
use uefi::{
|
||||||
data_types::Handle,
|
data_types::Handle,
|
||||||
proto::loaded_image::LoadedImage,
|
proto::loaded_image::LoadedImage,
|
||||||
@ -7,7 +6,7 @@ use uefi::{
|
|||||||
|
|
||||||
use linux_boot_params::BootParams;
|
use linux_boot_params::BootParams;
|
||||||
|
|
||||||
#[no_mangle]
|
#[export_name = "efi_stub_entry"]
|
||||||
extern "sysv64" fn efi_stub_entry(handle: Handle, mut system_table: SystemTable<Boot>) -> ! {
|
extern "sysv64" fn efi_stub_entry(handle: Handle, mut system_table: SystemTable<Boot>) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
system_table.boot_services().set_image_handle(handle);
|
system_table.boot_services().set_image_handle(handle);
|
||||||
@ -23,7 +22,7 @@ extern "sysv64" fn efi_stub_entry(handle: Handle, mut system_table: SystemTable<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[export_name = "efi_handover_entry"]
|
||||||
extern "sysv64" fn efi_handover_entry(
|
extern "sysv64" fn efi_handover_entry(
|
||||||
handle: Handle,
|
handle: Handle,
|
||||||
mut system_table: SystemTable<Boot>,
|
mut system_table: SystemTable<Boot>,
|
||||||
@ -39,16 +38,21 @@ extern "sysv64" fn efi_handover_entry(
|
|||||||
|
|
||||||
fn efi_phase_boot(
|
fn efi_phase_boot(
|
||||||
handle: Handle,
|
handle: Handle,
|
||||||
mut system_table: SystemTable<Boot>,
|
system_table: SystemTable<Boot>,
|
||||||
boot_params: *mut BootParams,
|
boot_params: *mut BootParams,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
// Safety: this init function is only called once.
|
// Safety: this init function is only called once.
|
||||||
unsafe { crate::console::init() };
|
unsafe { crate::console::init() };
|
||||||
|
|
||||||
// Safety: this is a right place to call this function.
|
// Safety: this is the right time to apply relocations.
|
||||||
unsafe { crate::x86::relocation::apply_rela_dyn_relocations() };
|
unsafe { crate::x86::relocation::apply_rela_dyn_relocations() };
|
||||||
|
|
||||||
uefi_services::println!("[EFI stub] Relocations applied.");
|
uefi_services::println!("[EFI stub] Relocations applied.");
|
||||||
|
|
||||||
|
uefi_services::println!("[EFI stub] Loading payload.");
|
||||||
|
let payload = unsafe { crate::get_payload(&*boot_params) };
|
||||||
|
crate::loader::load_elf(payload);
|
||||||
|
|
||||||
uefi_services::println!("[EFI stub] Exiting EFI boot services.");
|
uefi_services::println!("[EFI stub] Exiting EFI boot services.");
|
||||||
let memory_type = {
|
let memory_type = {
|
||||||
let boot_services = system_table.boot_services();
|
let boot_services = system_table.boot_services();
|
||||||
@ -63,14 +67,40 @@ fn efi_phase_boot(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn efi_phase_runtime(
|
fn efi_phase_runtime(
|
||||||
mut system_table: SystemTable<Runtime>,
|
_system_table: SystemTable<Runtime>,
|
||||||
memory_map: MemoryMap<'static>,
|
memory_map: MemoryMap<'static>,
|
||||||
boot_params: *mut BootParams,
|
boot_params_ptr: *mut BootParams,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
crate::console::print_str("[EFI stub] Entered runtime services.\n");
|
crate::console::print_str("[EFI stub] Entered runtime services.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let boot_params = unsafe { &mut *boot_params_ptr };
|
||||||
|
|
||||||
|
// Write memory map to e820 table in boot_params.
|
||||||
|
let e820_table = &mut boot_params.e820_table;
|
||||||
|
let mut e820_entries = 0;
|
||||||
|
for md in memory_map.entries() {
|
||||||
|
if e820_entries >= e820_table.len() || e820_entries >= 128 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e820_table[e820_entries] = linux_boot_params::BootE820Entry {
|
||||||
|
addr: md.phys_start as u64,
|
||||||
|
size: md.page_count as u64 * 4096,
|
||||||
|
typ: match md.ty {
|
||||||
|
uefi::table::boot::MemoryType::CONVENTIONAL => linux_boot_params::E820Type::Ram,
|
||||||
|
uefi::table::boot::MemoryType::RESERVED => linux_boot_params::E820Type::Reserved,
|
||||||
|
uefi::table::boot::MemoryType::ACPI_RECLAIM => linux_boot_params::E820Type::Acpi,
|
||||||
|
uefi::table::boot::MemoryType::ACPI_NON_VOLATILE => {
|
||||||
|
linux_boot_params::E820Type::Nvs
|
||||||
|
}
|
||||||
|
_ => linux_boot_params::E820Type::Reserved,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
e820_entries += 1;
|
||||||
|
}
|
||||||
|
boot_params.e820_entries = e820_entries as u8;
|
||||||
|
|
||||||
#[cfg(feature = "debug_print")]
|
#[cfg(feature = "debug_print")]
|
||||||
unsafe {
|
unsafe {
|
||||||
use crate::console::{print_hex, print_str};
|
use crate::console::{print_hex, print_str};
|
||||||
@ -90,5 +120,5 @@ fn efi_phase_runtime(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::trojan_entry(boot_params as usize);
|
unsafe { super::call_jinux_entrypoint(super::JINUX_ENTRY_POINT, boot_params_ptr as u64) }
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ global_asm!(include_str!("setup.S"));
|
|||||||
|
|
||||||
pub const ASTER_ENTRY_POINT: u32 = 0x8001200;
|
pub const ASTER_ENTRY_POINT: u32 = 0x8001200;
|
||||||
|
|
||||||
pub unsafe fn call_aster_entrypoint(entrypoint: u64, boot_params_ptr: u64) -> ! {
|
unsafe fn call_aster_entrypoint(entrypoint: u64, boot_params_ptr: u64) -> ! {
|
||||||
asm!("mov rsi, {}", in(reg) boot_params_ptr as u64);
|
asm!("mov rsi, {}", in(reg) boot_params_ptr as u64);
|
||||||
asm!("mov rax, {}", in(reg) entrypoint as u64);
|
asm!("mov rax, {}", in(reg) entrypoint as u64);
|
||||||
asm!("jmp rax");
|
asm!("jmp rax");
|
||||||
|
@ -1,19 +1,43 @@
|
|||||||
|
use linux_boot_params::BootParams;
|
||||||
|
|
||||||
use core::arch::{asm, global_asm};
|
use core::arch::{asm, global_asm};
|
||||||
|
|
||||||
global_asm!(include_str!("header.S"));
|
global_asm!(include_str!("header.S"));
|
||||||
|
|
||||||
global_asm!(include_str!("setup.S"));
|
global_asm!(include_str!("setup.S"));
|
||||||
|
|
||||||
#[no_mangle]
|
use crate::console::{print_hex, print_str};
|
||||||
extern "cdecl" fn _trojan_entry_32(boot_params_ptr: u32) -> ! {
|
|
||||||
|
#[export_name = "_trojan_entry_32"]
|
||||||
|
extern "cdecl" fn trojan_entry(boot_params_ptr: u32) -> ! {
|
||||||
// Safety: this init function is only called once.
|
// Safety: this init function is only called once.
|
||||||
unsafe { crate::console::init() };
|
unsafe { crate::console::init() };
|
||||||
crate::trojan_entry(0, boot_params_ptr.try_into().unwrap());
|
|
||||||
|
// println!("[setup] bzImage loaded at {:#x}", x86::relocation::get_image_loaded_offset());
|
||||||
|
unsafe {
|
||||||
|
print_str("[setup] bzImage loaded at ");
|
||||||
|
print_hex(crate::x86::relocation::get_image_loaded_offset() as u64);
|
||||||
|
print_str("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety: the boot_params_ptr is a valid pointer to be borrowed.
|
||||||
|
let boot_params = unsafe { &*(boot_params_ptr as *const BootParams) };
|
||||||
|
// Safety: the payload_offset and payload_length is valid.
|
||||||
|
let payload = crate::get_payload(boot_params);
|
||||||
|
crate::loader::load_elf(payload);
|
||||||
|
|
||||||
|
// Safety: the entrypoint and the ptr is valid.
|
||||||
|
unsafe {
|
||||||
|
call_jinux_entrypoint(
|
||||||
|
super::JINUX_ENTRY_POINT,
|
||||||
|
boot_params_ptr.try_into().unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
|
pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
|
||||||
|
|
||||||
pub unsafe fn call_aster_entrypoint(entrypoint: u32, boot_params_ptr: u32) -> ! {
|
unsafe fn call_aster_entrypoint(entrypoint: u32, boot_params_ptr: u32) -> ! {
|
||||||
asm!("mov esi, {}", in(reg) boot_params_ptr);
|
asm!("mov esi, {}", in(reg) boot_params_ptr);
|
||||||
asm!("mov eax, {}", in(reg) entrypoint);
|
asm!("mov eax, {}", in(reg) entrypoint);
|
||||||
asm!("jmp eax");
|
asm!("jmp eax");
|
||||||
@ -22,6 +46,6 @@ pub unsafe fn call_aster_entrypoint(entrypoint: u32, boot_params_ptr: u32) -> !
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,14 @@ pub fn get_image_loaded_offset() -> isize {
|
|||||||
start_of_setup32 as isize - START_OF_SETUP32_VA as isize
|
start_of_setup32 as isize - START_OF_SETUP32_VA as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
struct Elf64Rela {
|
struct Elf64Rela {
|
||||||
r_offset: u64,
|
r_offset: u64,
|
||||||
r_info: u64,
|
r_info: u64,
|
||||||
r_addend: i64,
|
r_addend: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
fn get_rela_array() -> &'static [Elf64Rela] {
|
fn get_rela_array() -> &'static [Elf64Rela] {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn __rela_dyn_start();
|
fn __rela_dyn_start();
|
||||||
@ -59,6 +61,7 @@ const R_X86_64_RELATIVE: u32 = 8;
|
|||||||
/// This function will modify the memory pointed by the relocations. And the Rust memory safety
|
/// This function will modify the memory pointed by the relocations. And the Rust memory safety
|
||||||
/// mechanisms are not aware of these kind of modification. Failure to do relocations will cause
|
/// mechanisms are not aware of these kind of modification. Failure to do relocations will cause
|
||||||
/// dyn Trait objects to break.
|
/// dyn Trait objects to break.
|
||||||
|
#[allow(unused)]
|
||||||
pub unsafe fn apply_rela_dyn_relocations() {
|
pub unsafe fn apply_rela_dyn_relocations() {
|
||||||
let image_loaded_offset = get_image_loaded_offset();
|
let image_loaded_offset = get_image_loaded_offset();
|
||||||
let relas = get_rela_array();
|
let relas = get_rela_array();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user