mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 19:33:23 +00:00
Successfully entered setup rust entrypoint
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
922fbd0c91
commit
052fc795a5
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -647,6 +647,7 @@ dependencies = [
|
||||
"volatile",
|
||||
"x86",
|
||||
"x86_64",
|
||||
"xmas-elf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
1
Makefile
1
Makefile
@ -58,7 +58,6 @@ export
|
||||
|
||||
# Toolchain variables that are used when building the Linux setup header
|
||||
export CARGO := cargo
|
||||
export OBJCOPY := objcopy
|
||||
|
||||
.PHONY: all setup build tools run test docs check clean
|
||||
|
||||
|
@ -30,5 +30,8 @@ aml = "0.16.3"
|
||||
multiboot2 = "0.16.0"
|
||||
rsdp = "2.0.0"
|
||||
|
||||
[build-dependencies]
|
||||
xmas-elf = "0.8.0"
|
||||
|
||||
[features]
|
||||
intel_tdx = ["dep:tdx-guest"]
|
||||
|
@ -1,14 +1,26 @@
|
||||
use std::{error::Error, io::Write, path::PathBuf};
|
||||
use std::{
|
||||
error::Error,
|
||||
io::{Seek, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use xmas_elf::program::{ProgramHeader, SegmentData};
|
||||
|
||||
const SETUP32_LMA: usize = 0x100000;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
build_linux_setup_header()?;
|
||||
let source_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
build_linux_setup_header(&source_dir, &out_dir)?;
|
||||
copy_to_raw_binary(&out_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_linux_setup_header() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
// Build the setup header to raw binary.
|
||||
let source_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
fn build_linux_setup_header(
|
||||
source_dir: &Path,
|
||||
out_dir: &Path,
|
||||
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
// Build the setup header to ELF.
|
||||
let setup_crate_dir = source_dir
|
||||
.join("src")
|
||||
.join("arch")
|
||||
@ -26,12 +38,17 @@ fn build_linux_setup_header() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
let cargo = std::env::var("CARGO").unwrap();
|
||||
let mut cmd = std::process::Command::new(cargo);
|
||||
cmd.arg("install").arg("jinux-frame-x86-boot-setup");
|
||||
cmd.arg("--debug");
|
||||
cmd.arg("--locked");
|
||||
cmd.arg("--path").arg(setup_crate_dir.to_str().unwrap());
|
||||
cmd.arg("--target").arg(target_json.as_os_str());
|
||||
cmd.arg("-Zbuild-std=core,compiler_builtins");
|
||||
cmd.arg("-Zbuild-std-features=compiler-builtins-mem");
|
||||
// Specify the installation root.
|
||||
cmd.arg("--root").arg(out_dir.as_os_str());
|
||||
// Specify the build target directory to avoid cargo running
|
||||
// into a deadlock reading the workspace files.
|
||||
cmd.arg("--target-dir").arg(out_dir.as_os_str());
|
||||
cmd.env_remove("RUSTFLAGS");
|
||||
cmd.env_remove("CARGO_ENCODED_RUSTFLAGS");
|
||||
let output = cmd.output()?;
|
||||
@ -45,31 +62,46 @@ fn build_linux_setup_header() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// We need a binary which satisfies `LMA == File_Offset`, 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 copy_to_raw_binary(out_dir: &Path) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
// Strip the elf header to get the raw header.
|
||||
let elf_path = out_dir.join("bin").join("jinux-frame-x86-boot-setup");
|
||||
let bin_path = out_dir.join("bin").join("jinux-frame-x86-boot-setup.bin");
|
||||
|
||||
let objcopy = std::env::var("OBJCOPY").unwrap();
|
||||
let mut cmd = std::process::Command::new(objcopy);
|
||||
cmd.arg("-O").arg("binary");
|
||||
cmd.arg("-j").arg(".header");
|
||||
cmd.arg("-j").arg(".text");
|
||||
cmd.arg("-j").arg(".rodata");
|
||||
cmd.arg("-j").arg(".data");
|
||||
cmd.arg("-j").arg(".bss");
|
||||
cmd.arg("-j").arg(".eh_frame");
|
||||
cmd.arg("-j").arg(".eh_frame_hdr");
|
||||
cmd.arg(elf_path.to_str().unwrap());
|
||||
cmd.arg(bin_path.to_str().unwrap());
|
||||
let output = cmd.output()?;
|
||||
if !output.status.success() {
|
||||
std::io::stdout().write_all(&output.stdout).unwrap();
|
||||
std::io::stderr().write_all(&output.stderr).unwrap();
|
||||
return Err(format!(
|
||||
"Failed to strip linux boot header:\n\tcommand `{:?}`\n\treturned {}",
|
||||
cmd, output.status
|
||||
)
|
||||
.into());
|
||||
let elf_file = std::fs::read(elf_path)?;
|
||||
let elf = xmas_elf::ElfFile::new(&elf_file)?;
|
||||
|
||||
let bin_file = std::fs::File::create(bin_path)?;
|
||||
let mut bin_writer = std::io::BufWriter::new(bin_file);
|
||||
|
||||
for ph in elf.program_iter() {
|
||||
let ProgramHeader::Ph32(program) = ph else {
|
||||
return Err("Unexpected program header type".into());
|
||||
};
|
||||
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||
let dest_file_offset = program.virtual_addr as usize - SETUP32_LMA;
|
||||
bin_writer.seek(std::io::SeekFrom::End(0))?;
|
||||
let cur_file_offset = bin_writer.stream_position().unwrap() as usize;
|
||||
if cur_file_offset < dest_file_offset {
|
||||
let padding = vec![0; dest_file_offset - cur_file_offset];
|
||||
bin_writer.write_all(&padding)?;
|
||||
} else {
|
||||
bin_writer.seek(std::io::SeekFrom::Start(dest_file_offset as u64))?;
|
||||
}
|
||||
let SegmentData::Undefined(header_data) = program.get_data(&elf).unwrap() else {
|
||||
return Err("Unexpected segment data type".into());
|
||||
};
|
||||
bin_writer.write_all(header_data)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
.code16
|
||||
.org 0x01f1
|
||||
hdr:
|
||||
hdr_start:
|
||||
SETUP_SECTS = 4
|
||||
setup_sects: .byte SETUP_SECTS
|
||||
root_flags: .word 1
|
||||
@ -26,7 +26,7 @@ vid_mode: .word 0xfffd
|
||||
root_dev: .word 0
|
||||
boot_flag: .word 0xAA55
|
||||
jump: .byte 0xeb
|
||||
jump_addr: .byte start_of_setup32-jump_addr
|
||||
jump_addr: .byte hdr_end-jump_addr
|
||||
magic: .ascii "HdrS"
|
||||
.word 0x020f
|
||||
realmode_swtch: .word 0, 0
|
||||
@ -58,12 +58,12 @@ pref_address: .quad 0
|
||||
init_size: .long 0xabababab # at 0x260/4, to be filled by the runner
|
||||
handover_offset: .long 0
|
||||
kernel_info_offset: .long 0
|
||||
|
||||
hdr_end:
|
||||
// End of header.
|
||||
|
||||
// 32-bit setup code starts here.
|
||||
// 32-bit setup code starts here, and will be loaded at code32_start (0x100000).
|
||||
.code32
|
||||
start_of_setup32:
|
||||
.org 0x200 * (SETUP_SECTS + 1)
|
||||
start_of_setup32:
|
||||
.extern _rust_setup_entry
|
||||
jmp _rust_setup_entry
|
||||
|
Reference in New Issue
Block a user