Implemented serial driver

This commit is contained in:
2025-02-18 14:06:41 +01:00
parent f9dece59ce
commit 609e10e13c
6 changed files with 145 additions and 6 deletions
+19
View File
@@ -0,0 +1,19 @@
#ifndef _SERIAL_H
#define _SERIAL_H
#include <kernel.h>
#define COM1 0x3f8
#define COM2 0x2f8
#define COM3 0x3e8
#define COM4 0x2e8
int serial_init(int dev);
int serial_txem(int dev);
void serial_send(int dev, char data);
int serial_rcvd(int dev);
char serial_recv(int dev);
void serial_write(int dev, char* buf, size_t len);
void serial_print(int dev, char* s);
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef _SYSTEM_H
#define _SYSTEM_H
#include <kernel.h>
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
// Ports
uint8_t inb(uint16_t port);
void outb(uint16_t port, uint8_t data);
uint16_t inw(uint16_t port);
void outw(uint16_t port, uint16_t data);
uint32_t inl(uint16_t port);
void outl(uint16_t port, uint32_t data);
#endif
+3 -3
View File
@@ -17,9 +17,10 @@ multiboot:
dd FLAGS
dd CHECK
; Initialize stack
section .bss
align 16
; Initialize stack
stack_bottom:
resb 16384 ; 16kB
stack_top:
@@ -29,8 +30,7 @@ section .text
global _start
extern kmain
_start:
mov esp, stack_top
mov esp, stack_top ; Setup stack
call kmain ; Call kernel main
; Hang if kernel returns
+13 -1
View File
@@ -1,13 +1,25 @@
#include <kernel.h>
#include <serial.h>
#include <tty.h>
#define _hlt() while (1) __asm__ volatile ("cli; hlt");
__noreturn
void kmain(void) {
serial_init(COM1);
serial_print(COM1, "kern.\n\n");
while (1) {
char c = serial_recv(COM1);
serial_send(COM1, c);
if (c == '\r') {
serial_send(COM1, '\n');
break;
}
}
tty_init();
tty_puts("Hello, World!\n");
_hlt();
panic("kmain() reached end!");
}
+53
View File
@@ -0,0 +1,53 @@
#include <kernel.h>
#include <system.h>
#include <serial.h>
int serial_init(int dev) {
outb(dev + 1, 0x00); // Disable serial interrupts
outb(dev + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(dev + 0, 0x03); // Set divisor to 3 (low byte) 38400 baud
outb(dev + 1, 0x00); // (high byte)
outb(dev + 3, 0x03); // 8 bits, no parity, one stop bit
outb(dev + 2, 0xC7); // Enable FIFO, clear them, with 14 byte threshold
outb(dev + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(dev + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(dev + 0, 0xAE); // Test serial chip (send byte 0xAE and check if it returns)
if (inb(dev + 0) != 0xAE) return 1;
outb(dev + 4, 0x0F); // non-loopback, IRQs enabled, OUT#1 and OUT#2 bits enabled
return 0;
}
int serial_txem(int dev) {
return inb(dev + 5) & 0x20;
}
void serial_send(int dev, char data) {
while (serial_txem(dev) == 0);
outb(dev, data);
}
int serial_rcvd(int dev) {
return inb(dev + 5) & 1;
}
char serial_recv(int dev) {
while (serial_rcvd(dev) == 0);
return inb(dev);
}
void serial_write(int dev, char* buf, size_t len) {
for (size_t i = 0; i < len; i++) {
if (buf[i] == '\n') serial_send(dev, '\r');
serial_send(dev, buf[i]);
}
}
void serial_print(int dev, char* s) {
size_t len = 0;
char* p = s;
while (*p++ != '\0') len++;
serial_write(dev, s, len);
}
+39
View File
@@ -0,0 +1,39 @@
#include <kernel.h>
void cpuid(uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
__asm__ volatile ("cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(*eax)
: "memory");
}
uint8_t inb(uint16_t port) {
uint8_t r;
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
return r;
}
void outb(uint16_t port, uint8_t data) {
__asm__ volatile ("outb %1, %0" :: "dN"(port), "a"(data));
}
uint16_t inw(uint16_t port) {
uint16_t r;
__asm__ volatile ("inw %1, %0" : "=a"(r) : "dN"(port));
return r;
}
void outw(uint16_t port, uint16_t data) {
__asm__ volatile ("outw %1, %0" :: "dN"(port), "a"(data));
}
uint32_t inl(uint16_t port) {
uint32_t r;
__asm__ volatile ("inl %1, %0" : "=a"(r) : "dN"(port));
return r;
}
void outl(uint16_t port, uint32_t data) {
__asm__ volatile ("outl %1, %0" :: "dN"(port), "a"(data));
}