Dump IPC messages to serial port #2 as a pcapng file

This commit is contained in:
pjht 2024-07-07 07:59:27 -05:00
parent ff990d38f9
commit e79d426fb0
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
3 changed files with 64 additions and 6 deletions

View File

@ -1,8 +1,8 @@
use crate::{ 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 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 hashbrown::HashMap;
use pic8259::ChainedPics; use pic8259::ChainedPics;
use spin::{Lazy, Mutex, RwLock}; use spin::{Lazy, Mutex, RwLock};
@ -318,9 +318,24 @@ extern "C" fn syscall_handler() {
let mut tasking = TASKING.lock(); let mut tasking = TASKING.lock();
if let Some(_queue) = tasking.message_queue_mut(pid) { if let Some(_queue) = tasking.message_queue_mut(pid) {
let len = regs.rsi as usize; 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 buffer = Box::into_raw(buffer);
let new_buffer_key = let new_buffer_key = tasking.proc_data_buffers_mut(pid).insert(buffer);
tasking.proc_data_buffers_mut(pid).insert(buffer);
let queue = tasking.message_queue_mut(pid).unwrap(); let queue = tasking.message_queue_mut(pid).unwrap();
queue.push((new_buffer_key, len)); queue.push((new_buffer_key, len));
if tasking.proc_sleeping(pid) == Some(SleepReason::WaitingForIPC) { if tasking.proc_sleeping(pid) == Some(SleepReason::WaitingForIPC) {

View File

@ -27,6 +27,7 @@ use core::{slice, usize};
use bootinfo::BOOTINFO; 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 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 tar_no_std::TarArchiveRef;
use tasking::TASKING; use tasking::TASKING;
use x86_64::{registers::rflags::{self, RFlags}, structures::paging::{Page, PageTableFlags}, VirtAddr}; 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 TASKING
.lock() .lock()
.new_process( .new_process(

View File

@ -2,7 +2,7 @@ use core::{fmt, fmt::Write};
use spin::{Lazy, Mutex}; use spin::{Lazy, Mutex};
use uart_16550::SerialPort; use uart_16550::SerialPort;
pub static PORT: Lazy<Wrapper> = Lazy::new(|| { pub static FIRST_PORT: Lazy<Wrapper> = Lazy::new(|| {
// SAFETY: // SAFETY:
// 0x3f8 is the defined address for the first serial port on x86_64, // 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. // so we know it is safe to use that as the port's base address.
@ -11,6 +11,15 @@ pub static PORT: Lazy<Wrapper> = Lazy::new(|| {
Wrapper(Mutex::new(port)) Wrapper(Mutex::new(port))
}); });
pub static SECOND_PORT: Lazy<Wrapper> = 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<SerialPort>); pub struct Wrapper(Mutex<SerialPort>);
impl fmt::Write for &Wrapper { impl fmt::Write for &Wrapper {
fn write_str(&mut self, s: &str) -> fmt::Result { 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_export]
macro_rules! print { macro_rules! print {
($($arg:tt)*) => ($crate::serial::_print(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::serial::_print(format_args!($($arg)*)));
@ -53,5 +78,5 @@ macro_rules! dbg {
#[doc(hidden)] #[doc(hidden)]
pub fn _print(args: fmt::Arguments) { pub fn _print(args: fmt::Arguments) {
(&*PORT).write_fmt(args).unwrap(); (&*FIRST_PORT).write_fmt(args).unwrap();
} }