From cf104ecf28583c4dc491f29b75eb208993d3d38e Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 22 Mar 2022 15:37:33 +0200 Subject: [PATCH] feature: x86_64 serial console --- Makefile | 3 +- kernel/src/arch/x86_64/boot/mod.rs | 5 +- kernel/src/arch/x86_64/intc.rs | 1 + kernel/src/arch/x86_64/irq_vectors.S | 24 +- kernel/src/arch/x86_64/mod.rs | 5 +- kernel/src/arch/x86_64/uart.rs | 36 +- kernel/src/arch/x86_64/virt/table.rs | 1 - kernel/src/mem/virt/table.rs | 1 + kernel/src/proc/wait.rs | 27 +- kernel/src/syscall/mod.rs | 613 +++++++++++++-------------- user/src/init/main.rs | 30 +- 11 files changed, 397 insertions(+), 349 deletions(-) diff --git a/Makefile b/Makefile index 00e88e7..48f730d 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,8 @@ MACH=none QEMU_OPTS+=-cdrom $(O)/image.iso \ -M q35 \ -m 512 \ - -serial mon:stdio \ + -chardev stdio,id=chr0,mux=on \ + -serial chardev:chr0 \ -net none else ifeq ($(MACH),qemu) diff --git a/kernel/src/arch/x86_64/boot/mod.rs b/kernel/src/arch/x86_64/boot/mod.rs index 63af7c1..9c72769 100644 --- a/kernel/src/arch/x86_64/boot/mod.rs +++ b/kernel/src/arch/x86_64/boot/mod.rs @@ -5,7 +5,7 @@ use crate::arch::x86_64::{ }; use crate::config::{ConfigKey, CONFIG}; use crate::debug; -use crate::dev::{display::FramebufferInfo, pseudo, Device}; +use crate::dev::{display::FramebufferInfo, irq::IntSource, pseudo, Device}; use crate::font; use crate::fs::{devfs::{self, CharDeviceType}, sysfs}; use crate::mem::{ @@ -93,6 +93,9 @@ extern "C" fn __x86_64_bsp_main(mb_checksum: u32, mb_info_ptr: u32) -> ! { phys_base: fb_info.address as usize, virt_base: virt, }); + unsafe { + x86_64::COM1.init_irqs(); + } font::init(); debug::set_display(&x86_64::DISPLAY); syscall::init(); diff --git a/kernel/src/arch/x86_64/intc.rs b/kernel/src/arch/x86_64/intc.rs index a0f3dc5..23c428f 100644 --- a/kernel/src/arch/x86_64/intc.rs +++ b/kernel/src/arch/x86_64/intc.rs @@ -100,6 +100,7 @@ impl IntController for I8259 { let irq_number = ic.token(); assert!(irq_number > 0); + // Clear irq if irq_number > 8 { self.cmd_b.write(0x20); } diff --git a/kernel/src/arch/x86_64/irq_vectors.S b/kernel/src/arch/x86_64/irq_vectors.S index 988769a..ccb321f 100644 --- a/kernel/src/arch/x86_64/irq_vectors.S +++ b/kernel/src/arch/x86_64/irq_vectors.S @@ -24,7 +24,25 @@ __x86_64_irq_\no: mov %rsp, %rdi call __x86_64_irq_handler - jmp . + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + + pop %rdi + pop %rsi + pop %rbp + pop %rbx + pop %rdx + pop %rcx + pop %rax + + add $16, %rsp + iretq .endm .section .text @@ -49,10 +67,6 @@ __x86_64_irq_0: push %r14 push %r15 - mov $0x3F8, %dx - mov $'T', %al - outb %al, %dx - mov $0x20, %al mov $0x20, %dx outb %al, %dx diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index db8b504..d2d913c 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -5,6 +5,7 @@ mod uart; use uart::Uart; mod intc; use intc::I8259; +pub use intc::IrqNumber; mod io; pub(self) use io::PortIo; @@ -54,6 +55,6 @@ pub fn console() -> &'static impl SerialDevice { &COM1 } -static COM1: Uart = unsafe { Uart::new(0x3F8) }; -static INTC: I8259 = I8259::new(); +static COM1: Uart = unsafe { Uart::new(0x3F8, IrqNumber::new(4)) }; +pub(self) static INTC: I8259 = I8259::new(); pub(self) static DISPLAY: StaticFramebuffer = StaticFramebuffer::uninit(); diff --git a/kernel/src/arch/x86_64/uart.rs b/kernel/src/arch/x86_64/uart.rs index abeb7c2..1af6835 100644 --- a/kernel/src/arch/x86_64/uart.rs +++ b/kernel/src/arch/x86_64/uart.rs @@ -1,16 +1,19 @@ -use crate::arch::x86_64::PortIo; -use libsys::error::Errno; +use crate::arch::x86_64::{self, IrqNumber, PortIo}; use crate::dev::{ - tty::{CharRing, TtyDevice}, irq::{IntController, IntSource}, serial::SerialDevice, + tty::{CharRing, TtyDevice}, Device, }; +use libsys::error::Errno; #[derive(TtyCharDevice)] pub(super) struct Uart { dr: PortIo, - ring: CharRing<16> + ier: PortIo, + isr: PortIo, + ring: CharRing<16>, + irq: IrqNumber, } impl Device for Uart { @@ -29,6 +32,24 @@ impl TtyDevice<16> for Uart { } } +impl IntSource for Uart { + fn handle_irq(&self) -> Result<(), Errno> { + if self.isr.read() != 0 { + self.recv_byte(self.dr.read()); + } + Ok(()) + } + + fn init_irqs(&'static self) -> Result<(), Errno> { + // TODO shared IRQs between COM# ports + x86_64::INTC.register_handler(self.irq, self)?; + self.ier.write((1 << 0)); + x86_64::INTC.enable_irq(self.irq)?; + + Ok(()) + } +} + impl SerialDevice for Uart { fn send(&self, byte: u8) -> Result<(), Errno> { self.dr.write(byte); @@ -41,10 +62,13 @@ impl SerialDevice for Uart { } impl Uart { - pub const unsafe fn new(base: u16) -> Self { + pub const unsafe fn new(base: u16, irq: IrqNumber) -> Self { Self { dr: PortIo::new(base), - ring: CharRing::new() + ier: PortIo::new(base + 1), + isr: PortIo::new(base + 2), + ring: CharRing::new(), + irq, } } } diff --git a/kernel/src/arch/x86_64/virt/table.rs b/kernel/src/arch/x86_64/virt/table.rs index 36a7bfa..410f036 100644 --- a/kernel/src/arch/x86_64/virt/table.rs +++ b/kernel/src/arch/x86_64/virt/table.rs @@ -229,7 +229,6 @@ impl Space for SpaceImpl { ); Err(Errno::AlreadyExists) } else { - debugln!("write_last_level {:#x}, {:#x?}", virt, entry); l2_table[l3i] = entry; unsafe { core::arch::asm!("invlpg ({})", in(reg) virt, options(att_syntax)); diff --git a/kernel/src/mem/virt/table.rs b/kernel/src/mem/virt/table.rs index eb3396d..a2d9cda 100644 --- a/kernel/src/mem/virt/table.rs +++ b/kernel/src/mem/virt/table.rs @@ -137,6 +137,7 @@ pub trait Space { /// Creates a new virtual -> physical memory mapping. Will fail if one is /// already associated with given virtual address. fn map(&mut self, virt: usize, phys: usize, attrs: MapAttributes) -> Result<(), Errno> { + #[cfg(feature = "verbose")] debugln!("Map {:#x} -> {:#x}, {:?}", virt, phys, attrs); unsafe { self.write_last_level( diff --git a/kernel/src/proc/wait.rs b/kernel/src/proc/wait.rs index b1ccd32..209f863 100644 --- a/kernel/src/proc/wait.rs +++ b/kernel/src/proc/wait.rs @@ -69,7 +69,32 @@ impl Wait { /// Interrupt wait pending on the channel pub fn abort(&self, tid: Tid, enqueue: bool) { - todo!(); + let mut queue = self.queue.lock(); + let mut tick_lock = TICK_LIST.lock(); + let mut cursor = tick_lock.cursor_front_mut(); + while let Some(item) = cursor.current() { + if tid == item.tid { + cursor.remove_current(); + break; + } else { + cursor.move_next(); + } + } + + let mut cursor = queue.cursor_front_mut(); + while let Some(item) = cursor.current() { + if tid == *item { + cursor.remove_current(); + let thread = Thread::get(tid).unwrap(); + thread.set_wait_status(WaitStatus::Interrupted); + if enqueue { + SCHED.enqueue(tid); + } + break; + } else { + cursor.move_next(); + } + } } fn wakeup_some(&self, mut limit: usize) -> usize { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 4f5e0d5..27bc679 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1,16 +1,17 @@ //! System call implementation -// use crate::arch::{machine, platform::exception::ExceptionFrame}; -use crate::arch::platform::ForkFrame; +use crate::arch::{machine, platform::ForkFrame}; use crate::debug::Level; // use crate::dev::timer::TimestampSource; use crate::fs::create_filesystem; use crate::mem::{ phys::PageUsage, - virt::table::{Space, MapAttributes}, + virt::table::{MapAttributes, Space}, }; use crate::proc::{self, elf, wait, Process, ProcessIo, Thread}; +use core::mem::size_of; use core::ops::DerefMut; +use core::time::Duration; use libsys::{ abi::SystemCall, debug::TraceLevel, @@ -77,132 +78,132 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result { io.file(fd)?.borrow_mut().write(buf) } - // SystemCall::Open => { - // let at_fd = FileDescriptor::from_i32(args[0] as i32)?; - // let path = arg::str_ref(args[1], args[2])?; - // let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; - // let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?; - // - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // - // let at = if let Some(fd) = at_fd { - // io.file(fd)?.borrow().node() - // } else { - // None - // }; - // - // let file = io.ioctx().open(at, path, mode, opts)?; - // Ok(u32::from(io.place_file(file)?) as usize) - // } - // SystemCall::Close => { - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // let fd = FileDescriptor::from(args[0] as u32); - // - // io.close_file(fd)?; - // Ok(0) - // } - // SystemCall::FileStatus => { - // let at_fd = FileDescriptor::from_i32(args[0] as i32)?; - // let filename = arg::str_ref(args[1], args[2])?; - // let buf = arg::struct_mut::(args[3])?; - // let flags = args[4] as u32; - // - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // let stat = - // find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat()?; - // *buf = stat; - // Ok(0) - // } - // SystemCall::Ioctl => { - // let fd = FileDescriptor::from(args[0] as u32); - // let cmd = IoctlCmd::try_from(args[1] as u32)?; - // - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // - // let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?; - // node.ioctl(cmd, args[2], args[3]) - // } - // SystemCall::Select => { - // let rfds = arg::option_struct_mut::(args[0])?; - // let wfds = arg::option_struct_mut::(args[1])?; - // let timeout = if args[2] == 0 { - // None - // } else { - // Some(Duration::from_nanos(args[2] as u64)) - // }; - // - // wait::select(Thread::current(), rfds, wfds, timeout) - // } - // SystemCall::Access => { - // let at_fd = FileDescriptor::from_i32(args[0] as i32)?; - // let path = arg::str_ref(args[1], args[2])?; - // let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; - // let flags = args[4] as u32; - // - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // - // find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)? - // .check_access(io.ioctx(), mode)?; - // Ok(0) - // } - // SystemCall::ReadDirectory => { - // let proc = Process::current(); - // let fd = FileDescriptor::from(args[0] as u32); - // let mut io = proc.io.lock(); - // let buf = arg::struct_buf_mut::(args[1], args[2])?; - // - // io.file(fd)?.borrow_mut().readdir(buf) - // } - // SystemCall::GetUserId => { - // let proc = Process::current(); - // let uid = proc.io.lock().uid(); - // Ok(u32::from(uid) as usize) - // } - // SystemCall::GetGroupId => { - // let proc = Process::current(); - // let gid = proc.io.lock().gid(); - // Ok(u32::from(gid) as usize) - // } - // SystemCall::DuplicateFd => { - // let src = FileDescriptor::from(args[0] as u32); - // let dst = FileDescriptor::from_i32(args[1] as i32)?; - // - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // - // let res = io.duplicate_file(src, dst)?; - // - // Ok(u32::from(res) as usize) - // } - // SystemCall::SetUserId => { - // let uid = UserId::from(args[0] as u32); - // let proc = Process::current(); - // proc.io.lock().set_uid(uid)?; - // Ok(0) - // } - // SystemCall::SetGroupId => { - // let gid = GroupId::from(args[0] as u32); - // let proc = Process::current(); - // proc.io.lock().set_gid(gid)?; - // Ok(0) - // } - // SystemCall::SetCurrentDirectory => { - // let path = arg::str_ref(args[0], args[1])?; - // let proc = Process::current(); - // proc.io.lock().ioctx().chdir(path)?; - // Ok(0) - // } - // SystemCall::GetCurrentDirectory => { - // todo!() - // } - // SystemCall::Seek => { - // todo!() - // } + SystemCall::Open => { + let at_fd = FileDescriptor::from_i32(args[0] as i32)?; + let path = arg::str_ref(args[1], args[2])?; + let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; + let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?; + + let proc = Process::current(); + let mut io = proc.io.lock(); + + let at = if let Some(fd) = at_fd { + io.file(fd)?.borrow().node() + } else { + None + }; + + let file = io.ioctx().open(at, path, mode, opts)?; + Ok(u32::from(io.place_file(file)?) as usize) + } + SystemCall::Close => { + let proc = Process::current(); + let mut io = proc.io.lock(); + let fd = FileDescriptor::from(args[0] as u32); + + io.close_file(fd)?; + Ok(0) + } + SystemCall::FileStatus => { + let at_fd = FileDescriptor::from_i32(args[0] as i32)?; + let filename = arg::str_ref(args[1], args[2])?; + let buf = arg::struct_mut::(args[3])?; + let flags = args[4] as u32; + + let proc = Process::current(); + let mut io = proc.io.lock(); + let stat = + find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat()?; + *buf = stat; + Ok(0) + } + SystemCall::Ioctl => { + let fd = FileDescriptor::from(args[0] as u32); + let cmd = IoctlCmd::try_from(args[1] as u32)?; + + let proc = Process::current(); + let mut io = proc.io.lock(); + + let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?; + node.ioctl(cmd, args[2], args[3]) + } + SystemCall::Select => { + let rfds = arg::option_struct_mut::(args[0])?; + let wfds = arg::option_struct_mut::(args[1])?; + let timeout = if args[2] == 0 { + None + } else { + Some(Duration::from_nanos(args[2] as u64)) + }; + + wait::select(Thread::current(), rfds, wfds, timeout) + } + SystemCall::Access => { + let at_fd = FileDescriptor::from_i32(args[0] as i32)?; + let path = arg::str_ref(args[1], args[2])?; + let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; + let flags = args[4] as u32; + + let proc = Process::current(); + let mut io = proc.io.lock(); + + find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)? + .check_access(io.ioctx(), mode)?; + Ok(0) + } + SystemCall::ReadDirectory => { + let proc = Process::current(); + let fd = FileDescriptor::from(args[0] as u32); + let mut io = proc.io.lock(); + let buf = arg::struct_buf_mut::(args[1], args[2])?; + + io.file(fd)?.borrow_mut().readdir(buf) + } + SystemCall::GetUserId => { + let proc = Process::current(); + let uid = proc.io.lock().uid(); + Ok(u32::from(uid) as usize) + } + SystemCall::GetGroupId => { + let proc = Process::current(); + let gid = proc.io.lock().gid(); + Ok(u32::from(gid) as usize) + } + SystemCall::DuplicateFd => { + let src = FileDescriptor::from(args[0] as u32); + let dst = FileDescriptor::from_i32(args[1] as i32)?; + + let proc = Process::current(); + let mut io = proc.io.lock(); + + let res = io.duplicate_file(src, dst)?; + + Ok(u32::from(res) as usize) + } + SystemCall::SetUserId => { + let uid = UserId::from(args[0] as u32); + let proc = Process::current(); + proc.io.lock().set_uid(uid)?; + Ok(0) + } + SystemCall::SetGroupId => { + let gid = GroupId::from(args[0] as u32); + let proc = Process::current(); + proc.io.lock().set_gid(gid)?; + Ok(0) + } + SystemCall::SetCurrentDirectory => { + let path = arg::str_ref(args[0], args[1])?; + let proc = Process::current(); + proc.io.lock().ioctx().chdir(path)?; + Ok(0) + } + SystemCall::GetCurrentDirectory => { + todo!() + } + SystemCall::Seek => { + todo!() + } SystemCall::MapMemory => { let len = args[1]; if len == 0 || (len & 0xFFF) != 0 { @@ -211,8 +212,7 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result { let acc = MemoryAccess::from_bits(args[2] as u32).ok_or(Errno::InvalidArgument)?; let _flags = MemoryAccess::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?; - let mut attrs = - MapAttributes::SHARE_OUTER | MapAttributes::USER_READ; + let mut attrs = MapAttributes::SHARE_OUTER | MapAttributes::USER_READ; if !acc.contains(MemoryAccess::READ) { return Err(Errno::NotImplemented); } @@ -237,186 +237,185 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result { space.allocate(0x100000000, 0xF00000000, len / 4096, attrs, usage) }) } - // SystemCall::UnmapMemory => { - // let addr = args[0]; - // let len = args[1]; - // - // if addr == 0 || len == 0 || addr & 0xFFF != 0 || len & 0xFFF != 0 { - // return Err(Errno::InvalidArgument); - // } - // - // let proc = Process::current(); - // proc.manipulate_space(move |space| space.free(addr, len / 4096))?; - // Ok(0) - // } - // - // // Process - // SystemCall::Clone => { - // let entry = args[0]; - // let stack = args[1]; - // let arg = args[2]; - // - // Process::current() - // .new_user_thread(entry, stack, arg) - // .map(|e| u32::from(e) as usize) - // } - // SystemCall::Exec => { - // let filename = arg::str_ref(args[0], args[1])?; - // let argv = arg::struct_buf_ref::<&str>(args[2], args[3])?; - // // Validate each argument as well - // for item in argv.iter() { - // arg::validate_ptr(item.as_ptr() as usize, item.len(), false)?; - // } - // let node = { - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // // TODO argv, envp array passing ABI? - // let node = io.ioctx().find(None, filename, true)?; - // drop(io); - // node - // }; - // let file = node.open(OpenFlags::O_RDONLY)?; - // Process::execve(move |space| elf::load_elf(space, file), argv).unwrap(); - // panic!(); - // } - SystemCall::Exit => { - let status = ExitCode::from(args[0] as i32); - let flags = args[1]; + SystemCall::UnmapMemory => { + let addr = args[0]; + let len = args[1]; - if flags & (1 << 0) != 0 { - Process::exit_thread(Thread::current(), status); - } else { - Process::current().exit(status); - } + if addr == 0 || len == 0 || addr & 0xFFF != 0 || len & 0xFFF != 0 { + return Err(Errno::InvalidArgument); + } - unreachable!(); + let proc = Process::current(); + proc.manipulate_space(move |space| space.free(addr, len / 4096))?; + Ok(0) + } + // // Process + // SystemCall::Clone => { + // let entry = args[0]; + // let stack = args[1]; + // let arg = args[2]; + + // Process::current() + // .new_user_thread(entry, stack, arg) + // .map(|e| u32::from(e) as usize) + // } + SystemCall::Exec => { + let filename = arg::str_ref(args[0], args[1])?; + let argv = arg::struct_buf_ref::<&str>(args[2], args[3])?; + // Validate each argument as well + for item in argv.iter() { + arg::validate_ptr(item.as_ptr() as usize, item.len(), false)?; + } + let node = { + let proc = Process::current(); + let mut io = proc.io.lock(); + // TODO argv, envp array passing ABI? + let node = io.ioctx().find(None, filename, true)?; + drop(io); + node + }; + let file = node.open(OpenFlags::O_RDONLY)?; + Process::execve(move |space| elf::load_elf(space, file), argv).unwrap(); + panic!(); + } + SystemCall::Exit => { + let status = ExitCode::from(args[0] as i32); + let flags = args[1]; + + if flags & (1 << 0) != 0 { + Process::exit_thread(Thread::current(), status); + } else { + Process::current().exit(status); + } + + unreachable!(); + } + SystemCall::WaitPid => { + // TODO special "pid" values + let pid = Pid::try_from(args[0] as u32)?; + let status = arg::struct_mut::(args[1])?; + + match Process::waitpid(pid) { + Ok(exit) => { + *status = i32::from(exit); + Ok(0) } - SystemCall::WaitPid => { - // TODO special "pid" values - let pid = Pid::try_from(args[0] as u32)?; - let status = arg::struct_mut::(args[1])?; + e => e.map(|e| i32::from(e) as usize), + } + } + SystemCall::WaitTid => { + let tid = Tid::from(args[0] as u32); - match Process::waitpid(pid) { - Ok(exit) => { - *status = i32::from(exit); - Ok(0) - } - e => e.map(|e| i32::from(e) as usize), - } + match Thread::waittid(tid) { + Ok(_) => Ok(0), + _ => todo!(), + } + } + SystemCall::GetPid => Ok(u32::from(Process::current().id()) as usize), + SystemCall::GetTid => Ok(u32::from(Thread::current().id()) as usize), + SystemCall::Sleep => { + let rem_buf = arg::option_buf_ref(args[1], size_of::() * 2)?; + let mut rem = Duration::new(0, 0); + let res = wait::sleep(Duration::from_nanos(args[0] as u64), &mut rem); + if res == Err(Errno::Interrupt) { + warnln!("Sleep interrupted, {:?} remaining", rem); + if rem_buf.is_some() { + todo!() } - // SystemCall::WaitTid => { - // let tid = Tid::from(args[0] as u32); - // - // match Thread::waittid(tid) { - // Ok(_) => Ok(0), - // _ => todo!(), - // } - // } - // SystemCall::GetPid => Ok(u32::from(Process::current().id()) as usize), - // SystemCall::GetTid => Ok(u32::from(Thread::current().id()) as usize), - // SystemCall::Sleep => { - // let rem_buf = arg::option_buf_ref(args[1], size_of::() * 2)?; - // let mut rem = Duration::new(0, 0); - // let res = wait::sleep(Duration::from_nanos(args[0] as u64), &mut rem); - // if res == Err(Errno::Interrupt) { - // warnln!("Sleep interrupted, {:?} remaining", rem); - // if rem_buf.is_some() { - // todo!() - // } - // } - // res.map(|_| 0) - // } - // SystemCall::SetSignalEntry => { - // Thread::current().set_signal_entry(args[0], args[1]); - // Ok(0) - // } - // SystemCall::SignalReturn => { - // Thread::current().return_from_signal(); - // unreachable!(); - // } - // SystemCall::SendSignal => { - // let target = SignalDestination::from(args[0] as isize); - // let signal = Signal::try_from(args[1] as u32)?; - // - // match target { - // SignalDestination::This => Process::current().set_signal(signal), - // SignalDestination::Process(pid) => Process::get(pid) - // .ok_or(Errno::DoesNotExist)? - // .set_signal(signal), - // _ => todo!(), - // }; - // Ok(0) - // } - // SystemCall::Yield => { - // proc::switch(); - // Ok(0) - // } - // SystemCall::GetSid => { - // // TODO handle kernel processes here? - // let pid = Pid::to_option(args[0] as u32); - // let current = Process::current(); - // let proc = if let Some(pid) = pid { - // let proc = Process::get(pid).ok_or(Errno::DoesNotExist)?; - // if proc.sid() != current.sid() { - // return Err(Errno::PermissionDenied); - // } - // proc - // } else { - // current - // }; - // - // Ok(u32::from(proc.sid()) as usize) - // } - // SystemCall::GetPgid => { - // // TODO handle kernel processes here? - // let pid = Pid::to_option(args[0] as u32); - // let current = Process::current(); - // let proc = if let Some(pid) = pid { - // Process::get(pid).ok_or(Errno::DoesNotExist)? - // } else { - // current - // }; - // - // Ok(u32::from(proc.pgid()) as usize) - // } - // SystemCall::GetPpid => Ok(u32::from(Process::current().ppid().unwrap()) as usize), - // SystemCall::SetSid => { - // let proc = Process::current(); - // let mut io = proc.io.lock(); - // - // if let Some(_ctty) = io.ctty() { - // todo!(); - // } - // - // let id = proc.id(); - // proc.set_sid(id); - // Ok(u32::from(id) as usize) - // } - // SystemCall::SetPgid => { - // let pid = Pid::to_option(args[0] as u32); - // let pgid = Pid::to_option(args[1] as u32); - // - // let current = Process::current(); - // let proc = if let Some(_pid) = pid { - // todo!() - // } else { - // current - // }; - // - // if let Some(_pgid) = pgid { - // todo!(); - // } else { - // proc.set_pgid(proc.id()); - // } - // - // Ok(u32::from(proc.pgid()) as usize) - // } - // - // // System - // SystemCall::GetCpuTime => { - // let time = machine::local_timer().timestamp()?; - // Ok(time.as_nanos() as usize) - // } + } + res.map(|_| 0) + } + // SystemCall::SetSignalEntry => { + // Thread::current().set_signal_entry(args[0], args[1]); + // Ok(0) + // } + // SystemCall::SignalReturn => { + // Thread::current().return_from_signal(); + // unreachable!(); + // } + // SystemCall::SendSignal => { + // let target = SignalDestination::from(args[0] as isize); + // let signal = Signal::try_from(args[1] as u32)?; + + // match target { + // SignalDestination::This => Process::current().set_signal(signal), + // SignalDestination::Process(pid) => Process::get(pid) + // .ok_or(Errno::DoesNotExist)? + // .set_signal(signal), + // _ => todo!(), + // }; + // Ok(0) + // } + SystemCall::Yield => { + proc::switch(); + Ok(0) + } + SystemCall::GetSid => { + // TODO handle kernel processes here? + let pid = Pid::to_option(args[0] as u32); + let current = Process::current(); + let proc = if let Some(pid) = pid { + let proc = Process::get(pid).ok_or(Errno::DoesNotExist)?; + if proc.sid() != current.sid() { + return Err(Errno::PermissionDenied); + } + proc + } else { + current + }; + + Ok(u32::from(proc.sid()) as usize) + } + SystemCall::GetPgid => { + // TODO handle kernel processes here? + let pid = Pid::to_option(args[0] as u32); + let current = Process::current(); + let proc = if let Some(pid) = pid { + Process::get(pid).ok_or(Errno::DoesNotExist)? + } else { + current + }; + + Ok(u32::from(proc.pgid()) as usize) + } + SystemCall::GetPpid => Ok(u32::from(Process::current().ppid().unwrap()) as usize), + SystemCall::SetSid => { + let proc = Process::current(); + let mut io = proc.io.lock(); + + if let Some(_ctty) = io.ctty() { + todo!(); + } + + let id = proc.id(); + proc.set_sid(id); + Ok(u32::from(id) as usize) + } + SystemCall::SetPgid => { + let pid = Pid::to_option(args[0] as u32); + let pgid = Pid::to_option(args[1] as u32); + + let current = Process::current(); + let proc = if let Some(_pid) = pid { + todo!() + } else { + current + }; + + if let Some(_pgid) = pgid { + todo!(); + } else { + proc.set_pgid(proc.id()); + } + + Ok(u32::from(proc.pgid()) as usize) + } + + // // System + // SystemCall::GetCpuTime => { + // let time = machine::local_timer().timestamp()?; + // Ok(time.as_nanos() as usize) + // } SystemCall::Mount => { let target = arg::str_ref(args[0], args[1])?; let options = arg::struct_ref::(args[2])?; @@ -432,7 +431,7 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result { target_node.mount(root)?; Ok(0) - }, + } // Debugging SystemCall::DebugTrace => { diff --git a/user/src/init/main.rs b/user/src/init/main.rs index 7745c9d..fee2b16 100644 --- a/user/src/init/main.rs +++ b/user/src/init/main.rs @@ -33,32 +33,12 @@ fn main() -> i32 { if let Some(pid) = unsafe { sys_fork().unwrap() } { let mut status = 0; sys_waitpid(pid, &mut status).unwrap(); - trace_debug!("Child exited!"); + println!("Process {:?} exited with status {}", pid, status); - loop {} - } else { - for _ in 0..1000000 { - unsafe { - asm!("nop"); - } + loop { } - - trace_debug!("Will now exit"); - - 0 + } else { + sys_execve("/sbin/login", &["/sbin/login", "/dev/ttyS0"]).unwrap(); + unreachable!(); } - - // loop {} - - // if let Some(pid) = unsafe { sys_fork().unwrap() } { - // let mut status = 0; - // sys_waitpid(pid, &mut status).unwrap(); - // println!("Process {:?} exited with status {}", pid, status); - - // loop { - // } - // } else { - // sys_execve("/sbin/login", &["/sbin/login", "/dev/ttyS0"]).unwrap(); - // unreachable!(); - // } }