Bring both EFI and legacy to test
This commit is contained in:
		
							parent
							
								
									487e0cdd15
								
							
						
					
					
						commit
						432f0c34b0
					
				| 
						 | 
				
			
			@ -28,22 +28,23 @@ jobs:
 | 
			
		|||
        id: boot_test_microvm
 | 
			
		||||
        run: make run AUTO_TEST=boot ENABLE_KVM=0 BOOT_METHOD=microvm RELEASE_MODE=1
 | 
			
		||||
 | 
			
		||||
      - name: Boot Test (Linux Boot Protocol)
 | 
			
		||||
        id: boot_test_linux
 | 
			
		||||
        run: make run AUTO_TEST=boot ENABLE_KVM=0 BOOT_PROTOCOL=linux RELEASE_MODE=1
 | 
			
		||||
      - name: Boot Test (Linux Legacy 32-bit Boot Protocol)
 | 
			
		||||
        id: boot_test_linux_legacy32
 | 
			
		||||
        run: make run AUTO_TEST=boot ENABLE_KVM=0 BOOT_PROTOCOL=linux-legacy32 RELEASE_MODE=1
 | 
			
		||||
 | 
			
		||||
      - name: Syscall Test (MicroVM)
 | 
			
		||||
        id: syscall_test_microvm
 | 
			
		||||
        run: make run AUTO_TEST=syscall ENABLE_KVM=0 BOOT_METHOD=microvm RELEASE_MODE=1
 | 
			
		||||
      - name: Boot Test (Linux EFI Handover Boot Protocol)
 | 
			
		||||
        id: syscall_test_linux_efi_handover64
 | 
			
		||||
        run: make run AUTO_TEST=boot ENABLE_KVM=0 BOOT_PROTOCOL=linux-efi-handover64 RELEASE_MODE=1
 | 
			
		||||
 | 
			
		||||
      - name: Syscall Test at Ext2 (Linux Boot Protocol)
 | 
			
		||||
      - name: Syscall Test at Ext2 (Linux EFI Handover Boot Protocol)
 | 
			
		||||
        id: syscall_test_at_ext2_linux
 | 
			
		||||
        run: make run AUTO_TEST=syscall SYSCALL_TEST_DIR=/ext2 ENABLE_KVM=0 BOOT_PROTOCOL=linux RELEASE_MODE=1
 | 
			
		||||
        run: make run AUTO_TEST=syscall SYSCALL_TEST_DIR=/ext2 ENABLE_KVM=0 BOOT_PROTOCOL=linux-efi-handover64 RELEASE_MODE=1
 | 
			
		||||
 | 
			
		||||
      - name: Syscall Test at Ext2 (MicroVM)
 | 
			
		||||
        id: syscall_test_at_ext2_microvm
 | 
			
		||||
        run: make run AUTO_TEST=syscall SYSCALL_TEST_DIR=/ext2 ENABLE_KVM=0 BOOT_METHOD=microvm RELEASE_MODE=1
 | 
			
		||||
        
 | 
			
		||||
      - name: Regression Test (Linux Boot Protocol)
 | 
			
		||||
      - name: Regression Test (MicroVM)
 | 
			
		||||
        id: regression_test_linux
 | 
			
		||||
        run: make run AUTO_TEST=regression ENABLE_KVM=0 BOOT_PROTOCOL=linux RELEASE_MODE=1
 | 
			
		||||
        run: make run AUTO_TEST=regression ENABLE_KVM=0 BOOT_METHOD=microvm RELEASE_MODE=1
 | 
			
		||||
        
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +10,3 @@ bytemuck = { version = "1.14.0", features = ["derive"] }
 | 
			
		|||
bitflags = "1.3"
 | 
			
		||||
serde = { version = "1.0.192", features = ["derive"] }
 | 
			
		||||
xmas-elf = "0.9.1"
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
default = ["trojan64"]
 | 
			
		||||
trojan64 = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
//! This crate is responsible for building the bzImage. It contains methods to build
 | 
			
		||||
//! the wrapper binary and methods to build the bzImage.
 | 
			
		||||
//!
 | 
			
		||||
//! We should build the jinux kernel as a ELF file, and feed it to the builder to
 | 
			
		||||
//! We should build the asterinas kernel as a ELF file, and feed it to the builder to
 | 
			
		||||
//! generate the bzImage. The builder will generate the PE/COFF header for the wrapper
 | 
			
		||||
//! and concatenate it to the ELF file to make the bzImage.
 | 
			
		||||
//!
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ mod pe_header;
 | 
			
		|||
 | 
			
		||||
use std::{
 | 
			
		||||
    fs::File,
 | 
			
		||||
    io::{Read, Write},
 | 
			
		||||
    io::{Read, Seek, SeekFrom, Write},
 | 
			
		||||
    path::{Path, PathBuf},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ use mapping::{WrapperFileOffset, WrapperVA};
 | 
			
		|||
///
 | 
			
		||||
/// 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 trojan_to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
 | 
			
		||||
fn wrapper_to_flat_binary(elf_file: &[u8]) -> Vec<u8> {
 | 
			
		||||
    let elf = xmas_elf::ElfFile::new(&elf_file).unwrap();
 | 
			
		||||
    let mut bin = Vec::<u8>::new();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ fn fill_header_field(header: &mut [u8], offset: usize, value: &[u8]) {
 | 
			
		|||
fn fill_legacy_header_fields(
 | 
			
		||||
    header: &mut [u8],
 | 
			
		||||
    kernel_len: usize,
 | 
			
		||||
    trojan_len: usize,
 | 
			
		||||
    wrapper_len: usize,
 | 
			
		||||
    payload_offset: WrapperVA,
 | 
			
		||||
) {
 | 
			
		||||
    fill_header_field(
 | 
			
		||||
| 
						 | 
				
			
			@ -90,29 +90,44 @@ fn fill_legacy_header_fields(
 | 
			
		|||
    fill_header_field(
 | 
			
		||||
        header,
 | 
			
		||||
        0x260, /* init_size */
 | 
			
		||||
        &((trojan_len + kernel_len) as u32).to_le_bytes(),
 | 
			
		||||
        &((wrapper_len + kernel_len) as u32).to_le_bytes(),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_out: &Path) {
 | 
			
		||||
    #[cfg(feature = "trojan64")]
 | 
			
		||||
    let wrapper = build_trojan_with_arch(trojan_src, trojan_out, &TrojanBuildArch::X86_64);
 | 
			
		||||
/// The type of the bzImage that we are building through `make_bzimage`.
 | 
			
		||||
///
 | 
			
		||||
/// Currently, Legacy32 and Efi64 are mutually exclusive.
 | 
			
		||||
pub enum BzImageType {
 | 
			
		||||
    Legacy32,
 | 
			
		||||
    Efi64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    #[cfg(not(feature = "trojan64"))]
 | 
			
		||||
    let wrapper = {
 | 
			
		||||
        let arch = trojan_src
 | 
			
		||||
            .join("x86_64-i386_pm-none.json")
 | 
			
		||||
            .canonicalize()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        build_trojan_with_arch(trojan_src, trojan_out, &TrojanBuildArch::Other(arch))
 | 
			
		||||
pub fn make_bzimage(
 | 
			
		||||
    image_path: &Path,
 | 
			
		||||
    kernel_path: &Path,
 | 
			
		||||
    image_type: BzImageType,
 | 
			
		||||
    wrapper_src: &Path,
 | 
			
		||||
    wrapper_out: &Path,
 | 
			
		||||
) {
 | 
			
		||||
    let wrapper = match image_type {
 | 
			
		||||
        BzImageType::Legacy32 => {
 | 
			
		||||
            let arch = wrapper_src
 | 
			
		||||
                .join("x86_64-i386_pm-none.json")
 | 
			
		||||
                .canonicalize()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            build_wrapper_with_arch(wrapper_src, wrapper_out, &WrapperBuildArch::Other(arch))
 | 
			
		||||
        }
 | 
			
		||||
        BzImageType::Efi64 => {
 | 
			
		||||
            build_wrapper_with_arch(wrapper_src, wrapper_out, &WrapperBuildArch::X86_64)
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let mut trojan_elf = Vec::new();
 | 
			
		||||
    let mut wrapper_elf = Vec::new();
 | 
			
		||||
    File::open(wrapper)
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .read_to_end(&mut trojan_elf)
 | 
			
		||||
        .read_to_end(&mut wrapper_elf)
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    let mut wrapper = trojan_to_flat_binary(&trojan_elf);
 | 
			
		||||
    let mut wrapper = wrapper_to_flat_binary(&wrapper_elf);
 | 
			
		||||
    // Pad the header with 8-byte alignment.
 | 
			
		||||
    wrapper.resize((wrapper.len() + 7) & !7, 0x00);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,28 +138,32 @@ pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_o
 | 
			
		|||
        .unwrap();
 | 
			
		||||
    let payload = kernel;
 | 
			
		||||
 | 
			
		||||
    let trojan_len = wrapper.len();
 | 
			
		||||
    let wrapper_len = wrapper.len();
 | 
			
		||||
    let payload_len = payload.len();
 | 
			
		||||
    let payload_offset = WrapperFileOffset::from(trojan_len);
 | 
			
		||||
    fill_legacy_header_fields(&mut wrapper, payload_len, trojan_len, payload_offset.into());
 | 
			
		||||
    let payload_offset = WrapperFileOffset::from(wrapper_len);
 | 
			
		||||
    fill_legacy_header_fields(
 | 
			
		||||
        &mut wrapper,
 | 
			
		||||
        payload_len,
 | 
			
		||||
        wrapper_len,
 | 
			
		||||
        payload_offset.into(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let mut kernel_image = File::create(path).unwrap();
 | 
			
		||||
    let mut kernel_image = File::create(image_path).unwrap();
 | 
			
		||||
    kernel_image.write_all(&wrapper).unwrap();
 | 
			
		||||
    kernel_image.write_all(&payload).unwrap();
 | 
			
		||||
 | 
			
		||||
    let image_size = trojan_len + payload_len;
 | 
			
		||||
    let image_size = wrapper_len + payload_len;
 | 
			
		||||
 | 
			
		||||
    // Since the Linux boot header starts at 0x1f1, we can write the PE/COFF header directly to the
 | 
			
		||||
    // start of the file without overwriting the Linux boot header.
 | 
			
		||||
    let pe_header = pe_header::make_pe_coff_header(&trojan_elf, image_size);
 | 
			
		||||
    assert!(
 | 
			
		||||
        pe_header.header_at_zero.len() <= 0x1f1,
 | 
			
		||||
        "PE/COFF header is too large"
 | 
			
		||||
    );
 | 
			
		||||
    if matches!(image_type, BzImageType::Efi64) {
 | 
			
		||||
        // Write the PE/COFF header to the start of the file.
 | 
			
		||||
        // Since the Linux boot header starts at 0x1f1, we can write the PE/COFF header directly to the
 | 
			
		||||
        // start of the file without overwriting the Linux boot header.
 | 
			
		||||
        let pe_header = pe_header::make_pe_coff_header(&wrapper_elf, image_size);
 | 
			
		||||
        assert!(
 | 
			
		||||
            pe_header.header_at_zero.len() <= 0x1f1,
 | 
			
		||||
            "PE/COFF header is too large"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "trojan64")]
 | 
			
		||||
    {
 | 
			
		||||
        use std::io::{Seek, SeekFrom};
 | 
			
		||||
        kernel_image.seek(SeekFrom::Start(0)).unwrap();
 | 
			
		||||
        kernel_image.write_all(&pe_header.header_at_zero).unwrap();
 | 
			
		||||
        kernel_image
 | 
			
		||||
| 
						 | 
				
			
			@ -154,19 +173,15 @@ pub fn make_bzimage(path: &Path, kernel_path: &Path, trojan_src: &Path, trojan_o
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// We need a custom target file for i386 but not for x86_64.
 | 
			
		||||
// The compiler may warn us the X86_64 enum variant is not constructed
 | 
			
		||||
// when we are building for i386, but we can ignore it.
 | 
			
		||||
#[allow(dead_code)]
 | 
			
		||||
enum TrojanBuildArch {
 | 
			
		||||
enum WrapperBuildArch {
 | 
			
		||||
    X86_64,
 | 
			
		||||
    Other(PathBuf),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Build the trojan binary.
 | 
			
		||||
/// Build the wrapper binary.
 | 
			
		||||
///
 | 
			
		||||
/// It will return the path to the built trojan binary.
 | 
			
		||||
fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildArch) -> PathBuf {
 | 
			
		||||
/// It will return the path to the built wrapper binary.
 | 
			
		||||
fn build_wrapper_with_arch(source_dir: &Path, out_dir: &Path, arch: &WrapperBuildArch) -> PathBuf {
 | 
			
		||||
    if !out_dir.exists() {
 | 
			
		||||
        std::fs::create_dir_all(&out_dir).unwrap();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -185,8 +200,8 @@ fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildA
 | 
			
		|||
    }
 | 
			
		||||
    cmd.arg("--package").arg("aster-boot-wrapper");
 | 
			
		||||
    cmd.arg("--target").arg(match arch {
 | 
			
		||||
        TrojanBuildArch::X86_64 => "x86_64-unknown-none",
 | 
			
		||||
        TrojanBuildArch::Other(path) => path.to_str().unwrap(),
 | 
			
		||||
        WrapperBuildArch::X86_64 => "x86_64-unknown-none",
 | 
			
		||||
        WrapperBuildArch::Other(path) => path.to_str().unwrap(),
 | 
			
		||||
    });
 | 
			
		||||
    cmd.arg("-Zbuild-std=core,alloc,compiler_builtins");
 | 
			
		||||
    cmd.arg("-Zbuild-std-features=compiler-builtins-mem");
 | 
			
		||||
| 
						 | 
				
			
			@ -207,14 +222,14 @@ fn build_trojan_with_arch(source_dir: &Path, out_dir: &Path, arch: &TrojanBuildA
 | 
			
		|||
 | 
			
		||||
    // Get the path to the wrapper binary.
 | 
			
		||||
    let arch_name = match arch {
 | 
			
		||||
        TrojanBuildArch::X86_64 => "x86_64-unknown-none",
 | 
			
		||||
        TrojanBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
 | 
			
		||||
        WrapperBuildArch::X86_64 => "x86_64-unknown-none",
 | 
			
		||||
        WrapperBuildArch::Other(path) => path.file_stem().unwrap().to_str().unwrap(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let trojan_artifact = out_dir
 | 
			
		||||
    let wrapper_artifact = out_dir
 | 
			
		||||
        .join(arch_name)
 | 
			
		||||
        .join(profile)
 | 
			
		||||
        .join("aster-boot-wrapper");
 | 
			
		||||
 | 
			
		||||
    trojan_artifact.to_owned()
 | 
			
		||||
    wrapper_artifact.to_owned()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ pub fn load_elf(file: &[u8]) {
 | 
			
		|||
 | 
			
		||||
    for ph in elf.program_iter() {
 | 
			
		||||
        let ProgramHeader::Ph64(program) = ph else {
 | 
			
		||||
            panic!("[setup] Unexpected program header type! Jinux should be 64-bit ELF binary.");
 | 
			
		||||
            panic!("[setup] Unexpected program header type! Asterinas should be 64-bit ELF binary.");
 | 
			
		||||
        };
 | 
			
		||||
        if program.get_type().unwrap() == xmas_elf::program::Type::Load {
 | 
			
		||||
            load_segment(&elf, program);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,10 +122,10 @@ fn efi_phase_runtime(
 | 
			
		|||
 | 
			
		||||
    unsafe {
 | 
			
		||||
        use crate::console::{print_hex, print_str};
 | 
			
		||||
        print_str("[EFI stub] Entering Jinux entrypoint at ");
 | 
			
		||||
        print_hex(super::JINUX_ENTRY_POINT as u64);
 | 
			
		||||
        print_str("[EFI stub] Entering Asterinas entrypoint at ");
 | 
			
		||||
        print_hex(super::ASTER_ENTRY_POINT as u64);
 | 
			
		||||
        print_str("\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsafe { super::call_jinux_entrypoint(super::JINUX_ENTRY_POINT, boot_params_ptr as u64) }
 | 
			
		||||
    unsafe { super::call_aster_entrypoint(super::ASTER_ENTRY_POINT, boot_params_ptr as u64) }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ global_asm!(include_str!("setup.S"));
 | 
			
		|||
 | 
			
		||||
use crate::console::{print_hex, print_str};
 | 
			
		||||
 | 
			
		||||
pub const JINUX_ENTRY_POINT: u32 = 0x8001000;
 | 
			
		||||
pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
 | 
			
		||||
 | 
			
		||||
#[export_name = "_trojan_entry_32"]
 | 
			
		||||
extern "cdecl" fn trojan_entry(boot_params_ptr: u32) -> ! {
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ extern "cdecl" fn trojan_entry(boot_params_ptr: u32) -> ! {
 | 
			
		|||
    crate::loader::load_elf(payload);
 | 
			
		||||
 | 
			
		||||
    // Safety: the entrypoint and the ptr is valid.
 | 
			
		||||
    unsafe { call_jinux_entrypoint(JINUX_ENTRY_POINT, boot_params_ptr.try_into().unwrap()) };
 | 
			
		||||
    unsafe { call_aster_entrypoint(ASTER_ENTRY_POINT, boot_params_ptr.try_into().unwrap()) };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub const ASTER_ENTRY_POINT: u32 = 0x8001000;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,8 @@ use std::{fs::OpenOptions, io::Write, path::PathBuf, process::Command};
 | 
			
		|||
///
 | 
			
		||||
/// If argument `gdb_grub` is set true, it will run GRUB's gdb script.
 | 
			
		||||
///
 | 
			
		||||
/// Make sure to set GRUB_PREFIX to the actual GRUB you are using.
 | 
			
		||||
///
 | 
			
		||||
/// When debugging grub, the OVMF firmware will load the grub kernel at an
 | 
			
		||||
/// address unknown at the moment. You should use the debug message from our
 | 
			
		||||
/// custom built OVMF firmware and read the entrypoint address
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
use aster_boot_wrapper_builder::make_bzimage;
 | 
			
		||||
use aster_boot_wrapper_builder::{make_bzimage, BzImageType};
 | 
			
		||||
 | 
			
		||||
use std::{
 | 
			
		||||
    fs,
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +64,13 @@ pub const IOMMU_DEVICE_ARGS: &[&str] = &[
 | 
			
		|||
    "ioh3420,id=pcie.0,chassis=1",
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
// To test legacy boot, use the following:
 | 
			
		||||
// pub const GRUB_PREFIX: &str = "/usr/local/grub";
 | 
			
		||||
/// The default GRUB tools used.
 | 
			
		||||
pub const GRUB_PREFIX: &str = "/usr";
 | 
			
		||||
/// The GRUB version that defaults to use EFI handover. Which is the Debian APT version.
 | 
			
		||||
pub const GRUB_PREFIX_EFI_HANDOVER: &str = "/usr";
 | 
			
		||||
/// The GRUB version that uses Loadfile2 and has a fallback to use legacy boot. Which is the custom built upstream 2.12 verion.
 | 
			
		||||
pub const GRUB_PREFIX_EFI_AND_LEGACY: &str = "/usr/local/grub";
 | 
			
		||||
 | 
			
		||||
pub const GRUB_VERSION: &str = "x86_64-efi";
 | 
			
		||||
 | 
			
		||||
pub fn create_bootdev_image(
 | 
			
		||||
| 
						 | 
				
			
			@ -92,17 +96,23 @@ pub fn create_bootdev_image(
 | 
			
		|||
    .unwrap();
 | 
			
		||||
 | 
			
		||||
    let target_path = match protocol {
 | 
			
		||||
        BootProtocol::Linux => {
 | 
			
		||||
            let trojan_src = Path::new("framework/libs/boot-wrapper/wrapper");
 | 
			
		||||
            let trojan_out = Path::new("target/aster-boot-wrapper");
 | 
			
		||||
        BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => {
 | 
			
		||||
            let image_type = match protocol {
 | 
			
		||||
                BootProtocol::LinuxLegacy32 => BzImageType::Legacy32,
 | 
			
		||||
                BootProtocol::LinuxEfiHandover64 => BzImageType::Efi64,
 | 
			
		||||
                _ => unreachable!(),
 | 
			
		||||
            };
 | 
			
		||||
            let wrapper_src = Path::new("framework/libs/boot-wrapper/wrapper");
 | 
			
		||||
            let wrapper_out = Path::new("target/aster-boot-wrapper");
 | 
			
		||||
            // Make the `bzImage`-compatible kernel image and place it in the boot directory.
 | 
			
		||||
            let target_path = iso_root.join("boot").join("asterinaz");
 | 
			
		||||
            println!("[aster-runner] Building bzImage.");
 | 
			
		||||
            make_bzimage(
 | 
			
		||||
                &target_path,
 | 
			
		||||
                &aster_path.as_path(),
 | 
			
		||||
                &trojan_src,
 | 
			
		||||
                &trojan_out,
 | 
			
		||||
                image_type,
 | 
			
		||||
                &wrapper_src,
 | 
			
		||||
                &wrapper_out,
 | 
			
		||||
            );
 | 
			
		||||
            target_path
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +131,13 @@ pub fn create_bootdev_image(
 | 
			
		|||
 | 
			
		||||
    // Make the boot device CDROM image.
 | 
			
		||||
    let iso_path = target_dir.join(target_name.to_string() + ".iso");
 | 
			
		||||
    let grub_mkrescue_bin = PathBuf::from(GRUB_PREFIX).join("bin").join("grub-mkrescue");
 | 
			
		||||
    let grub_mkrescue_bin = match protocol {
 | 
			
		||||
        BootProtocol::LinuxLegacy32 => PathBuf::from(GRUB_PREFIX_EFI_AND_LEGACY),
 | 
			
		||||
        BootProtocol::LinuxEfiHandover64 => PathBuf::from(GRUB_PREFIX_EFI_HANDOVER),
 | 
			
		||||
        BootProtocol::Multiboot | BootProtocol::Multiboot2 => PathBuf::from(GRUB_PREFIX),
 | 
			
		||||
    }
 | 
			
		||||
    .join("bin")
 | 
			
		||||
    .join("grub-mkrescue");
 | 
			
		||||
    let mut cmd = std::process::Command::new(grub_mkrescue_bin.as_os_str());
 | 
			
		||||
    cmd.arg("--output").arg(&iso_path).arg(iso_root.as_os_str());
 | 
			
		||||
    if !cmd.status().unwrap().success() {
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +182,7 @@ pub fn generate_grub_cfg(
 | 
			
		|||
            .replace("#GRUB_CMD_KERNEL#", "multiboot2")
 | 
			
		||||
            .replace("#KERNEL#", "/boot/atserinas")
 | 
			
		||||
            .replace("#GRUB_CMD_INITRAMFS#", "module2 --nounzip"),
 | 
			
		||||
        BootProtocol::Linux => buffer
 | 
			
		||||
        BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => buffer
 | 
			
		||||
            .replace("#GRUB_CMD_KERNEL#", "linux")
 | 
			
		||||
            .replace("#KERNEL#", "/boot/asterinaz")
 | 
			
		||||
            .replace("#GRUB_CMD_INITRAMFS#", "initrd"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,8 @@ enum BootMethod {
 | 
			
		|||
pub enum BootProtocol {
 | 
			
		||||
    Multiboot,
 | 
			
		||||
    Multiboot2,
 | 
			
		||||
    Linux,
 | 
			
		||||
    LinuxLegacy32,
 | 
			
		||||
    LinuxEfiHandover64,
 | 
			
		||||
}
 | 
			
		||||
/// The CLI of this runner.
 | 
			
		||||
#[derive(Parser, Debug)]
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +57,8 @@ struct Args {
 | 
			
		|||
    /// Boot protocol. Can be one of the following items:
 | 
			
		||||
    ///  - `multiboot`;
 | 
			
		||||
    ///  - `multiboot2`;
 | 
			
		||||
    ///  - `linux`.
 | 
			
		||||
    ///  - `linux-legacy32`;
 | 
			
		||||
    ///  - `linux-efi-handover64`.
 | 
			
		||||
    #[arg(long, value_enum, default_value_t = BootProtocol::Multiboot2)]
 | 
			
		||||
    boot_protocol: BootProtocol,
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue