Hacky serial output

This commit is contained in:
River 2025-05-16 01:38:38 -04:00
parent df3ff681d0
commit d30c541e8a
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
12 changed files with 133 additions and 75 deletions

2
Cargo.lock generated
View File

@ -92,7 +92,7 @@ checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
[[package]]
name = "gila"
version = "0.2.3"
version = "0.3.0"
dependencies = [
"acpi",
"enumflags2",

View File

@ -1,6 +1,6 @@
[package]
name = "gila"
version = "0.2.3"
version = "0.3.0"
edition = "2024"
[dependencies]

View File

@ -1,5 +1,5 @@
# Gila v0.2.3 - a Rust Microkernel
# Gila v0.3.0 - a Rust Microkernel
Gila is a Rust microkernel OS, inspired by the Xinu embedded OS, as well as Linux. I aim to implement multitasking and different users for processes, and eventually a filesystem. I do not aim to make it POSIX-compatible, but it will likely end up sharing many features with POSIX operating systems.

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#![allow(clippy::missing_safety_doc)]
#![allow(dead_code)]
use core::arch::asm;
@ -10,3 +11,69 @@ pub unsafe fn halt() {
asm!("hlt");
}
}
pub unsafe fn port_read_u8(port: u16) -> u8 {
let result: u8;
unsafe {
asm! {
"in al dx",
in("dx") port,
out("al") result
}
}
result
}
pub unsafe fn port_read_u16(port: u16) -> u16 {
let result: u16;
unsafe {
asm! {
"in ax dx",
in("dx") port,
out("ax") result
}
}
result
}
pub unsafe fn port_read_u32(port: u16) -> u32 {
let result: u32;
unsafe {
asm! {
"in eax dx",
in("dx") port,
out("eax") result
}
}
result
}
pub unsafe fn port_write_u8(port: u16, data: u8) {
unsafe {
asm! {
"out dx, al",
in("dx") port,
in("al") data,
}
}
}
pub unsafe fn port_write_u16(port: u16, data: u16) {
unsafe {
asm! {
"out dx, ax",
in("dx") port,
in("ax") data,
}
}
}
pub unsafe fn port_write_u32(port: u16, data: u32) {
unsafe {
asm! {
"out dx eax",
in("dx") port,
in("eax") data,
}
}
}

View File

@ -4,3 +4,4 @@
pub mod acpi;
pub mod asm;
pub mod display;
pub mod serial;

View File

@ -0,0 +1,23 @@
use crate::{asm::*, log::LogSubscriber};
#[derive(Clone, Copy)]
pub struct Serialport {
port: u16,
}
impl LogSubscriber for Serialport {
fn write(&self, msg: &str) {
for c in msg.chars() {
unsafe { port_write_u8(self.port, c as u8) };
}
}
}
impl Serialport {
pub fn new(port: u16) -> Self {
Serialport {
port
}
}
}

View File

@ -22,3 +22,6 @@ pub static FILE_REQUEST: ExecutableFileRequest = limine::request::ExecutableFile
#[used]
#[unsafe(link_section = ".requests")]
pub static RSDP_REQUEST: RsdpRequest = limine::request::RsdpRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
pub static MODULE_REQUEST: ModuleRequest = limine::request::ModuleRequest::new();

View File

@ -41,13 +41,14 @@ impl Logger {
/// Calling log will sequentially acquire lock on all logging subscribers
/// to write to them with a formatted log message.
pub fn log(&self, level: LogLevel, msg: &str) {
// Nobody is EVER allowed to call log with the Disabled log level. It is a placeholder.
if level == LogLevel::Disabled {
// Nothing
} else if level > self.level {
} else if level >= self.level {
for sub in &self.subscriber {
let mut message = String::new();
write!(&mut message, "{:?}: {}", level, msg).unwrap();
writeln!(&mut message, "{level:?}: {msg}").unwrap();
sub.lock().write(&message);
}
}

View File

@ -15,9 +15,13 @@ mod process;
mod resources;
mod syscall_runner;
use arch::current::*;
use arch::x86_64::serial::Serialport;
use spin::mutex::Mutex;
use crate::boot::*;
use crate::log::*;
use crate::memory::alloc::{format, string::String, vec};
use crate::memory::alloc::{format, string::*, vec, boxed};
use crate::params::*;
#[unsafe(no_mangle)]
@ -25,6 +29,9 @@ unsafe extern "C" fn main() -> ! {
// Assert supported bootloader version
assert!(BASE_REVISION.is_supported());
// TODO: This is hacky and will not work on any other machine.
let qemu_serial = Serialport::new(0x3f8);
// Local logger fn
fn log(level: LogLevel, msg: &str) {
LOGGER.lock().log(level, msg);
@ -49,7 +56,7 @@ unsafe extern "C" fn main() -> ! {
// Append display console to log subs
}
if log_device_list.contains(&"serial") {
// Append serial console to log subs
LOGGER.lock().subscriber.push(Mutex::new(boxed::Box::new(qemu_serial)));
}
log(LogLevel::Info, "Boot: Configured kernel logging devices.")
}
@ -70,6 +77,28 @@ unsafe extern "C" fn main() -> ! {
),
);
}
if let Some(module_response) = MODULE_REQUEST.get_response() {
log(
LogLevel::Info,
&format!(
"Boot: Kernel modules count: {}",
module_response.modules().len()
)
);
log(
LogLevel::Info,
"Boot: Kernel modules list:"
);
for module in module_response.modules() {
log(
LogLevel::Info,
&format!(
"\t{}",
String::from_utf8_lossy(module.path().to_bytes())
)
)
}
}
log(
LogLevel::Info,
"Boot: Log devices configured. Booting `gila`.",

View File

@ -1,6 +1,5 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
mod ports;
mod registers_impl;
mod syscall_impl;

View File

@ -1,67 +0,0 @@
use core::{arch::asm, num::TryFromIntError};
pub unsafe fn port_read_u8(port: u16) -> u8 {
let result: u8;
unsafe {
asm! {
"in al dx",
in("dx") port,
out("al") result
}
}
result
}
pub unsafe fn port_read_u16(port: u16) -> u16 {
let result: u16;
unsafe {
asm! {
"in ax dx",
in("dx") port,
out("ax") result
}
}
result
}
pub unsafe fn port_read_u32(port: u16) -> u32 {
let result: u32;
unsafe {
asm! {
"in eax dx",
in("dx") port,
out("eax") result
}
}
result
}
pub unsafe fn port_write_u8(port: u16, data: u8) {
unsafe {
asm! {
"out dx al",
in("dx") port,
in("al") data,
}
}
}
pub unsafe fn port_write_u16(port: u16, data: u16) {
unsafe {
asm! {
"out dx ax",
in("dx") port,
in("ax") data,
}
}
}
pub unsafe fn port_write_u32(port: u16, data: u32) {
unsafe {
asm! {
"out dx eax",
in("dx") port,
in("eax") data,
}
}
}

View File

@ -3,6 +3,8 @@
// Every architecture MUST implement this as part of the ABI.
// Additional registers can be implemented with architecture-specific traits.
#[allow(clippy::missing_safety_doc)]
pub unsafe trait RegStoreLoad
where
Self: Sized,