Dump IPC messages to serial port #2 as a pcapng file
This commit is contained in:
parent
ff990d38f9
commit
e79d426fb0
@ -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) {
|
||||||
|
18
src/main.rs
18
src/main.rs
@ -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(
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user