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_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
.PHONY: all
@ -74,16 +61,16 @@ iso: $(OUT_ISO)
.PHONY: run
run: $(OUT_ELF)
$(QEMU) $(QEMU_FLAGS) -kernel $(OUT_ELF)
$(QEMU) -kernel $(OUT_ELF)
.PHONY: debug
debug:
$(QEMU) $(QEMU_FLAGS) -s -S -kernel $(OUT_ELF)
$(QEMU) -s -S -kernel $(OUT_ELF)
.PHONY: run_iso
run_iso:
$(QEMU) $(QEMU_FLAGS) -cdrom $(OUT_ISO)
$(QEMU) -cdrom $(OUT_ISO)
.PHONY: 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;
};
extern char_writer_t* default_output;
int putc(char_writer_t*, char);
int print(char_writer_t*, const char*);
int println(char_writer_t*, const char*);

View file

@ -9,9 +9,9 @@
#include "io.h"
#include <stdint.h>
typedef struct serial_ctx_s {
typedef struct SerialState_s {
uint16_t port;
} serial_ctx_t;
} SerialState_t;
extern char_writer_t* default_COM;
@ -20,7 +20,7 @@ extern char_writer_t* default_COM;
* @param port The serial port number to initialize
* @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
@ -32,19 +32,19 @@ int serial_recv_pending();
* @brief Receive a single byte from the serial port
* @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
* @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
* @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

View file

@ -4,13 +4,21 @@
#include "serial.h"
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.
//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) {
default:
if(default_output){
printf(default_output, "INTERRUPT TRIGGERED! Info below.\n");
printf(default_output, "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(default_output, "GP Registers:\neax:%X\nebx:%X\necx:%X\nedx:%X\nesp:%X\nebp:%X\nesi:%X\nedi:%X\n",
if(out){
printf(out, "INTERRUPT TRIGGERED! Info below.\n");
printf(out, "Int_ID|ERR: %X|%X\n", cpu_state->interrupt_id, cpu_state->error_code);
printf(out, "EFLAGS|CS|EIP: %X|%X|%X\n", cpu_state->eflags, cpu_state->cs,cpu_state->eip);
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->ebx,
cpu_state->ecx,
@ -19,7 +27,7 @@ void generic_isr_handler(StateSnapshot_t* cpu_state) {
cpu_state->ebp,
cpu_state->esi,
cpu_state->edi);
printf(default_output, "HALT!");
printf(out, "HALT!");
while(1);
}
}

View file

@ -2,8 +2,6 @@
#include "kttools.h"
#include <stdarg.h>
char_writer_t* default_output = 0;
int printhex(char_writer_t* writer, uint32_t out) {
char buff[9];
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;
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:
default_output = default_vga;
printf(default_output, "Entry eax:%X\n", multiboot_magic);
printf(&vga_writer, "Entry eax:%X\n", multiboot_magic);
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;
} else {
println(default_output, "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);
println(&vga_writer, "Multiboot detected! Continuing...");
}
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;
int serial_init(serial_ctx_t* ctx) {
int serial_init(uint16_t port) {
//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.
outb(ctx->port + 3, 0b10000000);
outb(port + 3, 0b10000000);
//Sets the baud rate. Quick except on baud rate:
//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)
//Baud lo byte
outb(ctx->port, 0x03);
outb(port, 0x03);
//Baud hi byte
outb(ctx->port+1, 0x00);
outb(port+1, 0x00);
//Again from OSWiki we're going to use their defaults for now.
//DLAB off
//Parity=0(no Parity)
//One stop bit (set to 0)
//Transmit in units of 8 bits
outb(ctx->port+3, 0b00000011);
outb(port+3, 0b00000011);
//FIFO Control register
//14 bit threshold for interrupt trigger
//flush and enable FIFOs.
outb(ctx->port+2, 0b11000111);
outb(port+2, 0b11000111);
//Enable IRQs + DTR + RTS
//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.
outb(ctx->port+4, 0b00001011);
outb(port+4, 0b00001011);
//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
outb(ctx->port, 0xC4);
outb(port, 0xC4);
if(inb(ctx->port) != 0xC4) {
if(inb(port) != 0xC4) {
//Boo womp
return 1;
}
//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;
}
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
return !(inb(ctx->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;
return !(inb(port + 5) & 0x20);
}