mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Implemented serial driver
This commit is contained in:
+5
-5
@@ -17,11 +17,12 @@ multiboot:
|
||||
dd FLAGS
|
||||
dd CHECK
|
||||
|
||||
; Initialize stack
|
||||
section .bss
|
||||
align 16
|
||||
|
||||
; Initialize stack
|
||||
stack_bottom:
|
||||
resb 16384 ; 16kB
|
||||
resb 16384 ; 16kB
|
||||
stack_top:
|
||||
|
||||
; Entry point
|
||||
@@ -29,9 +30,8 @@ section .text
|
||||
global _start
|
||||
extern kmain
|
||||
_start:
|
||||
mov esp, stack_top
|
||||
|
||||
call kmain ; Call kernel main
|
||||
mov esp, stack_top ; Setup stack
|
||||
call kmain ; Call kernel main
|
||||
|
||||
; Hang if kernel returns
|
||||
cli
|
||||
|
||||
+13
-1
@@ -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!");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user