mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Implement OSDK functionalities and opt-in OSDK for asterinas
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
bc9bce9dea
commit
f97d0f1260
102
osdk/src/commands/build/bin.rs
Normal file
102
osdk/src/commands/build/bin.rs
Normal file
@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use linux_bzimage_builder::{make_bzimage, BzImageType};
|
||||
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::{
|
||||
fs::OpenOptions,
|
||||
io::{Seek, SeekFrom, Write},
|
||||
};
|
||||
|
||||
use crate::bin::{AsterBin, AsterBinType, AsterBzImageMeta, AsterElfMeta};
|
||||
use crate::config_manager::boot::BootProtocol;
|
||||
use crate::utils::get_current_crate_info;
|
||||
|
||||
pub fn make_install_bzimage(
|
||||
install_dir: impl AsRef<Path>,
|
||||
aster_elf: &AsterBin,
|
||||
protocol: &BootProtocol,
|
||||
) -> AsterBin {
|
||||
let target_name = get_current_crate_info().name;
|
||||
let image_type = match protocol {
|
||||
BootProtocol::LinuxLegacy32 => BzImageType::Legacy32,
|
||||
BootProtocol::LinuxEfiHandover64 => BzImageType::Efi64,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Make the `bzImage`-compatible kernel image and place it in the boot directory.
|
||||
let install_path = install_dir.as_ref().join(&target_name);
|
||||
info!("Building bzImage");
|
||||
make_bzimage(&install_path, image_type, &aster_elf.path);
|
||||
|
||||
AsterBin {
|
||||
path: install_path,
|
||||
typ: AsterBinType::BzImage(AsterBzImageMeta {
|
||||
support_legacy32_boot: matches!(protocol, BootProtocol::LinuxLegacy32),
|
||||
support_efi_boot: false,
|
||||
support_efi_handover: matches!(protocol, BootProtocol::LinuxEfiHandover64),
|
||||
}),
|
||||
version: aster_elf.version.clone(),
|
||||
sha256sum: "TODO".to_string(),
|
||||
stripped: aster_elf.stripped,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn strip_elf_for_qemu(install_dir: impl AsRef<Path>, elf: &AsterBin) -> AsterBin {
|
||||
let stripped_elf_path = {
|
||||
let elf_name = elf.path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
install_dir.as_ref().join(elf_name + ".stripped.elf")
|
||||
};
|
||||
|
||||
// We use rust-strip to reduce the kernel image size.
|
||||
let status = Command::new("rust-strip")
|
||||
.arg(&elf.path)
|
||||
.arg("-o")
|
||||
.arg(stripped_elf_path.as_os_str())
|
||||
.status();
|
||||
|
||||
match status {
|
||||
Ok(status) => {
|
||||
if !status.success() {
|
||||
panic!("Failed to strip kernel elf.");
|
||||
}
|
||||
}
|
||||
Err(err) => match err.kind() {
|
||||
std::io::ErrorKind::NotFound => panic!(
|
||||
"`rust-strip` command not found. Please
|
||||
try `cargo install cargo-binutils` and then rerun."
|
||||
),
|
||||
_ => panic!("Strip kernel elf failed, err:{:#?}", err),
|
||||
},
|
||||
}
|
||||
|
||||
// Because QEMU denies a x86_64 multiboot ELF file (GRUB2 accept it, btw),
|
||||
// modify `em_machine` to pretend to be an x86 (32-bit) ELF image,
|
||||
//
|
||||
// https://github.com/qemu/qemu/blob/950c4e6c94b15cd0d8b63891dddd7a8dbf458e6a/hw/i386/multiboot.c#L197
|
||||
// Set EM_386 (0x0003) to em_machine.
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&stripped_elf_path)
|
||||
.unwrap();
|
||||
|
||||
let bytes: [u8; 2] = [0x03, 0x00];
|
||||
|
||||
file.seek(SeekFrom::Start(18)).unwrap();
|
||||
file.write_all(&bytes).unwrap();
|
||||
file.flush().unwrap();
|
||||
|
||||
AsterBin {
|
||||
path: stripped_elf_path,
|
||||
typ: AsterBinType::Elf(AsterElfMeta {
|
||||
has_linux_header: false,
|
||||
has_pvh_header: false,
|
||||
has_multiboot_header: true,
|
||||
has_multiboot2_header: true,
|
||||
}),
|
||||
version: elf.version.clone(),
|
||||
sha256sum: "TODO".to_string(),
|
||||
stripped: true,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user