Compare commits

..

No commits in common. "53198515c8d942f3c6694976d70ae78bd5ecfb95" and "d6465ade55f0357cde59e858bceb5a9c9c4dc1d6" have entirely different histories.

7 changed files with 44 additions and 71 deletions

View file

@ -25,19 +25,6 @@ OBJECTS := $(OBJECTS:.s=.o)
OUT_ELF := $(BIN_DIR)/ukern.elf OUT_ELF := $(BIN_DIR)/ukern.elf
OUT_ISO := $(BIN_DIR)/uOS.iso OUT_ISO := $(BIN_DIR)/uOS.iso
###QEMU CONFIG
QEMU_FLAGS :=
VGA ?= 1
SERIAL ?= 0
ifeq ($(VGA), 0)
QEMU_FLAGS += -display none
endif
ifeq ($(SERIAL), 1)
QEMU_FLAGS += -serial stdio
endif
###RULES ###RULES
.PHONY: all .PHONY: all
@ -74,16 +61,16 @@ iso: $(OUT_ISO)
.PHONY: run .PHONY: run
run: $(OUT_ELF) run: $(OUT_ELF)
$(QEMU) $(QEMU_FLAGS) -kernel $(OUT_ELF) $(QEMU) -kernel $(OUT_ELF)
.PHONY: debug .PHONY: debug
debug: debug:
$(QEMU) $(QEMU_FLAGS) -s -S -kernel $(OUT_ELF) $(QEMU) -s -S -kernel $(OUT_ELF)
.PHONY: run_iso .PHONY: run_iso
run_iso: run_iso:
$(QEMU) $(QEMU_FLAGS) -cdrom $(OUT_ISO) $(QEMU) -cdrom $(OUT_ISO)
.PHONY: debug_iso .PHONY: debug_iso
debug_iso: debug_iso:
$(QEMU) $(QEMU_FLAGS) -s -S -cdrom $(OUT_ISO) $(QEMU) -s -S -cdrom $(OUT_ISO)

View file

@ -14,8 +14,6 @@ struct char_writer_s {
void* ctx; void* ctx;
}; };
extern char_writer_t* default_output;
int putc(char_writer_t*, char); int putc(char_writer_t*, char);
int print(char_writer_t*, const char*); int print(char_writer_t*, const char*);
int println(char_writer_t*, const char*); int println(char_writer_t*, const char*);

View file

@ -9,9 +9,9 @@
#include "io.h" #include "io.h"
#include <stdint.h> #include <stdint.h>
typedef struct serial_ctx_s { typedef struct SerialState_s {
uint16_t port; uint16_t port;
} serial_ctx_t; } SerialState_t;
extern char_writer_t* default_COM; extern char_writer_t* default_COM;
@ -20,7 +20,7 @@ extern char_writer_t* default_COM;
* @param port The serial port number to initialize * @param port The serial port number to initialize
* @return Status code indicating success or failure * @return Status code indicating success or failure
*/ */
int serial_init(serial_ctx_t* ctx); int serial_init(uint16_t port);
/** /**
* @brief Check if there is pending data to receive on the serial port * @brief Check if there is pending data to receive on the serial port
@ -32,19 +32,19 @@ int serial_recv_pending();
* @brief Receive a single byte from the serial port * @brief Receive a single byte from the serial port
* @return The received byte as an 8-bit unsigned integer * @return The received byte as an 8-bit unsigned integer
*/ */
uint8_t serial_recv8(serial_ctx_t* ctx); uint8_t serial_recv8(uint16_t port);
/** /**
* @brief Check if the serial port is ready to send data * @brief Check if the serial port is ready to send data
* @return Non-zero if ready to send, 0 otherwise * @return Non-zero if ready to send, 0 otherwise
*/ */
int serial_send_pending(serial_ctx_t* ctx); int serial_send_pending(uint16_t port);
/** /**
* @brief Send a single byte through the serial port * @brief Send a single byte through the serial port
* @param data The 8-bit data byte to send * @param data The 8-bit data byte to send
*/ */
int serial_send8(void* ctx, char data); int serial_send8(uint16_t port, char data);
#endif #endif

View file

@ -4,13 +4,21 @@
#include "serial.h" #include "serial.h"
void generic_isr_handler(StateSnapshot_t* cpu_state) { void generic_isr_handler(StateSnapshot_t* cpu_state) {
//We made it to C for our interrupt! For now, let's just print our interrupt to the screen. //We made it to C for our interrupt! For now, let's just print our interrupt to the screen.
//What's cookin for outputs?
char_writer_t* out = 0;
if(default_COM) {
out = default_COM;
} else if(default_vga) {
out = default_vga;
vga_clear_ctx(default_vga->ctx);
}
switch(cpu_state->interrupt_id) { switch(cpu_state->interrupt_id) {
default: default:
if(default_output){ if(out){
printf(default_output, "INTERRUPT TRIGGERED! Info below.\n"); printf(out, "INTERRUPT TRIGGERED! Info below.\n");
printf(default_output, "Int_ID|ERR: %X|%X\n", cpu_state->interrupt_id, cpu_state->error_code); printf(out, "Int_ID|ERR: %X|%X\n", cpu_state->interrupt_id, cpu_state->error_code);
printf(default_output, "EFLAGS|CS|EIP: %X|%X|%X\n", cpu_state->eflags, cpu_state->cs,cpu_state->eip); printf(out, "EFLAGS|CS|EIP: %X|%X|%X\n", cpu_state->eflags, cpu_state->cs,cpu_state->eip);
printf(default_output, "GP Registers:\neax:%X\nebx:%X\necx:%X\nedx:%X\nesp:%X\nebp:%X\nesi:%X\nedi:%X\n", printf(out, "GP Registers:\neax:%X\nebx:%X\necx:%X\nedx:%X\nesp:%X\nebp:%X\nesi:%X\nedi:%X\n",
cpu_state->eax, cpu_state->eax,
cpu_state->ebx, cpu_state->ebx,
cpu_state->ecx, cpu_state->ecx,
@ -19,7 +27,7 @@ void generic_isr_handler(StateSnapshot_t* cpu_state) {
cpu_state->ebp, cpu_state->ebp,
cpu_state->esi, cpu_state->esi,
cpu_state->edi); cpu_state->edi);
printf(default_output, "HALT!"); printf(out, "HALT!");
while(1); while(1);
} }
} }

View file

@ -2,8 +2,6 @@
#include "kttools.h" #include "kttools.h"
#include <stdarg.h> #include <stdarg.h>
char_writer_t* default_output = 0;
int printhex(char_writer_t* writer, uint32_t out) { int printhex(char_writer_t* writer, uint32_t out) {
char buff[9]; char buff[9];
i_to_str(out, buff, 9, 0x10); i_to_str(out, buff, 9, 0x10);

View file

@ -25,27 +25,17 @@ void kern_main(uint32_t multiboot_magic, mb_info_t* multiboot_info)
default_vga = &vga_writer; default_vga = &vga_writer;
vga_clear_ctx(&vga_ctx); vga_clear_ctx(&vga_ctx);
//Serial prep
serial_ctx_t serial_ctx;
serial_ctx.port = COM1;
char_writer_t serial_writer;
serial_writer.ctx = &serial_ctx;
serial_writer.putChar = serial_send8;
default_COM = &serial_writer;
serial_init(&serial_ctx);
//AND OUR DEFAULT OUTPUT IS: printf(&vga_writer, "Entry eax:%X\n", multiboot_magic);
default_output = default_vga;
printf(default_output, "Entry eax:%X\n", multiboot_magic);
if(multiboot_magic != 0x2BADB002) { if(multiboot_magic != 0x2BADB002) {
println(default_output, "Bootloader not multiboot1 compliant! Needed for mmap, etc. Can't work without it, kthxbye!"); println(&vga_writer, "Bootloader not multiboot1 compliant! Needed for mmap, etc. Can't work without it, kthxbye!");
return; return;
} else { } else {
println(default_output, "Multiboot detected! Continuing..."); println(&vga_writer, "Multiboot detected! Continuing...");
} }
printf(default_output, "MEM_LOWER:%X\n", multiboot_info->mem_lower);
printf(default_output, "MEM_UPPER:%X\n", multiboot_info->mem_upper); printf(&vga_writer, "MEM_LOWER:%X\n", multiboot_info->mem_lower);
printf(&vga_writer, "MEM_UPPER:%X\n", multiboot_info->mem_upper);
} }

View file

@ -3,12 +3,11 @@
char_writer_t* default_COM = 0; char_writer_t* default_COM = 0;
int serial_init(serial_ctx_t* ctx) { int serial_init(uint16_t port) {
//disable interrupts when messing with it //disable interrupts when messing with it
outb(ctx->port + 1, 0x00); outb(port + 1, 0x00);
//set the dlab latch in order to make the baud rate accessible. In binary for clarity. //set the dlab latch in order to make the baud rate accessible. In binary for clarity.
outb(ctx->port + 3, 0b10000000); outb(port + 3, 0b10000000);
//Sets the baud rate. Quick except on baud rate: //Sets the baud rate. Quick except on baud rate:
//internal clock for the serial controller is 115200 ticks/sec. Or 115200hz. //internal clock for the serial controller is 115200 ticks/sec. Or 115200hz.
@ -19,51 +18,44 @@ int serial_init(serial_ctx_t* ctx) {
//(Source:https://wiki.osdev.org/Serial_Ports#Baud_Rate) //(Source:https://wiki.osdev.org/Serial_Ports#Baud_Rate)
//Baud lo byte //Baud lo byte
outb(ctx->port, 0x03); outb(port, 0x03);
//Baud hi byte //Baud hi byte
outb(ctx->port+1, 0x00); outb(port+1, 0x00);
//Again from OSWiki we're going to use their defaults for now. //Again from OSWiki we're going to use their defaults for now.
//DLAB off //DLAB off
//Parity=0(no Parity) //Parity=0(no Parity)
//One stop bit (set to 0) //One stop bit (set to 0)
//Transmit in units of 8 bits //Transmit in units of 8 bits
outb(ctx->port+3, 0b00000011); outb(port+3, 0b00000011);
//FIFO Control register //FIFO Control register
//14 bit threshold for interrupt trigger //14 bit threshold for interrupt trigger
//flush and enable FIFOs. //flush and enable FIFOs.
outb(ctx->port+2, 0b11000111); outb(port+2, 0b11000111);
//Enable IRQs + DTR + RTS //Enable IRQs + DTR + RTS
//Nicely explained here: https://stackoverflow.com/questions/957337/what-is-the-difference-between-dtr-dsr-and-rts-cts-flow-control //Nicely explained here: https://stackoverflow.com/questions/957337/what-is-the-difference-between-dtr-dsr-and-rts-cts-flow-control
//In the future, this will be referred to 0x0B. //In the future, this will be referred to 0x0B.
outb(ctx->port+4, 0b00001011); outb(port+4, 0b00001011);
//done! Let's test our chip. put it in loopback mode. //done! Let's test our chip. put it in loopback mode.
outb(ctx->port+4, 0x1E); outb(port+4, 0x1E);
//Lets try sending C4 (boom!) to test it //Lets try sending C4 (boom!) to test it
outb(ctx->port, 0xC4); outb(port, 0xC4);
if(inb(ctx->port) != 0xC4) { if(inb(port) != 0xC4) {
//Boo womp //Boo womp
return 1; return 1;
} }
//we're good! All set up. Lets put it back into normal operational mode and gtfo. //we're good! All set up. Lets put it back into normal operational mode and gtfo.
outb(ctx->port+4, 0x0B); outb(port+4, 0x0B);
return 0; return 0;
} }
int serial_send_pending(serial_ctx_t* ctx) { int serial_send_pending(uint16_t port) {
//Bit 5 of the line status register has our output queue, essentially //Bit 5 of the line status register has our output queue, essentially
return !(inb(ctx->port + 5) & 0x20); return !(inb(port + 5) & 0x20);
}
int serial_send8(void* ctx, char out) {
serial_ctx_t* serial_ctx = (serial_ctx_t*) ctx;
while(serial_send_pending(serial_ctx));
outb(serial_ctx->port, out);
return 0;
} }