diff --git a/src/boot/limine/scripts/limine-build.sh b/src/boot/limine/scripts/limine-build.sh index 1fbd9b6ae..726712409 100755 --- a/src/boot/limine/scripts/limine-build.sh +++ b/src/boot/limine/scripts/limine-build.sh @@ -18,7 +18,8 @@ cd - # Copy the needed files into an ISO image. mkdir -p target/iso_root -cp $KERNEL boot/limine/conf/limine.cfg target/iso_root +cp $KERNEL target/iso_root/jinux +cp boot/limine/conf/limine.cfg target/iso_root cp target/limine/limine.sys target/iso_root cp target/limine/limine-cd.bin target/iso_root cp target/limine/limine-cd-efi.bin target/iso_root diff --git a/src/boot/src/main.rs b/src/boot/src/main.rs index 3d0f39610..92b943a25 100644 --- a/src/boot/src/main.rs +++ b/src/boot/src/main.rs @@ -1,6 +1,7 @@ use anyhow::anyhow; use std::{ fs::OpenOptions, + ops::Add, path::{Path, PathBuf}, process::{Command, ExitStatus}, time::Duration, @@ -23,7 +24,7 @@ const COMMON_ARGS: &[&str] = &[ const RUN_ARGS: &[&str] = &["-s"]; const TEST_ARGS: &[&str] = &[]; -const TEST_TIMEOUT_SECS: u64 = 10; +const TEST_TIMEOUT_SECS: u64 = 30; fn main() -> anyhow::Result<()> { let mut args = std::env::args().skip(1); let kernel_binary_path = { @@ -46,9 +47,14 @@ fn main() -> anyhow::Result<()> { let kernel_iso_path = { let a = kernel_binary_path.parent().unwrap(); - a.join("jinux.iso") + let str = kernel_binary_path + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string(); + a.join(str.add(".iso")) }; - // let bios = create_disk_images(&kernel_binary_path); if no_boot { println!("Created disk image at `{}`", kernel_iso_path.display()); @@ -68,6 +74,7 @@ fn main() -> anyhow::Result<()> { if binary_kind.is_test() { args.append(&mut TEST_ARGS.to_vec()); run_cmd.args(args); + println!("running:{:?}", run_cmd); let exit_status = run_test_command(run_cmd)?; match exit_status.code() { @@ -77,6 +84,7 @@ fn main() -> anyhow::Result<()> { } else { args.append(&mut RUN_ARGS.to_vec()); run_cmd.args(args); + println!("running:{:?}", run_cmd); let exit_status = run_cmd.status()?; if !exit_status.success() { diff --git a/src/build.rs b/src/build.rs index 88d3e8c2f..88a466e2a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -6,12 +6,7 @@ fn main() -> Result<(), Box> { } fn limine_build_script() -> Result<(), Box> { - // Get the name of the package. - let kernel_name = env::var("CARGO_PKG_NAME")?; - - // Tell rustc to pass the linker script to the linker. - println!("cargo:rustc-link-arg-bin={kernel_name}=--script=boot/limine/conf/linker.ld"); - + // Have cargo rerun this script if the linker script or CARGO_PKG_ENV changes. println!("cargo:rerun-if-changed=boot/limine/conf/linker.ld"); println!("cargo:rerun-if-env-changed=CARGO_PKG_NAME"); diff --git a/src/framework/jinux-frame/src/lib.rs b/src/framework/jinux-frame/src/lib.rs index 932f0bdd5..214362c4a 100644 --- a/src/framework/jinux-frame/src/lib.rs +++ b/src/framework/jinux-frame/src/lib.rs @@ -35,7 +35,6 @@ pub(crate) mod x86_64_util; pub use self::error::Error; pub use self::prelude::Result; -pub(crate) use self::sync::up::UPSafeCell; use alloc::vec::Vec; use core::{mem, panic::PanicInfo}; pub use device::serial::receive_char; diff --git a/src/framework/jinux-frame/src/mm/frame_allocator.rs b/src/framework/jinux-frame/src/mm/frame_allocator.rs index 627f08c22..b0f81fab7 100644 --- a/src/framework/jinux-frame/src/mm/frame_allocator.rs +++ b/src/framework/jinux-frame/src/mm/frame_allocator.rs @@ -1,19 +1,18 @@ use alloc::vec::Vec; +use spin::Mutex; -use crate::{config::PAGE_SIZE, vm::Paddr, UPSafeCell}; +use crate::{config::PAGE_SIZE, vm::Paddr}; use super::address::PhysAddr; use lazy_static::lazy_static; lazy_static! { - static ref FRAME_ALLOCATOR: UPSafeCell = unsafe { - UPSafeCell::new(FreeListAllocator { - current: 0, - end: 0, - free_list: Vec::new(), - }) - }; + static ref FRAME_ALLOCATOR: Mutex = Mutex::new(FreeListAllocator { + current: 0, + end: 0, + free_list: Vec::new(), + }); } trait FrameAllocator { @@ -62,7 +61,7 @@ impl PhysFrame { pub fn alloc() -> Option { FRAME_ALLOCATOR - .exclusive_access() + .lock() .alloc() .map(|pa| Self { start_pa: pa }) } @@ -73,7 +72,7 @@ impl PhysFrame { } pub fn dealloc(pa: usize) { - FRAME_ALLOCATOR.exclusive_access().dealloc(pa) + FRAME_ALLOCATOR.lock().dealloc(pa) } pub fn alloc_zero() -> Option { @@ -93,11 +92,11 @@ impl PhysFrame { impl Drop for PhysFrame { fn drop(&mut self) { - FRAME_ALLOCATOR.exclusive_access().dealloc(self.start_pa); + FRAME_ALLOCATOR.lock().dealloc(self.start_pa); } } pub(crate) fn init(start: usize, size: usize) { - FRAME_ALLOCATOR.exclusive_access().current = start; - FRAME_ALLOCATOR.exclusive_access().end = start + size; + FRAME_ALLOCATOR.lock().current = start; + FRAME_ALLOCATOR.lock().end = start + size; } diff --git a/src/framework/jinux-frame/src/mm/page_table.rs b/src/framework/jinux-frame/src/mm/page_table.rs index cd41772a1..cdae5422f 100644 --- a/src/framework/jinux-frame/src/mm/page_table.rs +++ b/src/framework/jinux-frame/src/mm/page_table.rs @@ -1,17 +1,23 @@ -use super::{memory_set::MapArea, *}; +use super::{ + address::{PhysAddr, VirtAddr}, + memory_set::MapArea, + PTFlags, +}; use crate::{ config::{ENTRY_COUNT, PAGE_SIZE, PHYS_OFFSET}, + println, vm::VmFrame, - *, + x86_64_util, }; use ::log::info; use alloc::{collections::BTreeMap, vec, vec::Vec}; use core::{fmt, panic}; use lazy_static::lazy_static; +use spin::Mutex; lazy_static! { - pub(crate) static ref ALL_MAPPED_PTE: UPSafeCell> = - unsafe { UPSafeCell::new(BTreeMap::new()) }; + pub(crate) static ref ALL_MAPPED_PTE: Mutex> = + Mutex::new(BTreeMap::new()); } #[derive(Clone, Copy)] @@ -58,7 +64,7 @@ impl PageTable { pub fn new() -> Self { let root_frame = VmFrame::alloc_zero().unwrap(); let p4 = table_of(root_frame.start_pa()); - let map_pte = ALL_MAPPED_PTE.exclusive_access(); + let map_pte = ALL_MAPPED_PTE.lock(); for (index, pte) in map_pte.iter() { p4[*index] = *pte; } @@ -262,7 +268,7 @@ pub(crate) fn init() { // Cancel mapping in lowest addresses. p4[0].0 = 0; // there is mapping where index is 1,2,3, so user may not use these value - let mut map_pte = ALL_MAPPED_PTE.exclusive_access(); + let mut map_pte = ALL_MAPPED_PTE.lock(); for i in 0..512 { if p4[i].flags().contains(PTFlags::PRESENT) { map_pte.insert(i, p4[i]); diff --git a/src/framework/jinux-frame/src/sync/mod.rs b/src/framework/jinux-frame/src/sync/mod.rs index a6e3eb308..ea9720b7c 100644 --- a/src/framework/jinux-frame/src/sync/mod.rs +++ b/src/framework/jinux-frame/src/sync/mod.rs @@ -1,7 +1,6 @@ mod atomic_bits; mod rcu; mod spin; -pub(crate) mod up; mod wait; pub use self::atomic_bits::AtomicBits; diff --git a/src/framework/jinux-frame/src/sync/up.rs b/src/framework/jinux-frame/src/sync/up.rs deleted file mode 100644 index 6a7ea836c..000000000 --- a/src/framework/jinux-frame/src/sync/up.rs +++ /dev/null @@ -1,36 +0,0 @@ -use core::cell::{Ref, RefCell, RefMut}; - -#[derive(Debug)] -/// Wrap a static data structure inside it so that we are -/// able to access it without any `unsafe`. -/// -/// We should only use it in uniprocessor. -/// -/// In order to get mutable reference of inner data, call -/// `exclusive_access`. -pub(crate) struct UPSafeCell { - /// inner data - inner: RefCell, -} - -unsafe impl Sync for UPSafeCell {} - -impl UPSafeCell { - /// User is responsible to guarantee that inner struct is only used in - /// uniprocessor. - pub unsafe fn new(value: T) -> Self { - Self { - inner: RefCell::new(value), - } - } - - /// Panic if the data has been borrowed. - pub fn exclusive_access(&self) -> RefMut<'_, T> { - self.inner.borrow_mut() - } - - /// Panic if the data has been borrowed. - pub fn get_ref(&self) -> Ref<'_, T> { - self.inner.borrow() - } -} diff --git a/src/framework/jinux-frame/src/task/processor.rs b/src/framework/jinux-frame/src/task/processor.rs index d84a2e750..2e7b93d3d 100644 --- a/src/framework/jinux-frame/src/task/processor.rs +++ b/src/framework/jinux-frame/src/task/processor.rs @@ -3,9 +3,9 @@ use super::{ task::{context_switch, TaskContext}, Task, TaskStatus, }; -use crate::UPSafeCell; use alloc::sync::Arc; -use lazy_static::*; +use lazy_static::lazy_static; +use spin::Mutex; pub struct Processor { current: Option>, @@ -34,19 +34,19 @@ impl Processor { } lazy_static! { - static ref PROCESSOR: UPSafeCell = unsafe { UPSafeCell::new(Processor::new()) }; + static ref PROCESSOR: Mutex = Mutex::new(Processor::new()); } pub fn take_current_task() -> Option> { - PROCESSOR.exclusive_access().take_current() + PROCESSOR.lock().take_current() } pub fn current_task() -> Option> { - PROCESSOR.exclusive_access().current() + PROCESSOR.lock().current() } pub(crate) fn get_idle_task_cx_ptr() -> *mut TaskContext { - PROCESSOR.exclusive_access().get_idle_task_cx_ptr() + PROCESSOR.lock().get_idle_task_cx_ptr() } /// call this function to switch to other task by using GLOBAL_SCHEDULER @@ -68,19 +68,17 @@ pub fn switch_to_task(next_task: Arc) { let next_task_cx_ptr = &next_task.inner_ctx() as *const TaskContext; let current_task: Arc; let current_task_cx_ptr = if current_task_option.is_none() { - PROCESSOR.exclusive_access().get_idle_task_cx_ptr() + PROCESSOR.lock().get_idle_task_cx_ptr() } else { current_task = current_task_option.unwrap(); if current_task.status() != TaskStatus::Exited { - GLOBAL_SCHEDULER - .exclusive_access() - .enqueue(current_task.clone()); + GLOBAL_SCHEDULER.lock().enqueue(current_task.clone()); } &mut current_task.inner_exclusive_access().ctx as *mut TaskContext }; // change the current task to the next task - PROCESSOR.exclusive_access().current = Some(next_task.clone()); + PROCESSOR.lock().current = Some(next_task.clone()); unsafe { context_switch(current_task_cx_ptr, next_task_cx_ptr); } diff --git a/src/framework/jinux-frame/src/task/scheduler.rs b/src/framework/jinux-frame/src/task/scheduler.rs index c31816146..52b949798 100644 --- a/src/framework/jinux-frame/src/task/scheduler.rs +++ b/src/framework/jinux-frame/src/task/scheduler.rs @@ -1,11 +1,12 @@ +use crate::prelude::*; use crate::task::Task; -use crate::{prelude::*, UPSafeCell}; use lazy_static::lazy_static; +use spin::Mutex; lazy_static! { - pub(crate) static ref GLOBAL_SCHEDULER: UPSafeCell = - unsafe { UPSafeCell::new(GlobalScheduler { scheduler: None }) }; + pub(crate) static ref GLOBAL_SCHEDULER: Mutex = + Mutex::new(GlobalScheduler { scheduler: None }); } /// A scheduler for tasks. @@ -42,13 +43,13 @@ impl GlobalScheduler { /// /// This must be called before invoking `Task::spawn`. pub fn set_scheduler(scheduler: &'static dyn Scheduler) { - GLOBAL_SCHEDULER.exclusive_access().scheduler = Some(scheduler); + GLOBAL_SCHEDULER.lock().scheduler = Some(scheduler); } pub fn fetch_task() -> Option> { - GLOBAL_SCHEDULER.exclusive_access().dequeue() + GLOBAL_SCHEDULER.lock().dequeue() } pub fn add_task(task: Arc) { - GLOBAL_SCHEDULER.exclusive_access().enqueue(task); + GLOBAL_SCHEDULER.lock().enqueue(task); } diff --git a/src/framework/jinux-frame/src/task/task.rs b/src/framework/jinux-frame/src/task/task.rs index d05adf9c0..f40f7dcfe 100644 --- a/src/framework/jinux-frame/src/task/task.rs +++ b/src/framework/jinux-frame/src/task/task.rs @@ -1,15 +1,15 @@ -use core::cell::RefMut; use core::mem::size_of; use lazy_static::lazy_static; +use spin::{Mutex, MutexGuard}; use crate::cell::Cell; use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE}; +use crate::prelude::*; use crate::task::processor::switch_to_task; use crate::trap::{CalleeRegs, SyscallFrame, TrapFrame}; use crate::user::{syscall_switch_to_user_space, trap_switch_to_user_space, UserSpace}; use crate::vm::{VmAllocOptions, VmFrameVec}; -use crate::{prelude::*, UPSafeCell}; use intrusive_collections::intrusive_adapter; use intrusive_collections::LinkedListAtomicLink; @@ -60,20 +60,18 @@ lazy_static! { func: Box::new(context_switch_to_user_space), data: Box::new(None::), user_space: None, - task_inner: unsafe { - UPSafeCell::new(TaskInner { + task_inner: Mutex::new(TaskInner { task_status: TaskStatus::Runnable, ctx: TaskContext::default(), is_from_trap:false, - }) - }, + }), exit_code: usize::MAX, kstack: KernelStack::new(), link: LinkedListAtomicLink::new(), }; - task.task_inner.exclusive_access().task_status = TaskStatus::Runnable; - task.task_inner.exclusive_access().ctx.rip = context_switch_to_user_space as usize; - task.task_inner.exclusive_access().ctx.regs.rsp = (task.kstack.frame.end_pa().unwrap().kvaddr().0 + task.task_inner.lock().task_status = TaskStatus::Runnable; + task.task_inner.lock().ctx.rip = context_switch_to_user_space as usize; + task.task_inner.lock().ctx.regs.rsp = (task.kstack.frame.end_pa().unwrap().kvaddr().0 - size_of::() - size_of::()) as u64; task @@ -98,7 +96,7 @@ pub struct Task { func: Box, data: Box, user_space: Option>, - task_inner: UPSafeCell, + task_inner: Mutex, exit_code: usize, /// kernel stack, note that the top is SyscallFrame/TrapFrame kstack: KernelStack, @@ -122,13 +120,13 @@ impl Task { } /// get inner - pub(crate) fn inner_exclusive_access(&self) -> RefMut<'_, TaskInner> { - self.task_inner.exclusive_access() + pub(crate) fn inner_exclusive_access(&self) -> MutexGuard<'_, TaskInner> { + self.task_inner.lock() } /// get inner pub(crate) fn inner_ctx(&self) -> TaskContext { - self.task_inner.exclusive_access().ctx + self.task_inner.lock().ctx } /// Yields execution so that another task may be scheduled. @@ -165,24 +163,21 @@ impl Task { func: Box::new(task_fn), data: Box::new(task_data), user_space, - task_inner: unsafe { - UPSafeCell::new(TaskInner { - task_status: TaskStatus::Runnable, - ctx: TaskContext::default(), - is_from_trap: false, - }) - }, + task_inner: Mutex::new(TaskInner { + task_status: TaskStatus::Runnable, + ctx: TaskContext::default(), + is_from_trap: false, + }), exit_code: 0, kstack: KernelStack::new(), link: LinkedListAtomicLink::new(), }; - result.task_inner.exclusive_access().task_status = TaskStatus::Runnable; - result.task_inner.exclusive_access().ctx.rip = kernel_task_entry as usize; - result.task_inner.exclusive_access().ctx.regs.rsp = - (result.kstack.frame.end_pa().unwrap().kvaddr().0 - - size_of::() - - size_of::()) as u64; + result.task_inner.lock().task_status = TaskStatus::Runnable; + result.task_inner.lock().ctx.rip = kernel_task_entry as usize; + result.task_inner.lock().ctx.regs.rsp = (result.kstack.frame.end_pa().unwrap().kvaddr().0 + - size_of::() + - size_of::()) as u64; let arc_self = Arc::new(result); switch_to_task(arc_self.clone()); @@ -210,24 +205,21 @@ impl Task { func: Box::new(task_fn), data: Box::new(task_data), user_space, - task_inner: unsafe { - UPSafeCell::new(TaskInner { - task_status: TaskStatus::Runnable, - ctx: TaskContext::default(), - is_from_trap: false, - }) - }, + task_inner: Mutex::new(TaskInner { + task_status: TaskStatus::Runnable, + ctx: TaskContext::default(), + is_from_trap: false, + }), exit_code: 0, kstack: KernelStack::new(), link: LinkedListAtomicLink::new(), }; - result.task_inner.exclusive_access().task_status = TaskStatus::Runnable; - result.task_inner.exclusive_access().ctx.rip = kernel_task_entry as usize; - result.task_inner.exclusive_access().ctx.regs.rsp = - (result.kstack.frame.end_pa().unwrap().kvaddr().0 - - size_of::() - - size_of::()) as u64; + result.task_inner.lock().task_status = TaskStatus::Runnable; + result.task_inner.lock().ctx.rip = kernel_task_entry as usize; + result.task_inner.lock().ctx.regs.rsp = (result.kstack.frame.end_pa().unwrap().kvaddr().0 + - size_of::() + - size_of::()) as u64; Ok(Arc::new(result)) } @@ -264,7 +256,7 @@ impl Task { /// Returns the task status. pub fn status(&self) -> TaskStatus { - self.task_inner.exclusive_access().task_status + self.task_inner.lock().task_status } /// Returns the task data. diff --git a/src/tests/console_input.rs b/src/tests/console_input.rs index 057d23ec8..0b508c7bf 100644 --- a/src/tests/console_input.rs +++ b/src/tests/console_input.rs @@ -3,19 +3,15 @@ #![feature(custom_test_frameworks)] #![test_runner(jinux_frame::test_runner)] #![reexport_test_harness_main = "test_main"] -use bootloader::{entry_point, BootInfo}; extern crate alloc; -use alloc::sync::Arc; use core::panic::PanicInfo; use jinux_frame::println; static mut INPUT_VALUE: u8 = 0; -entry_point!(kernel_test_main); - -fn kernel_test_main(boot_info: &'static mut BootInfo) -> ! { - jinux_frame::init(boot_info); - jinux_std::driver::tty::init(); +#[no_mangle] +pub extern "C" fn _start() -> ! { + jinux_frame::init(); test_main(); loop {} } @@ -34,11 +30,12 @@ fn test_input() { while INPUT_VALUE == 0 { jinux_frame::hlt(); } - println!("input value:{}", INPUT_VALUE); + // println!("input value:{}", INPUT_VALUE); } } pub fn input_callback(input: u8) { + println!("input value:{}", input); unsafe { INPUT_VALUE = input; } diff --git a/src/tests/rtc.rs b/src/tests/rtc.rs index 94394213e..1d4af243b 100644 --- a/src/tests/rtc.rs +++ b/src/tests/rtc.rs @@ -3,18 +3,15 @@ #![feature(custom_test_frameworks)] #![test_runner(jinux_frame::test_runner)] #![reexport_test_harness_main = "test_main"] -use bootloader::{entry_point, BootInfo}; extern crate alloc; -use alloc::sync::Arc; use core::panic::PanicInfo; use jinux_frame::println; static mut INPUT_VALUE: u8 = 0; -entry_point!(kernel_test_main); - -fn kernel_test_main(boot_info: &'static mut BootInfo) -> ! { - jinux_frame::init(boot_info); +#[no_mangle] +pub extern "C" fn _start() -> ! { + jinux_frame::init(); test_main(); loop {} } diff --git a/src/tests/test_example.rs b/src/tests/test_example.rs index ec75ca4ce..9d0b8896e 100644 --- a/src/tests/test_example.rs +++ b/src/tests/test_example.rs @@ -3,13 +3,11 @@ #![feature(custom_test_frameworks)] #![test_runner(jinux_frame::test_runner)] #![reexport_test_harness_main = "test_main"] -use bootloader::{entry_point, BootInfo}; use core::panic::PanicInfo; -entry_point!(kernel_test_main); - -fn kernel_test_main(boot_info: &'static mut BootInfo) -> ! { - jinux_frame::init(boot_info); +#[no_mangle] +pub extern "C" fn _start() -> ! { + jinux_frame::init(); test_main(); loop {} } diff --git a/src/tests/timer_test.rs b/src/tests/timer_test.rs index efc6023ce..7139b40b4 100644 --- a/src/tests/timer_test.rs +++ b/src/tests/timer_test.rs @@ -3,7 +3,6 @@ #![feature(custom_test_frameworks)] #![test_runner(jinux_frame::test_runner)] #![reexport_test_harness_main = "test_main"] -use bootloader::{entry_point, BootInfo}; use jinux_frame::timer::Timer; extern crate alloc; use alloc::sync::Arc; @@ -13,10 +12,9 @@ use jinux_frame::println; static mut TICK: usize = 0; -entry_point!(kernel_test_main); - -fn kernel_test_main(boot_info: &'static mut BootInfo) -> ! { - jinux_frame::init(boot_info); +#[no_mangle] +pub extern "C" fn _start() -> ! { + jinux_frame::init(); test_main(); loop {} } diff --git a/src/x86_64-custom.json b/src/x86_64-custom.json index a8d940d72..1861bb12e 100644 --- a/src/x86_64-custom.json +++ b/src/x86_64-custom.json @@ -1,17 +1,20 @@ { - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "pre-link-args": { - }, - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" - } \ No newline at end of file + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "pre-link-args": { + "ld.lld": [ + "-Tboot/limine/conf/linker.ld" + ] + }, + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" +}