fixed addr gdt, serial
This commit is contained in:
1 parent
b0dffe7bc8
commit
988d3d601d
9 files changed
+189
-24
No files matched your search
@@ -0,0 +1,92 @@
|
||||
use core::{fmt, hint};
|
||||
|
||||
use crate::ioport;
|
||||
|
||||
pub struct Com {
|
||||
port: u16,
|
||||
}
|
||||
|
||||
pub struct ComError;
|
||||
|
||||
impl Com {
|
||||
pub unsafe fn init(port: u16) -> Result<Self, ComError> {
|
||||
const ECHO_BYTE: u8 = 0x5a;
|
||||
|
||||
let echo = unsafe {
|
||||
// Unset DLAB
|
||||
ioport::outb(port + 3, 0x00);
|
||||
// Disable interrupts
|
||||
ioport::outb(port + 1, 0x00);
|
||||
// Set DLAB
|
||||
ioport::outb(port + 3, 0x80);
|
||||
// Set baud rate divisor to 00 01 (115200)
|
||||
ioport::outb(port + 0, 0x01);
|
||||
ioport::outb(port + 1, 0x00);
|
||||
// 8 bits, no parity, one stop bit
|
||||
ioport::outb(port + 3, 0x03);
|
||||
// Enable FIFO, clear them, with 14-byte threshold
|
||||
ioport::outb(port + 2, 0xc7);
|
||||
// IRQs enabled, RTS/DSR set
|
||||
ioport::outb(port + 4, 0x0b);
|
||||
// Set loopback mode
|
||||
ioport::outb(port + 4, 0x1e);
|
||||
ioport::outb(port + 0, ECHO_BYTE);
|
||||
|
||||
ioport::inb(port + 0)
|
||||
};
|
||||
|
||||
if echo != ECHO_BYTE {
|
||||
return Err(ComError);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ioport::outb(port + 4, 0x0f);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
port,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn poll_has_data(&self) -> bool {
|
||||
unsafe { ioport::inb(self.port + 5) & 0x01 != 0 }
|
||||
}
|
||||
|
||||
pub fn read_poll(&mut self) -> u8 {
|
||||
while !self.poll_has_data() {
|
||||
hint::spin_loop();
|
||||
}
|
||||
unsafe { ioport::inb(self.port) }
|
||||
}
|
||||
|
||||
pub fn poll_has_space(&self) -> bool {
|
||||
unsafe { ioport::inb(self.port + 5) & 0x20 != 0 }
|
||||
}
|
||||
|
||||
pub fn write_poll(&mut self, x: u8) {
|
||||
while !self.poll_has_space() {
|
||||
hint::spin_loop();
|
||||
}
|
||||
unsafe {
|
||||
ioport::outb(self.port, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for Com {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for b in s.bytes() {
|
||||
self.write_poll(b);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_char(&mut self, c: char) -> fmt::Result {
|
||||
let mut buf = [0u8; 4];
|
||||
let s = c.encode_utf8(&mut buf);
|
||||
for b in s.bytes() {
|
||||
self.write_poll(b);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use core::arch::asm;
|
||||
|
||||
pub unsafe fn inb(port: u16) -> u8 {
|
||||
let x: u8;
|
||||
unsafe {
|
||||
asm!(
|
||||
"in al, dx",
|
||||
in("dx") port,
|
||||
lateout("al") x
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
pub unsafe fn outb(port: u16, x: u8) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"out dx, al",
|
||||
in("al") x,
|
||||
in("dx") port,
|
||||
);
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -4,9 +4,11 @@
|
||||
#![test_runner(crate::test_runner)]
|
||||
|
||||
mod spin;
|
||||
mod ioport;
|
||||
mod vga;
|
||||
mod com;
|
||||
|
||||
use core::{arch::{asm, global_asm}, panic::PanicInfo, fmt::Write};
|
||||
use core::{arch::{asm, global_asm}, fmt::Write, panic::PanicInfo, ptr, slice};
|
||||
|
||||
global_asm!(include_str!("asm/trampoline.s"));
|
||||
|
||||
@@ -20,11 +22,26 @@ fn panic(info: &PanicInfo) -> ! {
|
||||
hlt()
|
||||
}
|
||||
|
||||
const COM1_PORT: u16 = 0x3f8;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
vga::vga_init();
|
||||
|
||||
let gdt_ptr = ptr::with_exposed_provenance::<u64>(0xc000);
|
||||
let gdt_slice = unsafe { slice::from_raw_parts(gdt_ptr, 4) };
|
||||
|
||||
vga_println!("hello from rust :)");
|
||||
vga_println!("{:016x}", gdt_slice[0]);
|
||||
vga_println!("{:016x}", gdt_slice[1]);
|
||||
vga_println!("{:016x}", gdt_slice[2]);
|
||||
vga_println!("{:016x}", gdt_slice[3]);
|
||||
|
||||
let mut com = unsafe { com::Com::init(COM1_PORT) };
|
||||
|
||||
if let Ok(com) = &mut com {
|
||||
writeln!(com, "hello serial").ok();
|
||||
}
|
||||
|
||||
hlt()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user