Hacky serial output
This commit is contained in:
parent
df3ff681d0
commit
d30c541e8a
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -92,7 +92,7 @@ checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
||||
|
||||
[[package]]
|
||||
name = "gila"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"acpi",
|
||||
"enumflags2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gila"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,3 +4,4 @@
|
||||
pub mod acpi;
|
||||
pub mod asm;
|
||||
pub mod display;
|
||||
pub mod serial;
|
23
src/kernel/arch/x86_64/serial.rs
Normal file
23
src/kernel/arch/x86_64/serial.rs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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`.",
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
mod ports;
|
||||
mod registers_impl;
|
||||
mod syscall_impl;
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user