Copy UART driver from xv6.

This commit is contained in:
Alexander Myltsev 2022-11-21 00:53:29 +03:00
parent 2ebc32c21c
commit bdfcf429db
6 changed files with 61 additions and 7 deletions

View File

@ -3,7 +3,7 @@ LD=x86_64-elf-ld
CC=x86_64-elf-gcc CC=x86_64-elf-gcc
run: image.bin run: image.bin
qemu-system-i386 -drive format=raw,file=$< qemu-system-i386 -drive format=raw,file=$< -serial mon:stdio
debug-preboot: image.bin mbr.elf debug-preboot: image.bin mbr.elf
qemu-system-i386 -drive format=raw,file=$< -s -S & qemu-system-i386 -drive format=raw,file=$< -s -S &
@ -33,7 +33,8 @@ fs.img: kernel.bin tools/mkfs
image.bin: mbr.bin fs.img image.bin: mbr.bin fs.img
cat $^ >$@ cat $^ >$@
kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o string.o drivers/ata.o cpu/vectors.o cpu/idt.o kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o \
string.o drivers/ata.o cpu/vectors.o cpu/idt.o drivers/uart.o
$(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ $(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^
%.o: %.c %.o: %.c

View File

@ -1,13 +1,18 @@
#include "console.h" #include "console.h"
#include "drivers/vga.h" #include "drivers/vga.h"
#include "drivers/uart.h"
void printk(const char* msg) { void printk(const char* msg) {
vga_print_string(msg); vga_print_string(msg);
for (; *msg; ++msg) {
uartputc(*msg);
}
} }
void panic(const char* msg) { void panic(const char* msg) {
printk("Kernel panic: "); printk("\nKernel panic: ");
printk(msg); printk(msg);
asm("cli");
while (1) { while (1) {
asm("hlt"); asm("hlt");
} }

View File

@ -79,8 +79,7 @@ void trap(registers_t *r) {
if (r->int_no < ARRLEN(exception_messages)) { if (r->int_no < ARRLEN(exception_messages)) {
msg = exception_messages[r->int_no]; msg = exception_messages[r->int_no];
} }
printk(msg); panic(msg);
printk("\n");
} }
/* Handle the interrupt in a more modular way */ /* Handle the interrupt in a more modular way */

44
drivers/uart.c Normal file
View File

@ -0,0 +1,44 @@
#include "uart.h"
#include "port.h"
static int uart;
enum {
COM1 = 0x3f8,
};
void uartinit() {
// Turn off the FIFO
port_byte_out(COM1+2, 0);
// 9600 baud, 8 data bits, 1 stop bit, parity off.
port_byte_out(COM1+3, 0x80); // Unlock divisor
port_byte_out(COM1+0, 115200/9600);
port_byte_out(COM1+1, 0);
port_byte_out(COM1+3, 0x03); // Lock divisor, 8 data bits.
port_byte_out(COM1+4, 0);
port_byte_out(COM1+1, 0x01); // Enable receive interrupts.
// If status is 0xFF, no serial port.
if(port_byte_in(COM1+5) == 0xFF)
return;
uart = 1;
// Acknowledge pre-existing interrupt conditions;
// enable interrupts.
port_byte_in(COM1+2);
port_byte_in(COM1+0);
}
void
uartputc(char c)
{
int i;
if (!uart)
return;
for (i = 0; i < 128 && !(port_byte_in(COM1+5) & 0x20); i++) {
asm("pause");
}
port_byte_out(COM1+0, c);
}

4
drivers/uart.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void uartputc(char c);
void uartinit();

View File

@ -6,9 +6,11 @@ asm(".asciz \"kernel start\"");
#include "drivers/vga.h" #include "drivers/vga.h"
#include "drivers/ata.h" #include "drivers/ata.h"
#include "drivers/misc.h" #include "drivers/misc.h"
#include "drivers/uart.h"
void _start() { void _start() {
init_keyboard(); init_keyboard();
uartinit();
load_idt(); load_idt();
sti(); sti();
char buf[512]; char buf[512];
@ -20,8 +22,7 @@ void _start() {
printk(buf); printk(buf);
while (1) { while (1) {
asm("pause"); asm("hlt");
} }
asm("hlt");
qemu_shutdown(); qemu_shutdown();
} }