summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--kernel/src/io.rs13
-rw-r--r--kernel/src/lib.rs34
-rw-r--r--kernel/src/serial.rs66
-rw-r--r--kernel/src/terminal.rs27
5 files changed, 104 insertions, 44 deletions
diff --git a/Makefile b/Makefile
index f248f46..c5e8bdc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
all: target/kernel.o
+clean_run: | clean run
+
run: target/kernel.o
- qemu-system-i386 -kernel $< -machine type=pc-i440fx-3.1
+ qemu-system-i386 -kernel $< -machine type=pc-i440fx-3.1 -serial stdio
target/boot.o: boot/boot.S
mkdir -p target
@@ -17,5 +19,5 @@ target/i686-lisibleos/release/libkernel.a:
clean:
RUST_TARGET_PATH=$(shell pwd) xargo clean --target i686-lisibleos
- rm target/kernel.o target/boot.o target/i686-lisibleos/debug/libkernel.a
- rm target/kernel.o target/boot.o target/i686-lisibleos/release/libkernel.a
+ rm -f target/kernel.o target/boot.o target/i686-lisibleos/debug/libkernel.a
+ rm -f target/kernel.o target/boot.o target/i686-lisibleos/release/libkernel.a
diff --git a/kernel/src/io.rs b/kernel/src/io.rs
index def8665..a647408 100644
--- a/kernel/src/io.rs
+++ b/kernel/src/io.rs
@@ -1,5 +1,14 @@
pub unsafe fn out8(address: u16, value: u8) {
asm!(
- "out dx, al", in("dx") address, in("al") value
- )
+ "out dx, al", in("dx") address, in("al") value
+ );
+}
+
+pub unsafe fn in8(address: u16) -> u8 {
+ let result: u8;
+ asm!(
+ "in al, dx", in("dx") address, out("al") result
+ );
+
+ result
}
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index edb5704..b1c8cf2 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -6,38 +6,20 @@ use crate::terminal::Terminal;
use core::panic::PanicInfo;
mod io;
+mod serial;
mod terminal;
#[no_mangle]
pub extern "C" fn kmain() -> ! {
let mut terminal = Terminal::new();
terminal.clear();
- terminal.put_string(b"1 LisibleOS\n");
- terminal.put_string(b"2 > \n");
- terminal.put_string(b"3\n");
- terminal.put_string(b"4\n");
- terminal.put_string(b"5\n");
- terminal.put_string(b"6\n");
- terminal.put_string(b"7\n");
- terminal.put_string(b"8\n");
- terminal.put_string(b"9\n");
- terminal.put_string(b"10\n");
- terminal.put_string(b"11\n");
- terminal.put_string(b"12\n");
- terminal.put_string(b"13\n");
- terminal.put_string(b"14\n");
- terminal.put_string(b"15\n");
- terminal.put_string(b"16\n");
- terminal.put_string(b"17\n");
- terminal.put_string(b"18\n");
- terminal.put_string(b"19\n");
- terminal.put_string(b"20\n");
- terminal.put_string(b"21\n");
- terminal.put_string(b"22\n");
- terminal.put_string(b"23\n");
- terminal.put_string(b"24\n");
- terminal.put_string(b"25\n");
- terminal.put_string(b"26");
+ if let Err(_) = serial::initialize_serial_port() {
+ terminal.put_string(b"Serial port initialization failed");
+ } else {
+ terminal.put_string(b"Serial port initialization succeeded");
+ }
+
+ serial::write_bytes(b"This string was sent through the serial port!!");
loop {}
}
diff --git a/kernel/src/serial.rs b/kernel/src/serial.rs
new file mode 100644
index 0000000..77c15cb
--- /dev/null
+++ b/kernel/src/serial.rs
@@ -0,0 +1,66 @@
+use crate::io::{in8, out8};
+use crate::serial::SerialError::SerialPortInitializationFailed;
+
+const COM1_PORT: u16 = 0x3F8;
+const OFFSET_DATA_REGISTER: u8 = 0;
+const OFFSET_INTERRUPT_ENABLE_REGISTER: u8 = 1;
+const OFFSET_INTERRUPT_IDENTIFICATION_AND_FIFO_CONTROL_REGISTER: u8 = 2;
+const OFFSET_LINE_CONTROL_REGISTER: u8 = 3;
+const OFFSET_MODEM_CONTROL_REGISTER: u8 = 4;
+const OFFSET_LINE_STATUS_REGISTER: u8 = 5;
+
+#[derive(Debug)]
+pub enum SerialError {
+ SerialPortInitializationFailed,
+}
+
+pub fn initialize_serial_port() -> Result<(), SerialError> {
+ // Safety:
+ // These instructions read and write data on valid COM ports
+ unsafe {
+ out8(COM1_PORT + OFFSET_INTERRUPT_ENABLE_REGISTER as u16, 0x00);
+ out8(COM1_PORT + OFFSET_LINE_CONTROL_REGISTER as u16, 0x80);
+ out8(COM1_PORT + OFFSET_DATA_REGISTER as u16, 0x03);
+ out8(COM1_PORT + OFFSET_INTERRUPT_ENABLE_REGISTER as u16, 0x00);
+ out8(COM1_PORT + OFFSET_LINE_CONTROL_REGISTER as u16, 0x03);
+ out8(
+ COM1_PORT + OFFSET_INTERRUPT_IDENTIFICATION_AND_FIFO_CONTROL_REGISTER as u16,
+ 0xC7,
+ );
+ out8(COM1_PORT + OFFSET_MODEM_CONTROL_REGISTER as u16, 0x0B);
+
+ // Testing the serial chip
+ out8(COM1_PORT + OFFSET_MODEM_CONTROL_REGISTER as u16, 0x1E); // Enable loopback mode
+ out8(COM1_PORT + OFFSET_DATA_REGISTER as u16, 0xAE);
+ if in8(COM1_PORT + OFFSET_DATA_REGISTER as u16) != 0xAE {
+ return Err(SerialPortInitializationFailed);
+ }
+
+ out8(COM1_PORT + OFFSET_MODEM_CONTROL_REGISTER as u16, 0x0F); // Enable normal mode
+ }
+
+ Ok(())
+}
+
+pub fn write(byte: u8) {
+ while !is_ready_to_send_data() {}
+ // Safety: the value is sent on a valid port address, which is the COM port
+ // data register address
+ unsafe {
+ out8(COM1_PORT, byte);
+ }
+}
+
+pub fn write_bytes(bytes: &[u8]) {
+ for &byte in bytes {
+ write(byte);
+ }
+}
+
+fn is_ready_to_send_data() -> bool {
+ const THRE_BIT: u8 = 0x20;
+
+ // Safety: the value is sent on a valid port address, which is the COM port
+ // line status register address
+ return unsafe { in8(COM1_PORT + OFFSET_LINE_STATUS_REGISTER as u16) } & THRE_BIT != 0;
+}
diff --git a/kernel/src/terminal.rs b/kernel/src/terminal.rs
index c64188c..63c7d95 100644
--- a/kernel/src/terminal.rs
+++ b/kernel/src/terminal.rs
@@ -1,15 +1,15 @@
use crate::io;
use compiler_builtins::mem::memcpy;
-const VGA_BUFFER_POINTER: *mut u8 = 0xb8000 as *mut u8;
+const VGA_BUFFER_POINTER: *mut u8 = 0xB8000 as *mut u8;
const VGA_BUFFER_SIZE: u16 = 4000;
-const ROW_COUNT: u16 = 25;
-const COL_COUNT: u16 = 80;
-const VALUE_SIZE: u16 = 2;
+const ROW_COUNT: u8 = 25;
+const COL_COUNT: u8 = 80;
+const VALUE_SIZE: u8 = 2;
pub(crate) struct Terminal {
- current_row: u16,
- current_col: u16,
+ current_row: u8,
+ current_col: u8,
}
impl Terminal {
@@ -67,9 +67,9 @@ impl Terminal {
// The end pointer isn't past the VGA character buffer pointer
// The offset doesn't overflow isize
// The offset doesn't rely on wrapping around the address space
- let src = unsafe { VGA_BUFFER_POINTER.offset((COL_COUNT * VALUE_SIZE) as isize) };
+ let src = unsafe { VGA_BUFFER_POINTER.offset(COL_COUNT as isize * VALUE_SIZE as isize) };
let dest = VGA_BUFFER_POINTER;
- let size = (VGA_BUFFER_SIZE - COL_COUNT) * VALUE_SIZE;
+ let size = (VGA_BUFFER_SIZE - COL_COUNT as u16) * VALUE_SIZE as u16;
// Safety:
// dest and src are valid pointer to the same object being the VGA character buffer
@@ -78,12 +78,13 @@ impl Terminal {
self.clear_line(ROW_COUNT - 1);
}
- pub fn put_char_at(&mut self, c: u8, row: u16, col: u16) {
+ pub fn put_char_at(&mut self, c: u8, row: u8, col: u8) {
self.current_row = row;
self.current_col = col;
unsafe {
*VGA_BUFFER_POINTER.offset(
- ((self.current_col + self.current_row * COL_COUNT) * VALUE_SIZE) as isize,
+ (self.current_col as isize + self.current_row as isize * COL_COUNT as isize)
+ * VALUE_SIZE as isize,
) = c;
}
}
@@ -96,7 +97,7 @@ impl Terminal {
self.current_row = 0;
}
- fn clear_line(&mut self, row: u16) {
+ fn clear_line(&mut self, row: u8) {
for col in 0..COL_COUNT {
self.put_char_at(b' ', row, col);
}
@@ -105,8 +106,8 @@ impl Terminal {
self.current_col = 0;
}
- pub fn set_cursor_position(&mut self, row: u16, col: u16) {
- let cursor_position = row * COL_COUNT + col;
+ pub fn set_cursor_position(&mut self, row: u8, col: u8) {
+ let cursor_position = row as u16 * COL_COUNT as u16 + col as u16;
let address_register = 0x3D4;
let data_register = 0x3D5;
unsafe {
Go back to lisible.xyz