Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ dkms.conf
*.img


.vscode
.vscode


build/*
build/*.inc
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ DOCKER_RUN := docker run --rm \
-e PATH=/home/linuxbrew/.linuxbrew/bin:$$PATH \
$(DOCKER_IMAGE)

INCLUDE_DIRS := $(shell find $(INCLUDE_DIR) -type d)

CFLAGS := \
-g \
-O0 \
Expand All @@ -44,8 +46,8 @@ CFLAGS := \
-nostdlib \
-nostartfiles \
-nodefaultlibs \
-I$(INCLUDE_DIR)

$(foreach dir,$(INCLUDE_DIRS),-I$(dir))
.PHONY: all clean run debug format format-check lint

all: $(OS_BIN)
Expand Down Expand Up @@ -109,6 +111,12 @@ run: $(OS_BIN)
-m 512M \
-serial stdio

setup:
@if ! docker image inspect $(DOCKER_IMAGE):latest >/dev/null 2>&1; then \
docker build -t $(DOCKER_IMAGE):latest .; \
fi
$(MAKE)


debug: $(OS_BIN)
qemu-system-i386 \
Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions includes/vga.h → includes/driver/vga.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

#define LIGHT_FLAG 0x08

#define DEFUALT_F LIGHT_GRAY
#define DEFUALT_B BLACK

typedef union vga_entry {
uint16_t value;

Expand All @@ -46,6 +49,8 @@ void vga_print_char(char c);

void vga_print(const char *str);

void vga_print_hex(uint32_t value);

void vga_scan_char(char c);

void vga_scan(const char *str);
Expand Down
3 changes: 2 additions & 1 deletion includes/idt.h → includes/interrupt/idt.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#define IDT_INTERRUPT_GATE 0x8E
#define KERNEL_CODE_SELECTOR 0x08

extern uint32_t isr_table[32];
extern uint32_t isr_table[256];
extern uint32_t irq_table[16];

struct idt_entry {
uint16_t offset_low; // handler address bits 0..15
Expand Down
Empty file added includes/interrupt/irq.h
Empty file.
43 changes: 43 additions & 0 deletions includes/interrupt/isr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef ISR_H
#define ISR_H

#include <stdint.h>

char *EXCEPTIONS[] = {
"Division Error", // 00
"Debug", // 01
"Non-maskable Interrupt", // 02
"Breakpoint", // 03
"Overflow", // 04
"Bound Range Exceeded", // 05
"Invalid Opcode", // 06
"Device Not Available", // 07
"Double Fault", // 08
"Coprocessor Segment Overrun", // 09
"Invalid TSS", // 10
"Segment Not Present", // 11
"Stack-Segment Fault", // 12
"General Protection Fault", // 13
"Page Fault", // 14
"-15", // 15
"x87 Floating-Point Exception", // 16
"Alignment Check", // 17
"Machine Check", // 18
"SIMD Floating-Point Exception", // 19
"Virtualization Exception", // 20
"Control Protection Exception", // 21
"-22", // 22
"-23", // 23
"-24", // 24
"-25", // 25
"-26", // 26
"-27", // 27
"Hypervisor Injection Exception", // 28
"VMM Communication Exception", // 29
"Security Exception", // 30
"-31" // 31
};

void isr_handler(uint32_t vector);

#endif
6 changes: 0 additions & 6 deletions includes/isr.h

This file was deleted.

35 changes: 35 additions & 0 deletions includes/lib/vga_lib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef VGA_LIB_H
#define VGA_LIB_H

#include <stdint.h>

/*
* Logging
*/
void vga_log_info(const char *str0, const char *str, const char *str2);
void vga_log_success(const char *str0, const char *str, const char *str2);
void vga_log_warning(const char *str0, const char *str, const char *str2);
void vga_log_error(const char *str0, const char *str, const char *str2);

/*
* Text utilities
*/
void vga_println(const char *str);
void vga_print_at_end(const char *str);
void vga_print_at_end_c(const char *str, uint8_t color);
void vga_print_line_at(uint8_t row, const char *str);
void vga_print_centered(const char *str, uint8_t row);

/*
* Screen utilities
*/
void vga_clear_line(uint8_t row);
void vga_clear_screen(void);

/*
* Cursor utilities
*/
void vga_newline(void);
void vga_home(void);

#endif
6 changes: 6 additions & 0 deletions includes/panic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef PANIC_H
#define PANIC_H

void panic(char *err);
void exception(char *err);
#endif
2 changes: 2 additions & 0 deletions includes/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ void cli(void);
void sti(void);
void hlt(void);

uint32_t read_eflags(void);

#endif
Empty file added src/driver/pit.c
Empty file.
11 changes: 11 additions & 0 deletions src/driver/vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ void vga_print(const char *str) {
}
}

void vga_print_hex(uint32_t value) {
const char hex[] = "0123456789ABCDEF";

vga_print("0x");

for (int i = 7; i >= 0; i--) {
uint8_t digit = (value >> (i * 4)) & 0xF;
vga_print_char(hex[digit]);
}
}

void vga_set_color(uint8_t foreground, uint8_t background) {
current_color = (background << 4 | foreground);
}
Expand Down
6 changes: 6 additions & 0 deletions src/interrupt/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ void idt_init(void) {

idt_init_descriptor();

// isr
for (uint8_t i = 0; i < 32; i++) {
idt_set_gate(i, isr_table[i], KERNEL_CODE_SELECTOR, IDT_INTERRUPT_GATE);
}

// irq
for (uint8_t i = 32; i < 48; i++) {
idt_set_gate(i, irq_table[i - 32], KERNEL_CODE_SELECTOR, IDT_INTERRUPT_GATE);
}

idt_load();
}
149 changes: 149 additions & 0 deletions src/interrupt/irq.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
; ============================================================
; IRQ handlers 0-15
;
; PIC IRQs:
; IRQ 0 -> IDT vector 32
; IRQ 1 -> IDT vector 33
; ...
; IRQ 15 -> IDT vector 47
;
; The IDT uses vectors 32-47, but we pass IRQ numbers
; 0-15 to the C IRQ handler.
; ============================================================

[BITS 32]


; ============================================================
; Export IRQ handlers and IRQ table
; ============================================================

global irq0
global irq1
global irq2
global irq3
global irq4
global irq5
global irq6
global irq7
global irq8
global irq9
global irq10
global irq11
global irq12
global irq13
global irq14
global irq15

global irq_table


extern irq_handler


; ============================================================
; IRQ macro
;
; IRQs do NOT automatically push an error code.
;
; We push:
;
; 1. dummy error code
; 2. IRQ number
;
; This gives us a predictable stack layout.
; ============================================================

%macro IRQ 1

irq%1:

cli

push dword 0 ; dummy error code
push dword %1 ; IRQ number: 0-15

jmp irq_common_stub

%endmacro


; ============================================================
; IRQ entry points
; ============================================================

IRQ 0
IRQ 1
IRQ 2
IRQ 3
IRQ 4
IRQ 5
IRQ 6
IRQ 7
IRQ 8
IRQ 9
IRQ 10
IRQ 11
IRQ 12
IRQ 13
IRQ 14
IRQ 15


; ============================================================
; IRQ table
;
; irq_table[0] -> irq0
; irq_table[1] -> irq1
; ...
; irq_table[15] -> irq15
; ============================================================

section .data

irq_table:
dd irq0
dd irq1
dd irq2
dd irq3
dd irq4
dd irq5
dd irq6
dd irq7
dd irq8
dd irq9
dd irq10
dd irq11
dd irq12
dd irq13
dd irq14
dd irq15


; ============================================================
; Common IRQ stub
; ============================================================

section .text

irq_common_stub:

; Save general-purpose registers
pusha

; Pass pointer to interrupt frame
push esp
call irq_handler
add esp, 4

; Restore general-purpose registers
popa

; Remove:
;
; 4 bytes = IRQ number
; 4 bytes = dummy error code
;
add esp, 8

iretd
9 changes: 9 additions & 0 deletions src/interrupt/irq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "irq.h"
#include "vga.h"
#include "vga_lib.h"

void irq_handler(uint32_t vector) {
vga_print("IRQ: ");
vga_print_hex(vector);
vga_print("\n");
}
Loading
Loading