Skip to content

Commit

Permalink
Merge pull request #27 from pbrucla/serial_driver
Browse files Browse the repository at this point in the history
Serial driver
  • Loading branch information
danieltherealyang authored Nov 16, 2023
2 parents 20bfcdf + 3a765d4 commit 9c791d9
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 34 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ image: boot kernel
$(DD) if=/dev/zero of=$(BUILD_DIR)/os_image seek=1 obs=1024 count=0 conv=notrunc

run: default
$(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image
$(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -serial stdio

gdb: default
# Need to have GEF installed for this to work
$(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -s -S & gdb -ex "gef-remote --qemu-user localhost 1234" build/kernel.elf

dockerun:
$(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image
$(QEMU) -drive format=raw,file=$(BUILD_DIR)/os_image -serial stdio

check:
@grep -RE $$'\r' source/ && echo "Found carriage returns in source files. Please run 'make format' to fix them." && exit 1 || exit 0
Expand Down
24 changes: 12 additions & 12 deletions source/kernel/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ __attribute__((noinline)) static void actualirq1Handler(void)

// send eoi to the master PIC
// this is needed in the PIC remapping, don't question it
outbb(0x20, 0x20);
outb(0x20, 0x20);
__asm__ volatile("cli");
}
}
Expand Down Expand Up @@ -78,28 +78,28 @@ void setup_pic(void)
unsigned char mask2 = inb(0xa1);

// send initialization command (0x11) to both PICs
// PIC will now wait for 4 outbb to their data port
outbb(0x20, 0x11);
// PIC will now wait for 4 outb to their data port
outb(0x20, 0x11);
io_wait();
outbb(0xa0, 0x11);
outb(0xa0, 0x11);
io_wait();

// remap PIC1 to 0x20-0x27 and PIC2 to 0x28-0x30
outbb(0x21, 0x20);
outb(0x21, 0x20);
io_wait();
outbb(0xa1, 0x28);
outb(0xa1, 0x28);
io_wait();

// tell PIC1 and PIC2 about each other
outbb(0x21, 1 << 2); // PIC2 is at IRQ2
outb(0x21, 1 << 2); // PIC2 is at IRQ2
io_wait();
outbb(0xa1, 2); // PIC1 cascade identify (idk what that means)
outb(0xa1, 2); // PIC1 cascade identify (idk what that means)
io_wait();

// tell PICs they are in 32-bit mode
outbb(0x21, 1);
outb(0x21, 1);
io_wait();
outbb(0xa1, 1);
outb(0xa1, 1);
io_wait();

// restore previous irq masks (0xb8 for PIC1 and 0x8e for PIC2)
Expand All @@ -111,9 +111,9 @@ void setup_pic(void)
// (which will enable them in hw)
mask1 = 0xff ^ (1 << 1 | 1 << 2);
mask2 = 0xff;
outbb(0x21, mask1);
outb(0x21, mask1);
io_wait();
outbb(0xa1, mask2);
outb(0xa1, mask2);
io_wait();
}

Expand Down
24 changes: 24 additions & 0 deletions source/kernel/include/serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "string.h"

enum COM_PORT {
COM1 = 0x3F8,
COM2 = 0x2F8,
COM3 = 0x3E8,
COM4 = 0x2E8,
COM5 = 0x5F8,
COM6 = 0x4F8,
COM7 = 0x5E8,
COM8 = 0x4E8
};

/**
* Return 1 if init is succesful
* Return 0 otherwise
*/
int serial_driver_init();
void write_serial(enum COM_PORT port, const char *s);

/* TODO implement this */
int read_serial(enum COM_PORT port, char *dest);
7 changes: 6 additions & 1 deletion source/kernel/init.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "init.h"
#include "serial.h"
#include "terminal_driver.h"

void init_drivers() { terminal_driver_init(); }
void init_drivers()
{
serial_driver_init();
terminal_driver_init();
}

void init_kernel_stack() {}
4 changes: 2 additions & 2 deletions source/kernel/isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ void irq_handler(registers_t *frame)
uint32_t irq_no = int_no - IRQ_OFFSET;
if (irq_no >= 8) {
// reset slave
outbb(0xA0, 0x20);
outb(0xA0, 0x20);
}
// reset master
outbb(0x20, 0x20);
outb(0x20, 0x20);
if (interrupt_handlers[int_no] != 0) {
isr_t handler = interrupt_handlers[int_no];
handler(frame);
Expand Down
5 changes: 5 additions & 0 deletions source/kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "init.h"
#include "io.h"
#include "memory.h"
#include "serial.h"
#include "string.h"
#include "terminal_driver.h"
#include "timer.h"
Expand All @@ -16,6 +17,10 @@ void main()
init_idt();
asm volatile("int $0x3");
asm volatile("int $0x4");

write_serial(COM1, "Hello From SecureOS!");
// printf(s.data);

// init_paging();
// string s;
// s.data =
Expand Down
60 changes: 60 additions & 0 deletions source/kernel/serial.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "serial.h"
#include "io.h"

static int init_serial_port(enum COM_PORT port);
inline static int putc_serial(enum COM_PORT port, char c);

int serial_driver_init()
{
return init_serial_port(COM1);

/* TODO initialize all COM ports */
}

static int init_serial_port(enum COM_PORT port)
{
outb(port + 1, 0x00); // Disable all interrupts
outb(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(port + 1, 0x00); // (hi byte)
outb(port + 3, 0x03); // 8 bits, no parity, one stop bit
outb(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(port + 4, 0x1E); // Set to loopback mode for test byte
outb(port + 0, 0xAE); // Send test byte

// If test byte was not returned, serial is faulty
if (inb(port + 0) != 0xAE)
return 0;

// // Otherwise, serial is operational, therefore disable loopback mode
outb(port + 4, 0x0F);
return 1;
}

void write_serial(enum COM_PORT port, const char *s)
{
for (size_t i = 0; s[i] != '\0'; ++i)
putc_serial(port, s[i]);
}

int read_serial(enum COM_PORT port, char *dest)
{
return 0;
}

inline static int transmit_buffer_empty(enum COM_PORT port)
{
/* Read from transmit buffer empty register */
return inb(port + 5) & 0x20;
}

inline static int putc_serial(enum COM_PORT port, char c)
{
/* Wait until transmit buffer is empty */
while (!transmit_buffer_empty(port))
;

/* Write character to output buffer */
outb(port + 0, c);
}
21 changes: 11 additions & 10 deletions source/kernel/terminal_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void terminal_put64(unsigned long long n)
temp += '0';
else
temp += 'A' - 10;

terminal_putchar(temp);
}
}
Expand All @@ -93,27 +94,27 @@ void terminal_enable_cursor()
{
uint8_t cursor_start = 0;
uint8_t cursor_end = 15;
outb(0x0A, 0x3D4);
outb((inb(0x3D5) & 0xC0) | cursor_start, 0x3D5);
outb(0x3D4, 0x0A);
outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start);

outb(0x0B, 0x3D4);
outb((inb(0x3D5) & 0xE0) | cursor_end, 0x3D5);
outb(0x3D4, 0x0B);
outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end);
}

void terminal_disable_cursor()
{
outb(0x0A, 0x3D4);
outb(0x20, 0x3D5);
outb(0x3D4, 0x0A);
outb(0x3D5, 0x20);
return;
}

void terminal_update_cursor()
{
uint16_t pos = cursor_row * VGA_WIDTH + cursor_col;
outb(0x0F, 0x3D4);
outb((uint8_t)(pos & 0xFF), 0x3D5);
outb(0x0E, 0x3D4);
outb((uint8_t)((pos >> 8) & 0xFF), 0x3D5);
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t)(pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
}

void terminal_move_cursor(uint8_t row, uint8_t col)
Expand Down
3 changes: 1 addition & 2 deletions source/libc/include/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#include "string.h"

unsigned char inb(unsigned short port);
void outb(unsigned char value, unsigned short port);
void outbb(unsigned short port, unsigned char value);
void outb(unsigned short port, unsigned char value);
void io_wait();
// printf attached to terminal for now
int printf(const char *s, ...);
Expand Down
6 changes: 1 addition & 5 deletions source/libc/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ unsigned char inb(unsigned short port)
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
void outb(unsigned char value, unsigned short port)
{
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}

void outbb(unsigned short port, unsigned char value)
void outb(unsigned short port, unsigned char value)
{
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}
Expand Down

0 comments on commit 9c791d9

Please sign in to comment.