diff --git a/framework/libs/linux-bzimage/builder/src/lib.rs b/framework/libs/linux-bzimage/builder/src/lib.rs index 6ab8a7dfa..bbb445d2b 100644 --- a/framework/libs/linux-bzimage/builder/src/lib.rs +++ b/framework/libs/linux-bzimage/builder/src/lib.rs @@ -19,7 +19,7 @@ mod pe_header; use std::{ fs::File, io::{Read, Seek, SeekFrom, Write}, - path::{Path, PathBuf}, + path::Path, }; use mapping::{SetupFileOffset, SetupVA}; @@ -36,23 +36,19 @@ pub enum BzImageType { /// Making a bzImage given the kernel ELF and setup source. /// /// Explanations for the arguments: -/// - `target_image_path`: The path to the target bzImage. -/// - `image_type`: The type of the bzImage that we are building. -/// - `kernel_path`: The path to the kernel ELF. -/// - `setup_tmp_out_dir`: The path to the temporary output directory for the setup binary. -pub fn make_bzimage(target_image_path: &Path, image_type: BzImageType, kernel_path: &Path) { - let setup = match image_type { - BzImageType::Legacy32 => { - let arch = PathBuf::from("../../setup/x86_64-i386_pm-none.json") - .canonicalize() - .unwrap(); - build_setup_with_arch(&SetupBuildArch::Other(arch)) - } - BzImageType::Efi64 => build_setup_with_arch(&SetupBuildArch::X86_64), - }; - +/// - `target_image_path`: The path to the target bzImage; +/// - `image_type`: The type of the bzImage that we are building; +/// - `kernel_path`: The path to the kernel ELF; +/// - `setup_elf_path`: The path to the setup ELF. +/// +pub fn make_bzimage( + target_image_path: &Path, + image_type: BzImageType, + kernel_path: &Path, + setup_elf_path: &Path, +) { let mut setup_elf = Vec::new(); - File::open(setup) + File::open(setup_elf_path) .unwrap() .read_to_end(&mut setup_elf) .unwrap(); @@ -97,9 +93,9 @@ pub fn make_bzimage(target_image_path: &Path, image_type: BzImageType, kernel_pa } } -enum SetupBuildArch { - X86_64, - Other(PathBuf), +/// To build the legacy32 bzImage setup header, the OSDK should use this target. +pub fn legacy32_rust_target_json() -> &'static str { + include_str!("x86_64-i386_pm-none.json") } /// We need a flat binary which satisfies PA delta == File offset delta, @@ -172,50 +168,3 @@ fn fill_legacy_header_fields( &((setup_len + kernel_len) as u32).to_le_bytes(), ); } - -/// Build the setup binary. -/// -/// It will return the path to the built setup binary. -fn build_setup_with_arch(arch: &SetupBuildArch) -> PathBuf { - // Relocations are fewer in release mode. That's why the release mode is more stable than - // the debug mode. - let profile = "release"; - - let mut cmd = std::process::Command::new("cargo"); - cmd.current_dir("../../setup"); - cmd.arg("build"); - if profile == "release" { - cmd.arg("--release"); - } - cmd.arg("--bin").arg("linux-bzimage-setup"); - cmd.arg("--target").arg(match arch { - SetupBuildArch::X86_64 => "x86_64-unknown-none", - SetupBuildArch::Other(path) => path.to_str().unwrap(), - }); - cmd.arg("-Zbuild-std=core,alloc,compiler_builtins"); - cmd.arg("-Zbuild-std-features=compiler-builtins-mem"); - cmd.env_remove("RUSTFLAGS"); - cmd.env_remove("CARGO_ENCODED_RUSTFLAGS"); - - let mut child = cmd.spawn().unwrap(); - let status = child.wait().unwrap(); - if !status.success() { - panic!( - "Failed to build linux x86 setup header:\n\tcommand `{:?}`\n\treturned {}", - cmd, status - ); - } - - // Get the path to the setup binary. - let arch_name = match arch { - SetupBuildArch::X86_64 => "x86_64-unknown-none", - SetupBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(), - }; - - let setup_artifact = PathBuf::from("../../setup/target") - .join(arch_name) - .join(profile) - .join("linux-bzimage-setup"); - - setup_artifact.to_owned() -} diff --git a/framework/libs/linux-bzimage/setup/x86_64-i386_pm-none.json b/framework/libs/linux-bzimage/builder/src/x86_64-i386_pm-none.json similarity index 100% rename from framework/libs/linux-bzimage/setup/x86_64-i386_pm-none.json rename to framework/libs/linux-bzimage/builder/src/x86_64-i386_pm-none.json diff --git a/osdk/src/commands/build/bin.rs b/osdk/src/commands/build/bin.rs index d4f8eb24a..3f6bd6ca6 100644 --- a/osdk/src/commands/build/bin.rs +++ b/osdk/src/commands/build/bin.rs @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 -use linux_bzimage_builder::{make_bzimage, BzImageType}; +use linux_bzimage_builder::{make_bzimage, BzImageType, legacy32_rust_target_json}; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::Command; use std::{ fs::OpenOptions, @@ -15,6 +15,7 @@ use crate::utils::get_current_crate_info; pub fn make_install_bzimage( install_dir: impl AsRef, + target_dir: impl AsRef, aster_elf: &AsterBin, protocol: &BootProtocol, ) -> AsterBin { @@ -24,10 +25,32 @@ pub fn make_install_bzimage( BootProtocol::LinuxEfiHandover64 => BzImageType::Efi64, _ => unreachable!(), }; + let setup_bin = { + let setup_install_dir = target_dir.as_ref(); + let setup_target_dir = &target_dir.as_ref().join("linux-bzimage-setup"); + match image_type { + BzImageType::Legacy32 => { + let target_json = legacy32_rust_target_json(); + let gen_target_json_path = target_dir.as_ref().join("x86_64-i386_pm-none.json"); + std::fs::write(&gen_target_json_path, target_json).unwrap(); + let arch = SetupInstallArch::Other(gen_target_json_path.canonicalize().unwrap()); + install_setup_with_arch(setup_install_dir, setup_target_dir, &arch); + } + BzImageType::Efi64 => { + install_setup_with_arch( + setup_install_dir, + setup_target_dir, + &SetupInstallArch::X86_64, + ); + } + }; + setup_install_dir.join("bin").join("linux-bzimage-setup") + }; // 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); + println!("install_path: {:?}", install_path); + make_bzimage(&install_path, image_type, &aster_elf.path, &setup_bin); AsterBin { path: install_path, @@ -100,3 +123,46 @@ pub fn strip_elf_for_qemu(install_dir: impl AsRef, elf: &AsterBin) -> Aste stripped: true, } } + +enum SetupInstallArch { + X86_64, + Other(PathBuf), +} + +fn install_setup_with_arch( + install_dir: impl AsRef, + target_dir: impl AsRef, + arch: &SetupInstallArch, +) { + if !target_dir.as_ref().exists() { + std::fs::create_dir_all(&target_dir).unwrap(); + } + let target_dir = std::fs::canonicalize(target_dir).unwrap(); + + let mut cmd = Command::new("cargo"); + cmd.env("RUSTFLAGS", "-Ccode-model=kernel -Crelocation-model=pie -Ctarget-feature=+crt-static -Zplt=yes -Zrelax-elf-relocations=yes -Zrelro-level=full"); + cmd.arg("install").arg("linux-bzimage-setup"); + cmd.arg("--force"); + cmd.arg("--root").arg(install_dir.as_ref()); + // TODO: Use the latest revision when modifications on the `osdk` branch is merged. + cmd.arg("--git") + .arg("https://github.com/junyang-zh/asterinas"); + cmd.arg("--branch").arg("osdk"); + cmd.arg("--target").arg(match arch { + SetupInstallArch::X86_64 => "x86_64-unknown-none", + SetupInstallArch::Other(path) => path.to_str().unwrap(), + }); + cmd.arg("-Zbuild-std=core,alloc,compiler_builtins"); + cmd.arg("-Zbuild-std-features=compiler-builtins-mem"); + // Specify the build target directory to avoid cargo running + // into a deadlock reading the workspace files. + cmd.arg("--target-dir").arg(target_dir.as_os_str()); + + let status = cmd.status().unwrap(); + if !status.success() { + panic!( + "Failed to build linux x86 setup header:\n\tcommand `{:?}`\n\treturned {}", + cmd, status + ); + } +} diff --git a/osdk/src/commands/build/grub.rs b/osdk/src/commands/build/grub.rs index a1ff2057a..f8caeb5c0 100644 --- a/osdk/src/commands/build/grub.rs +++ b/osdk/src/commands/build/grub.rs @@ -38,7 +38,12 @@ pub fn create_bootdev_image( // Make the kernel image and place it in the boot directory. match protocol { BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => { - make_install_bzimage(&iso_root.join("boot"), aster_bin, protocol); + make_install_bzimage( + &iso_root.join("boot"), + &target_dir, + aster_bin, + protocol, + ); } BootProtocol::Multiboot | BootProtocol::Multiboot2 => { // Copy the kernel image to the boot directory. diff --git a/osdk/src/commands/build/x86_64-i386_pm-none.json b/osdk/src/commands/build/x86_64-i386_pm-none.json deleted file mode 100644 index e69de29bb..000000000