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