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:
parent
4c76d5647a
commit
55d5823bde
14 changed files with 60 additions and 20 deletions
|
|
@ -1,5 +1,11 @@
|
||||||
|
/* IDT.h
|
||||||
|
* Interrupt Descriptor Table
|
||||||
|
*
|
||||||
|
* IDT related structures, globals and functions
|
||||||
|
*/
|
||||||
#ifndef IDT_H
|
#ifndef IDT_H
|
||||||
#define IDT_H
|
#define IDT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct InterruptDescriptor_s {
|
typedef struct InterruptDescriptor_s {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
/* interrupt_handlers.h
|
||||||
|
* Interrupt Handlers
|
||||||
|
*
|
||||||
|
* Functions and structs for the C side of handling interrupts.
|
||||||
|
*/
|
||||||
#ifndef INTERRUPTHANDLERS_H
|
#ifndef INTERRUPTHANDLERS_H
|
||||||
#define INTERRUPTHANDLERS_H
|
#define INTERRUPTHANDLERS_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* kio.h
|
/* kio.h
|
||||||
* Kernel I/O
|
* Kernel I/O
|
||||||
*
|
*
|
||||||
* Handles any in/output
|
* Responsible for kernel related in/output, such as VGA and serial
|
||||||
*/
|
*/
|
||||||
#ifndef KIO_H
|
#ifndef KIO_H
|
||||||
#define KIO_H
|
#define KIO_H
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
/* kmultiboot.h
|
||||||
|
* Kernel Multiboot
|
||||||
|
*
|
||||||
|
* Data needed for multiboot compatibility.
|
||||||
|
*/
|
||||||
#ifndef KMULTIBOOT_H
|
#ifndef KMULTIBOOT_H
|
||||||
#define KMULTIBOOT_H
|
#define KMULTIBOOT_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
/* kttools.h
|
||||||
|
* Kernel Type Tools
|
||||||
|
*
|
||||||
|
* Library for converting types and transcribing data.
|
||||||
|
*/
|
||||||
#ifndef KTTOOLS_H
|
#ifndef KTTOOLS_H
|
||||||
#define KTTOOLS_H
|
#define KTTOOLS_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
/* kdtables.h
|
/* tss.h
|
||||||
* Kernel Discriptor Tables
|
* Task State Segment
|
||||||
*
|
|
||||||
* Contains GDT, IDT, and any relevant functions and structs pertaining to them
|
|
||||||
*
|
*
|
||||||
|
* Structure definitions for the TSS
|
||||||
*/
|
*/
|
||||||
#ifndef TSS_H
|
#ifndef TSS_H
|
||||||
#define TSS_H
|
#define TSS_H
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ section .gdt_sect
|
||||||
dw 0
|
dw 0
|
||||||
gdt_end:
|
gdt_end:
|
||||||
gdtr:
|
gdtr:
|
||||||
|
;size of the gdt
|
||||||
dw gdt_end - gdt - 1
|
dw gdt_end - gdt - 1
|
||||||
|
;location of the gdt
|
||||||
dd gdt
|
dd gdt
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,18 @@
|
||||||
#include "interrupt_handlers.h"
|
#include "interrupt_handlers.h"
|
||||||
|
|
||||||
void setup_idt() {
|
void setup_idt() {
|
||||||
|
//IDT is pretty big. Lets make it 256 IDT entries large, 00-FF.
|
||||||
idtr.size = (sizeof(InterruptDescriptor_t) * 256) - 1;
|
idtr.size = (sizeof(InterruptDescriptor_t) * 256) - 1;
|
||||||
idtr.IDT = &idt_start;
|
idtr.IDT = &idt_start;
|
||||||
write_descriptors();
|
write_descriptors();
|
||||||
|
//load_idt is in assembly, go find it in alloc_idt.s
|
||||||
load_idt();
|
load_idt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_descriptors() {
|
void write_descriptors() {
|
||||||
|
|
||||||
for(int i = 0; i <= num_interrupts; i++) {
|
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];
|
uint32_t current_isr = (uint32_t)isr_ptrs[i];
|
||||||
InterruptDescriptor_t* current_idt_entry = idtr.IDT + i;
|
InterruptDescriptor_t* current_idt_entry = idtr.IDT + i;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
%define NUM_INTERRUPTS 255
|
||||||
global idtr, idt_start, num_interrupts, load_idt
|
global idtr, idt_start, num_interrupts, load_idt
|
||||||
|
|
||||||
|
;Stub function that just loads the IDT.
|
||||||
section .text
|
section .text
|
||||||
load_idt:
|
load_idt:
|
||||||
lidt [idtr]
|
lidt [idtr]
|
||||||
|
|
@ -10,10 +14,13 @@ section .idtr align=8
|
||||||
num_interrupts:
|
num_interrupts:
|
||||||
db NUM_INTERRUPTS
|
db NUM_INTERRUPTS
|
||||||
idtr:
|
idtr:
|
||||||
;IDTR looks like the size (minus 1) and then the pointer to the start of it.
|
;Word: size of idtr
|
||||||
dw 0
|
dw 0
|
||||||
|
;DWord: location of IDTR
|
||||||
dd 0
|
dd 0
|
||||||
|
|
||||||
section .idt nobits
|
section .idt nobits
|
||||||
|
;Reserve some space for the IDT. Actually defined later in C.
|
||||||
idt_start:
|
idt_start:
|
||||||
resb (NUM_INTERRUPTS+1) * 8
|
resb (NUM_INTERRUPTS+1) * 8
|
||||||
|
|
||||||
|
|
@ -21,23 +21,28 @@ isr_common:
|
||||||
add esp,8 ;deallocate the error code from the stack before heading out
|
add esp,8 ;deallocate the error code from the stack before heading out
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
;Macro for the isr: 1 argument for the interrupt ID
|
||||||
%macro ISR_ENTRY 1
|
%macro ISR_ENTRY 1
|
||||||
|
;isr_int#
|
||||||
isr_%1:
|
isr_%1:
|
||||||
cli
|
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
|
%if %1 = 8 || %1 = 10 || %1 = 11 || %1 = 12 || %1 = 13 || %1 = 14 || %1 = 17 || %1 = 21
|
||||||
%else
|
%else
|
||||||
push dword 0
|
push dword 0
|
||||||
%endif
|
%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
|
jmp isr_common
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
;This is to trigger the above macro once for every ISR.
|
||||||
%assign j 0
|
%assign j 0
|
||||||
%rep 255
|
%rep 255
|
||||||
ISR_ENTRY j
|
ISR_ENTRY j
|
||||||
%assign j j+1
|
%assign j j+1
|
||||||
%endrep
|
%endrep
|
||||||
|
|
||||||
; Generate a table of pointers that point to each of our ISRs. This will be accessed from C to setup our IDT.
|
; Generate a table of pointers that point to each of our ISRs. This will be accessed from C to setup our IDT.
|
||||||
isr_ptrs:
|
isr_ptrs:
|
||||||
%assign i 0
|
%assign i 0
|
||||||
|
|
|
||||||
12
src/kio.c
12
src/kio.c
|
|
@ -73,6 +73,18 @@ void vga_printdec(uint32_t out) {
|
||||||
vga_print(buff);
|
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, ...) {
|
void vga_printf(const char* fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* @brief Convert a hex int to string, up to 32 bits.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
//Hello C! Let's get to work in cleaning up our environment a bit and creating some safety.
|
||||||
//First interrupts.
|
//First interrupts.
|
||||||
vga_clear();
|
|
||||||
vga_printf("IDT base = %X", idtr.IDT);
|
|
||||||
|
|
||||||
|
|
||||||
setup_idt();
|
setup_idt();
|
||||||
|
|
||||||
vga_printf("IDT test :)");
|
|
||||||
int x = 5;
|
|
||||||
int y = 1;
|
|
||||||
x = x / (y-1);
|
|
||||||
|
|
||||||
vga_printf("%d", x);
|
|
||||||
//wipe the screen
|
//wipe the screen
|
||||||
vga_clear();
|
vga_clear();
|
||||||
//We're going to use this buffer as our 8char hex representation for reading mem
|
//We're going to use this buffer as our 8char hex representation for reading mem
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
; Bootloader places us in 32 bit mode :)
|
;start.s
|
||||||
|
;Entrypoint for kernel, hello world!
|
||||||
|
|
||||||
bits 32
|
bits 32
|
||||||
;Some symbols we'll need from other files...
|
;Some symbols we'll need from other files...
|
||||||
extern kern_main
|
extern kern_main
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue