diff --git a/src/interrupts.rs b/src/interrupts.rs index 4746ef6..1d30fe0 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -1,8 +1,8 @@ use crate::{ - bootinfo::BOOTINFO, dbg, print, println, tasking::SleepReason, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, TASKING + bootinfo::BOOTINFO, print, println, serial::SECOND_PORT, tasking::SleepReason, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, TASKING }; use alloc::{boxed::Box, vec::Vec}; -use core::{arch::asm, ptr::{addr_of, slice_from_raw_parts_mut}, slice, str}; +use core::{arch::asm, ptr::addr_of, slice, str}; use hashbrown::HashMap; use pic8259::ChainedPics; use spin::{Lazy, Mutex, RwLock}; @@ -318,9 +318,24 @@ extern "C" fn syscall_handler() { let mut tasking = TASKING.lock(); if let Some(_queue) = tasking.message_queue_mut(pid) { let len = regs.rsi as usize; + let trunc_len = usize::min(len, 4096) as u32; + let padding = if (trunc_len % 4) != 0 { 4 - (trunc_len % 4) } else { 0 }; + let padded_len = trunc_len + padding; + SECOND_PORT.write_u32s(&[ + 0x3, // SPB type + padded_len + 8 + (4 * 4), // Total block length + (len as u32) + 8, // Packet length + ]); + SECOND_PORT.write_bytes(&pid.to_ne_bytes()); + SECOND_PORT.write_bytes(&buffer[0..trunc_len as usize]); + for _ in 0..padding { + SECOND_PORT.write_bytes(&[0]); + } + SECOND_PORT.write_u32s(&[ + padded_len + 8 + (4 * 4), // Total block length + ]); let buffer = Box::into_raw(buffer); - let new_buffer_key = - tasking.proc_data_buffers_mut(pid).insert(buffer); + let new_buffer_key = tasking.proc_data_buffers_mut(pid).insert(buffer); let queue = tasking.message_queue_mut(pid).unwrap(); queue.push((new_buffer_key, len)); if tasking.proc_sleeping(pid) == Some(SleepReason::WaitingForIPC) { diff --git a/src/main.rs b/src/main.rs index cb4694a..c5932ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use core::{slice, usize}; use bootinfo::BOOTINFO; use elf::{abi::{PT_DYNAMIC, PT_GNU_EH_FRAME, PT_GNU_RELRO, PT_GNU_STACK, PT_LOAD, PT_NULL, PT_PHDR, R_X86_64_RELATIVE, SHT_REL, SHT_RELA}, endian::AnyEndian, ElfBytes}; +use serial::SECOND_PORT; use tar_no_std::TarArchiveRef; use tasking::TASKING; use x86_64::{registers::rflags::{self, RFlags}, structures::paging::{Page, PageTableFlags}, VirtAddr}; @@ -118,6 +119,23 @@ pub fn main() { } } } + + // Before starting init, write the pcapng section header + interface description to the second serial port + SECOND_PORT.write_u32s(&[ + 0x0A0D0D0A, // SHB type + 7 * 4, // Total block length + 0x1A2B3C4D, // Byte order magic + 0x0000_0001, // Version (1.0) + 0xFFFFFFFF, // Length upper (-1) across both + 0xFFFFFFFF, // Length lower + 7 * 4, // Total block length + 0x1, // IDB type + 5 * 4, // Total block length + 147, // Link type + 4096 + 8, // Packet length limit, + 5 * 4, // Total block length + ]); + TASKING .lock() .new_process( diff --git a/src/serial.rs b/src/serial.rs index 31e98db..631bee9 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -2,7 +2,7 @@ use core::{fmt, fmt::Write}; use spin::{Lazy, Mutex}; use uart_16550::SerialPort; -pub static PORT: Lazy = Lazy::new(|| { +pub static FIRST_PORT: Lazy = Lazy::new(|| { // SAFETY: // 0x3f8 is the defined address for the first serial port on x86_64, // so we know it is safe to use that as the port's base address. @@ -11,6 +11,15 @@ pub static PORT: Lazy = Lazy::new(|| { Wrapper(Mutex::new(port)) }); +pub static SECOND_PORT: Lazy = Lazy::new(|| { + // SAFETY: + // 0x2f8 is the defined address for the second serial port on x86_64, + // so we know it is safe to use that as the port's base address. + let mut port = unsafe { SerialPort::new(0x2f8) }; + port.init(); + Wrapper(Mutex::new(port)) +}); + pub struct Wrapper(Mutex); impl fmt::Write for &Wrapper { fn write_str(&mut self, s: &str) -> fmt::Result { @@ -18,6 +27,22 @@ impl fmt::Write for &Wrapper { } } +impl Wrapper { + pub fn write_bytes(&self, bytes: &[u8]) { + let mut port = self.0.lock(); + for byte in bytes { + port.send_raw(*byte); + } + } + + pub fn write_u32s(&self, u32s: &[u32]) { + for elem in u32s { + let bytes = elem.to_ne_bytes(); + self.write_bytes(&bytes); + } + } +} + #[macro_export] macro_rules! print { ($($arg:tt)*) => ($crate::serial::_print(format_args!($($arg)*))); @@ -53,5 +78,5 @@ macro_rules! dbg { #[doc(hidden)] pub fn _print(args: fmt::Arguments) { - (&*PORT).write_fmt(args).unwrap(); + (&*FIRST_PORT).write_fmt(args).unwrap(); }