Copy UART driver from xv6.
This commit is contained in:
parent
2ebc32c21c
commit
bdfcf429db
5
Makefile
5
Makefile
@ -3,7 +3,7 @@ LD=x86_64-elf-ld
|
||||
CC=x86_64-elf-gcc
|
||||
|
||||
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
|
||||
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
|
||||
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 $^
|
||||
|
||||
%.o: %.c
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
#include "console.h"
|
||||
#include "drivers/vga.h"
|
||||
#include "drivers/uart.h"
|
||||
|
||||
void printk(const char* msg) {
|
||||
vga_print_string(msg);
|
||||
for (; *msg; ++msg) {
|
||||
uartputc(*msg);
|
||||
}
|
||||
}
|
||||
|
||||
void panic(const char* msg) {
|
||||
printk("Kernel panic: ");
|
||||
printk("\nKernel panic: ");
|
||||
printk(msg);
|
||||
asm("cli");
|
||||
while (1) {
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
@ -79,8 +79,7 @@ void trap(registers_t *r) {
|
||||
if (r->int_no < ARRLEN(exception_messages)) {
|
||||
msg = exception_messages[r->int_no];
|
||||
}
|
||||
printk(msg);
|
||||
printk("\n");
|
||||
panic(msg);
|
||||
}
|
||||
|
||||
/* Handle the interrupt in a more modular way */
|
||||
|
||||
44
drivers/uart.c
Normal file
44
drivers/uart.c
Normal 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
4
drivers/uart.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void uartputc(char c);
|
||||
void uartinit();
|
||||
5
kernel.c
5
kernel.c
@ -6,9 +6,11 @@ asm(".asciz \"kernel start\"");
|
||||
#include "drivers/vga.h"
|
||||
#include "drivers/ata.h"
|
||||
#include "drivers/misc.h"
|
||||
#include "drivers/uart.h"
|
||||
|
||||
void _start() {
|
||||
init_keyboard();
|
||||
uartinit();
|
||||
load_idt();
|
||||
sti();
|
||||
char buf[512];
|
||||
@ -20,8 +22,7 @@ void _start() {
|
||||
printk(buf);
|
||||
|
||||
while (1) {
|
||||
asm("pause");
|
||||
asm("hlt");
|
||||
}
|
||||
asm("hlt");
|
||||
qemu_shutdown();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user