diff --git a/.github/workflows/cargo_check.yml b/.github/workflows/cargo_check.yml index 610e4535..2d2071be 100644 --- a/.github/workflows/cargo_check.yml +++ b/.github/workflows/cargo_check.yml @@ -10,9 +10,9 @@ on: jobs: test: runs-on: ubuntu-latest - container: jinuxdev/jinux:0.1.1 + container: jinuxdev/jinux:0.1.2 steps: - - run: echo "Running in jinuxdev/jinux:0.1.1" + - run: echo "Running in jinuxdev/jinux:0.1.2" - uses: actions/checkout@v3 diff --git a/.github/workflows/syscall_test.yml b/.github/workflows/syscall_test.yml index 2f69546b..e154c88d 100644 --- a/.github/workflows/syscall_test.yml +++ b/.github/workflows/syscall_test.yml @@ -10,9 +10,9 @@ on: jobs: test: runs-on: ubuntu-latest - container: jinuxdev/jinux:0.1.1 + container: jinuxdev/jinux:0.1.2 steps: - - run: echo "Running in jinuxdev/jinux:0.1.1" + - run: echo "Running in jinuxdev/jinux:0.1.2" - uses: actions/checkout@v3 @@ -20,8 +20,8 @@ jobs: id: syscall_test_mb2 run: RUSTFLAGS="-C opt-level=1" make run AUTO_SYSCALL_TEST=1 ENABLE_KVM=0 SKIP_GRUB_MENU=1 BOOT_METHOD=grub-multiboot2 - - name: Syscall Test (Linux Boot Protocol) - id: syscall_test_lbp - run: RUSTFLAGS="-C opt-level=1" make run AUTO_SYSCALL_TEST=1 ENABLE_KVM=0 SKIP_GRUB_MENU=1 BOOT_METHOD=grub-linux - - # TODO: include the integration tests for Multiboot and MicroVM, which are not ready yet. + # TODO: include the integration tests for Multiboot/MicroVM/Linux boot methods, which are not ready yet. + + # - name: Syscall Test (Linux Boot Protocol) + # id: syscall_test_lbp + # run: RUSTFLAGS="-C opt-level=1" make run AUTO_SYSCALL_TEST=1 ENABLE_KVM=0 SKIP_GRUB_MENU=1 BOOT_METHOD=grub-linux diff --git a/Cargo.lock b/Cargo.lock index 74feb13d..ba3e2ee1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -599,7 +599,7 @@ dependencies = [ [[package]] name = "jinux" -version = "0.1.1" +version = "0.1.2" dependencies = [ "component", "jinux-frame", @@ -659,6 +659,10 @@ dependencies = [ "x86_64", ] +[[package]] +name = "jinux-frame-x86-boot-setup" +version = "0.1.0" + [[package]] name = "jinux-framebuffer" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 8781c7d0..1dc0a8a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jinux" -version = "0.1.1" +version = "0.1.2" edition = "2021" [[bin]] @@ -22,6 +22,7 @@ jinux-framebuffer = { path = "services/comps/framebuffer" } members = [ "build", "framework/jinux-frame", + "framework/jinux-frame/src/arch/x86/boot/linux_boot/setup", "framework/libs/align_ext", "services/comps/virtio", "services/comps/input", diff --git a/Makefile b/Makefile index 6de05d6c..e48a0f5b 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,8 @@ export export JINUX_BOOT_PROTOCOL=$(BOOT_PROTOCOL) -# GNU toolchain variables +# Toolchain variables +export CARGO := cargo export AS := as export CC := gcc export OBJCOPY := objcopy diff --git a/README.md b/README.md index 5ef71180..b9a70bc4 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ git clone [repository url] 2. After downloading the source code, run the following command to pull the development image. ```bash -docker pull jinuxdev/jinux:0.1.1 +docker pull jinuxdev/jinux:0.1.2 ``` 3. Start the development container. ```bash -docker run -it --privileged --network=host --device=/dev/kvm -v `pwd`:/root/jinux jinuxdev/jinux:0.1.1 +docker run -it --privileged --network=host --device=/dev/kvm -v `pwd`:/root/jinux jinuxdev/jinux:0.1.2 ``` **All build and test commands should be run inside the development container.** diff --git a/VERSION b/VERSION index 17e51c38..d917d3e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 diff --git a/build.rs b/build.rs index 8ca97eca..2c864375 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,7 @@ use std::{error::Error, path::PathBuf}; fn main() -> Result<(), Box> { - let linker_script_path = get_source_dir() + let linker_script_path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .join("framework") .join("jinux-frame") .join("src") @@ -9,19 +9,8 @@ fn main() -> Result<(), Box> { .join("x86") .join("boot") .join("linker.ld"); - println!( - "cargo:rerun-if-changed={}", - linker_script_path.to_str().unwrap() - ); - println!( - "cargo:rustc-link-arg=-T{}", - linker_script_path.to_str().unwrap() - ); + println!("cargo:rerun-if-changed={}", linker_script_path.display()); + println!("cargo:rustc-link-arg=-T{}", linker_script_path.display()); println!("cargo:rerun-if-env-changed=CARGO_PKG_NAME"); Ok(()) } - -fn get_source_dir() -> PathBuf { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); - PathBuf::from(manifest_dir) -} diff --git a/build/src/machine/default.rs b/build/src/machine/default.rs index 31e2fa20..81af6cca 100644 --- a/build/src/machine/default.rs +++ b/build/src/machine/default.rs @@ -63,7 +63,9 @@ pub fn create_bootdev_image( // Find the setup header in the build script output directory. let out_dir = glob("target/x86_64-custom/debug/build/jinux-frame-*").unwrap(); let header_bin = Path::new(out_dir.into_iter().next().unwrap().unwrap().as_path()) - .join("out/linux_header.bin"); + .join("out") + .join("bin") + .join("jinux-frame-x86-boot-setup.bin"); // Deliver the kernel image to the boot directory. match protocol { diff --git a/framework/jinux-frame/build.rs b/framework/jinux-frame/build.rs index 6259b1ea..ab669ae6 100644 --- a/framework/jinux-frame/build.rs +++ b/framework/jinux-frame/build.rs @@ -5,59 +5,65 @@ fn main() -> Result<(), Box> { Ok(()) } -fn get_source_dir() -> PathBuf { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); - PathBuf::from(manifest_dir) -} - -fn get_header_out_dir() -> PathBuf { - PathBuf::from(std::env::var("OUT_DIR").unwrap()) -} - fn build_linux_setup_header() -> Result<(), Box> { - // Compile the header to raw binary. - let linux_boot_header_asm_path = get_source_dir() + // 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()); + let setup_crate_dir = source_dir .join("src") .join("arch") .join("x86") .join("boot") .join("linux_boot") - .join("header.S"); + .join("setup"); + let target_json = setup_crate_dir.join("x86_64-i386_protected_mode.json"); + println!( "cargo:rerun-if-changed={}", - linux_boot_header_asm_path.to_str().unwrap() + setup_crate_dir.to_str().unwrap() ); - let linux_boot_header_elf_path = get_header_out_dir().join("linux_header.o"); - let gas = std::env::var("AS").unwrap(); - let mut cmd = std::process::Command::new(gas); - cmd.arg(linux_boot_header_asm_path); - cmd.arg("-o") - .arg(linux_boot_header_elf_path.to_str().unwrap()); + + 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("--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"); + cmd.arg("--root").arg(out_dir.as_os_str()); + cmd.env_remove("RUSTFLAGS"); + cmd.env_remove("CARGO_ENCODED_RUSTFLAGS"); let output = cmd.output()?; if !output.status.success() { std::io::stdout().write_all(&output.stdout).unwrap(); std::io::stderr().write_all(&output.stderr).unwrap(); - panic!( - "Failed to compile linux boot header:\n\tcommand `{:?}`\n\treturned {}", + return Err(format!( + "Failed to build linux x86 setup header::\n\tcommand `{:?}`\n\treturned {}", cmd, output.status - ); + ) + .into()); } + // Strip the elf header to get the raw header. - let linux_boot_header_bin_path = get_header_out_dir().join("linux_header.bin"); + 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(".boot_compatibility_bin"); - cmd.arg(linux_boot_header_elf_path.to_str().unwrap()); - cmd.arg(linux_boot_header_bin_path.to_str().unwrap()); + cmd.arg("-j").arg(".boot_real_mode"); + 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(); - panic!( + return Err(format!( "Failed to strip linux boot header:\n\tcommand `{:?}`\n\treturned {}", cmd, output.status - ); + ) + .into()); } Ok(()) } diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/Cargo.toml b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/Cargo.toml new file mode 100644 index 00000000..7eb687be --- /dev/null +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "jinux-frame-x86-boot-setup" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/build.rs b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/build.rs new file mode 100644 index 00000000..41a9b831 --- /dev/null +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/build.rs @@ -0,0 +1,9 @@ +use std::path::PathBuf; + +fn main() { + let source_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + println!( + "cargo:rustc-link-arg-bins=--script={}", + source_dir.join("linker.ld").display() + ) +} diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/linker.ld b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/linker.ld new file mode 100644 index 00000000..bfc95aa7 --- /dev/null +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/linker.ld @@ -0,0 +1,22 @@ +ENTRY(start_of_setup) +OUTPUT_ARCH(i386:x86) +OUTPUT_FORMAT(elf32-i386) + +SETUP_LMA = 0x1000; + +SECTIONS +{ + . = SETUP_LMA; + + .boot_real_mode : AT(ADDR(.boot_real_mode) - SETUP_LMA) { KEEP(*(.boot_real_mode)) } + + .text : AT(ADDR(.text) - SETUP_LMA) { *(.text .text.*) } + .rodata : AT(ADDR(.rodata) - SETUP_LMA) { *(.rodata .rodata.*) } + + .data : AT(ADDR(.data) - SETUP_LMA) { *(.data .data.*) } + .bss : AT(ADDR(.bss) - SETUP_LMA) { + __bss = .; + *(.bss .bss.*) *(COMMON) + __bss_end = .; + } +} diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/header.S b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/header.S similarity index 95% rename from framework/jinux-frame/src/arch/x86/boot/linux_boot/header.S rename to framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/header.S index 591e80bd..69f436a9 100644 --- a/framework/jinux-frame/src/arch/x86/boot/linux_boot/header.S +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/header.S @@ -2,11 +2,9 @@ // See https://www.kernel.org/doc/html/v5.6/x86/boot.html for // more information on the Linux x86 Boot Protocol. -.intel_syntax noprefix - // The section name is used by the build script to strip and make // the binary file. -.section ".boot_compatibility_bin", "awx" +.section ".boot_real_mode", "awx" // The Linux x86 Boot Protocol header. // @@ -68,7 +66,8 @@ kernel_info_offset: .long 0 .align 16 real_gdtr: .word gdt_end - gdt - 1 - .quad gdt + .long 0 # upper 32-bit address of GDT + .long gdt # lower 32-bit address of GDT .align 16 gdt: diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/main.rs b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/main.rs new file mode 100644 index 00000000..e3882107 --- /dev/null +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/src/main.rs @@ -0,0 +1,11 @@ +#![no_std] +#![no_main] + +use core::arch::global_asm; + +global_asm!(include_str!("header.S")); + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/x86_64-i386_protected_mode.json b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/x86_64-i386_protected_mode.json new file mode 100644 index 00000000..55ce0b1a --- /dev/null +++ b/framework/jinux-frame/src/arch/x86/boot/linux_boot/setup/x86_64-i386_protected_mode.json @@ -0,0 +1,20 @@ +{ + "llvm-target": "i386-unknown-none", + "data-layout": "e-m:e-i32:32-f80:128-n8:16:32-S128-p:32:32", + "cpu": "i386", + "arch": "x86", + "dynamic-linking": false, + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "max-atomic-width": 64, + "position-independent-executables": false, + "disable-redzone": true, + "target-c-int-width": "32", + "target-pointer-width": "32", + "target-endian": "little", + "panic-strategy": "abort", + "os": "none", + "relocation-model": "static", + "features": "+soft-float,-sse,-mmx" +} \ No newline at end of file diff --git a/framework/jinux-frame/src/lib.rs b/framework/jinux-frame/src/lib.rs index 5d587192..36f3a36c 100644 --- a/framework/jinux-frame/src/lib.rs +++ b/framework/jinux-frame/src/lib.rs @@ -9,7 +9,7 @@ #![feature(core_intrinsics)] #![feature(new_uninit)] #![feature(strict_provenance)] -#![feature(link_llvm_intrinsics)] +//#![feature(link_llvm_intrinsics)] #![feature(const_trait_impl)] #![feature(generators)] #![feature(iter_from_generator)] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 175237df..32a937f8 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-08-01" +channel = "nightly-2023-10-05" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/services/libs/comp-sys/cargo-component/tests/test_utils/mod.rs b/services/libs/comp-sys/cargo-component/tests/test_utils/mod.rs index 6ef8c6ee..0ce24978 100644 --- a/services/libs/comp-sys/cargo-component/tests/test_utils/mod.rs +++ b/services/libs/comp-sys/cargo-component/tests/test_utils/mod.rs @@ -24,7 +24,7 @@ static CARGO_COMPONENT_PATH: LazyLock = LazyLock::new(|| { }); pub fn run_cargo_component(test_name: &str) -> String { - let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); let target_dir = root_dir.join("target").join(test_name); let cwd = root_dir.join("tests").join(test_name); let output = cargo_clean(&cwd, &target_dir); diff --git a/services/libs/comp-sys/component-macro/src/priority.rs b/services/libs/comp-sys/component-macro/src/priority.rs index 04f7243f..3f7db6ea 100644 --- a/services/libs/comp-sys/component-macro/src/priority.rs +++ b/services/libs/comp-sys/component-macro/src/priority.rs @@ -199,7 +199,7 @@ fn calculate_priority( } fn metadata() -> json::JsonValue { - let mut cmd = Command::new(env!("CARGO")); + let mut cmd = Command::new(std::env::var("CARGO").unwrap()); cmd.arg("metadata"); cmd.arg("--format-version").arg("1"); let output = cmd.output().unwrap();