Added tons of documentation

Still need to document a lot of functions, but I cleaned up and
explained a lot of the code via comments.
This commit is contained in:
lordtet 2025-06-28 02:11:09 -04:00
parent 4c76d5647a
commit 55d5823bde
14 changed files with 60 additions and 20 deletions

View file

@ -1,5 +1,11 @@
/* IDT.h
* Interrupt Descriptor Table
*
* IDT related structures, globals and functions
*/
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
typedef struct InterruptDescriptor_s {

View file

@ -1,3 +1,8 @@
/* interrupt_handlers.h
* Interrupt Handlers
*
* Functions and structs for the C side of handling interrupts.
*/
#ifndef INTERRUPTHANDLERS_H
#define INTERRUPTHANDLERS_H
#include <stdint.h>

View file

@ -1,7 +1,7 @@
/* kio.h
* Kernel I/O
*
* Handles any in/output
* Responsible for kernel related in/output, such as VGA and serial
*/
#ifndef KIO_H
#define KIO_H

View file

@ -1,3 +1,8 @@
/* kmultiboot.h
* Kernel Multiboot
*
* Data needed for multiboot compatibility.
*/
#ifndef KMULTIBOOT_H
#define KMULTIBOOT_H

View file

@ -1,3 +1,8 @@
/* kttools.h
* Kernel Type Tools
*
* Library for converting types and transcribing data.
*/
#ifndef KTTOOLS_H
#define KTTOOLS_H
#include <stdint.h>

View file

@ -1,8 +1,7 @@
/* kdtables.h
* Kernel Discriptor Tables
/* tss.h
* Task State Segment
*
* Contains GDT, IDT, and any relevant functions and structs pertaining to them
*
* Structure definitions for the TSS
*/
#ifndef TSS_H
#define TSS_H

View file

@ -52,6 +52,8 @@ section .gdt_sect
dw 0
gdt_end:
gdtr:
;size of the gdt
dw gdt_end - gdt - 1
;location of the gdt
dd gdt

View file

@ -2,15 +2,18 @@
#include "interrupt_handlers.h"
void setup_idt() {
//IDT is pretty big. Lets make it 256 IDT entries large, 00-FF.
idtr.size = (sizeof(InterruptDescriptor_t) * 256) - 1;
idtr.IDT = &idt_start;
write_descriptors();
//load_idt is in assembly, go find it in alloc_idt.s
load_idt();
}
void write_descriptors() {
for(int i = 0; i <= num_interrupts; i++) {
// Grab the location of the ISR we're working with and the location of the IDT entry to write it to.
uint32_t current_isr = (uint32_t)isr_ptrs[i];
InterruptDescriptor_t* current_idt_entry = idtr.IDT + i;

View file

@ -1,6 +1,10 @@
;idt_asm.s
;Memory allocation for the IDT and any assembly-required functions for it to work.
%define NUM_INTERRUPTS 255
global idtr, idt_start, num_interrupts, load_idt
;Stub function that just loads the IDT.
section .text
load_idt:
lidt [idtr]
@ -10,10 +14,13 @@ section .idtr align=8
num_interrupts:
db NUM_INTERRUPTS
idtr:
;IDTR looks like the size (minus 1) and then the pointer to the start of it.
;Word: size of idtr
dw 0
;DWord: location of IDTR
dd 0
section .idt nobits
;Reserve some space for the IDT. Actually defined later in C.
idt_start:
resb (NUM_INTERRUPTS+1) * 8

View file

@ -21,23 +21,28 @@ isr_common:
add esp,8 ;deallocate the error code from the stack before heading out
iret
;Macro for the isr: 1 argument for the interrupt ID
%macro ISR_ENTRY 1
;isr_int#
isr_%1:
cli
;Small table of interrupts that don't have an error code associated, so we push a dummy for stack consistency.
%if %1 = 8 || %1 = 10 || %1 = 11 || %1 = 12 || %1 = 13 || %1 = 14 || %1 = 17 || %1 = 21
%else
push dword 0
%endif
push dword %1 ; saving our interrupt so C knows
;This is us pushing the isr #, which is also just the interrupt ID. Useful later.
push dword %1
jmp isr_common
%endmacro
;This is to trigger the above macro once for every ISR.
%assign j 0
%rep 255
ISR_ENTRY j
%assign j j+1
%endrep
; Generate a table of pointers that point to each of our ISRs. This will be accessed from C to setup our IDT.
isr_ptrs:
%assign i 0

View file

@ -73,6 +73,18 @@ void vga_printdec(uint32_t out) {
vga_print(buff);
}
/**
* @brief Print a format string to the VGA output.
*
* Print some format string to the vga output cleanly. Supports a few format strings in C format.
*
* @param fmt: The format string to print
* @param ...: Values for the format specifiers
*
* @return No return value
*
*/
void vga_printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);

View file

@ -11,8 +11,6 @@
*/
//convert digits from int num to buffer buf. in hex. This is 32 bit only for now!
//WARN: integer is written from right to left into the buffer, and will halt if the buffer is too small.
/**
* @brief Convert a hex int to string, up to 32 bits.

View file

@ -10,18 +10,9 @@ void kern_main(uint32_t multiboot_magic, mb_info_t* multiboot_info)
{
//Hello C! Let's get to work in cleaning up our environment a bit and creating some safety.
//First interrupts.
vga_clear();
vga_printf("IDT base = %X", idtr.IDT);
setup_idt();
vga_printf("IDT test :)");
int x = 5;
int y = 1;
x = x / (y-1);
vga_printf("%d", x);
//wipe the screen
vga_clear();
//We're going to use this buffer as our 8char hex representation for reading mem

View file

@ -1,4 +1,6 @@
; Bootloader places us in 32 bit mode :)
;start.s
;Entrypoint for kernel, hello world!
bits 32
;Some symbols we'll need from other files...
extern kern_main