The Great Refactoring :D

This commit is contained in:
Tyler McGurrin 2025-06-04 07:00:28 -04:00
parent 66e9e959ae
commit 8af8000bcf
31 changed files with 770 additions and 764 deletions

View File

@ -11,7 +11,7 @@ Designed to run from just one 1.44MB floppy disk, ATA support coming soon! (TM)
Good luck figuring out the spagetti code i write... (sorry not sorry ;D) Good luck figuring out the spagetti code i write... (sorry not sorry ;D)
Designed for older computers such as a Pentium (i586) Class Machine. I would recomend atleast a Pentium 2 Class or higher system however. Designed for older computers such as a Pentium (i586) Class Machine. I would recomend atleast a Pentium 2 Class System or higher however.
## Features ## Features
A funtioning Bootloader and half working kernel. A funtioning Bootloader and half working kernel.
@ -33,9 +33,10 @@ If you wanted to write it to a floppy disk you can use `write.sh` tho be careful
Testing is mostly done with QEMU These days, but I do sometimes pull out my Dell Latitude D610 to test on (for anyone wondering its completely maxed out. [2GB of ram Pentium M @ 2.23GHz]) Testing is mostly done with QEMU These days, but I do sometimes pull out my Dell Latitude D610 to test on (for anyone wondering its completely maxed out. [2GB of ram Pentium M @ 2.23GHz])
## Thanks! ## Thanks!
Nanobyte and the OSDEV wiki for providing resources for me to be able to make this. Resources I've Used Throughout the Project
- Nanobyte's Youtube Channel: https://www.youtube.com/@nanobyte-dev - Nanobyte's Youtube Channel: https://www.youtube.com/@nanobyte-dev
- OSDEV Wiki: https://wiki.osdev.org/Expanded_Main_Page - OSDEV Wiki: https://wiki.osdev.org/Expanded_Main_Page
- BrokenThorn: http://www.brokenthorn.com
And thanks to some of my favorite bands for some nice ass music! And thanks to some of my favorite bands for some nice ass music!
- King Gizzard and The Lizzard Wizzard - King Gizzard and The Lizzard Wizzard

View File

@ -22,15 +22,15 @@ echo "#include \"gdt.h\"" >> $ISRS_GEN_C
echo "" >> $ISRS_GEN_C echo "" >> $ISRS_GEN_C
for i in $(seq 0 255); do for i in $(seq 0 255); do
echo "void __attribute((cdecl)) i686_ISR${i}();" >> $ISRS_GEN_C echo "void __attribute((cdecl)) ISR${i}();" >> $ISRS_GEN_C
done done
echo "" >> $ISRS_GEN_C echo "" >> $ISRS_GEN_C
echo "void i686_ISR_InitializeGates()" >> $ISRS_GEN_C echo "void ISR_InitializeGates()" >> $ISRS_GEN_C
echo "{" >> $ISRS_GEN_C echo "{" >> $ISRS_GEN_C
for i in $(seq 0 255); do for i in $(seq 0 255); do
echo " i686_IDT_SetGate(${i}, i686_ISR${i}, i686_GDT_CODE_SEGMENT, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);" >> $ISRS_GEN_C echo " IDT_SetGate(${i}, ISR${i}, GDT_CODE_SEGMENT, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);" >> $ISRS_GEN_C
done done

View File

@ -55,7 +55,7 @@ $(BUILD_DIR)/kernel/asm/%.obj: %.asm $(HEADERS_ASM)
@echo "--> Compiled: " $< @echo "--> Compiled: " $<
arch/i686/gen_isr.c arch/i686/gen_isr.inc: arch/i686/gen_isr.c arch/i686/gen_isr.inc:
@$(SOURCE_DIR)/build_tools/generate_isrs.sh $@ @$(SOURCE_DIR)/build_scripts/genISR.sh $@
@echo "--> Compiled: ISR Gen Files" @echo "--> Compiled: ISR Gen Files"
clean: clean:

View File

@ -5,12 +5,12 @@
;/////////////////////; ;/////////////////////;
[bits 32] [bits 32]
global i686_reboot global Reboot
i686_reboot: Reboot:
XOR AL, AL XOR AL, AL
IN AL, 0x64 IN AL, 0x64
TEST AL, 0x02 TEST AL, 0x02
JNZ i686_reboot JNZ Reboot
MOV AL, 0xFC MOV AL, 0xFC
OUT 0x64, AL OUT 0x64, AL

View File

@ -5,4 +5,4 @@
\*----------------*/ \*----------------*/
#pragma once #pragma once
void __attribute__((cdecl)) i686_reboot(); void __attribute__((cdecl)) Reboot();

View File

@ -5,9 +5,9 @@
;/////////////////////; ;/////////////////////;
[bits 32] [bits 32]
; void __attribute__((cdecl)) i686_GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment); ; void __attribute__((cdecl)) GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment);
global i686_GDT_Load global GDT_Load
i686_GDT_Load: GDT_Load:
; make new call frame ; make new call frame
push ebp ; save old call frame push ebp ; save old call frame
mov ebp, esp ; initialize new call frame mov ebp, esp ; initialize new call frame

View File

@ -85,8 +85,8 @@ GDTEntry g_GDT[] = {
GDTDescriptor g_GDTDescriptor = { sizeof(g_GDT) - 1, g_GDT}; GDTDescriptor g_GDTDescriptor = { sizeof(g_GDT) - 1, g_GDT};
void __attribute__((cdecl)) i686_GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment); void __attribute__((cdecl)) GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment);
void i686_GDT_Initialize() { void GDT_Initialize() {
i686_GDT_Load(&g_GDTDescriptor, i686_GDT_CODE_SEGMENT, i686_GDT_DATA_SEGMENT); GDT_Load(&g_GDTDescriptor, GDT_CODE_SEGMENT, GDT_DATA_SEGMENT);
} }

View File

@ -5,7 +5,7 @@
\*----------------*/ \*----------------*/
#pragma once #pragma once
#define i686_GDT_CODE_SEGMENT 0x8 #define GDT_CODE_SEGMENT 0x8
#define i686_GDT_DATA_SEGMENT 0x10 #define GDT_DATA_SEGMENT 0x10
void i686_GDT_Initialize(); void GDT_Initialize();

File diff suppressed because it is too large Load Diff

View File

@ -5,9 +5,9 @@
;/////////////////////; ;/////////////////////;
[bits 32] [bits 32]
; void __attribute__((cdecl)) i686_IDT_Load(IDTDescriptor* idtDescriptor); ; void __attribute__((cdecl)) IDT_Load(IDTDescriptor* idtDescriptor);
global i686_IDT_Load global IDT_Load
i686_IDT_Load: IDT_Load:
; make new call frame ; make new call frame
push ebp ; save old call frame push ebp ; save old call frame

View File

@ -26,9 +26,9 @@ IDTEntry g_IDT[256];
IDTDescriptor g_IDTDescriptor = {sizeof(g_IDT) -1, g_IDT}; IDTDescriptor g_IDTDescriptor = {sizeof(g_IDT) -1, g_IDT};
void __attribute__((cdecl)) i686_IDT_Load(IDTDescriptor* idtDescriptor); void __attribute__((cdecl)) IDT_Load(IDTDescriptor* idtDescriptor);
void i686_IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags) { void IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags) {
g_IDT[interupt].BaseLow = ((uint32_t)base) & 0xFFFF; g_IDT[interupt].BaseLow = ((uint32_t)base) & 0xFFFF;
g_IDT[interupt].SegmentSelector = segmentDescriptor; g_IDT[interupt].SegmentSelector = segmentDescriptor;
g_IDT[interupt].Reserved = 0; g_IDT[interupt].Reserved = 0;
@ -36,15 +36,15 @@ void i686_IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint
g_IDT[interupt].BaseHigh = ((uint32_t)base >> 16) & 0xFFFF; g_IDT[interupt].BaseHigh = ((uint32_t)base >> 16) & 0xFFFF;
} }
void i686_IDT_EnableGate(int interupt) { void IDT_EnableGate(int interupt) {
FLAG_SET(g_IDT[interupt].Flags, IDT_FLAG_PRESENT); FLAG_SET(g_IDT[interupt].Flags, IDT_FLAG_PRESENT);
} }
void i686_IDT_DisableGate(int interupt) { void IDT_DisableGate(int interupt) {
FLAG_UNSET(g_IDT[interupt].Flags, IDT_FLAG_PRESENT); FLAG_UNSET(g_IDT[interupt].Flags, IDT_FLAG_PRESENT);
} }
void i686_IDT_Initialize() { void IDT_Initialize() {
i686_IDT_Load(&g_IDTDescriptor); IDT_Load(&g_IDTDescriptor);
} }

View File

@ -7,10 +7,10 @@
#include <stdint.h> #include <stdint.h>
void i686_IDT_Initialize(); void IDT_Initialize();
void i686_IDT_DisableGate(int interupt); void IDT_DisableGate(int interupt);
void i686_IDT_EnableGate(int interupt); void IDT_EnableGate(int interupt);
void i686_IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags); void IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags);
typedef enum { typedef enum {
IDT_FLAG_GATE_TASK = 0x5, IDT_FLAG_GATE_TASK = 0x5,

View File

@ -4,33 +4,33 @@
;Tyler McGurrin ; ;Tyler McGurrin ;
;/////////////////////; ;/////////////////////;
global i686_outb global outb
i686_outb: outb:
[bits 32] [bits 32]
mov dx, [esp + 4] mov dx, [esp + 4]
mov al, [esp + 8] mov al, [esp + 8]
out dx, al out dx, al
ret ret
global i686_inb global inb
i686_inb: inb:
[bits 32] [bits 32]
mov dx, [esp + 4] mov dx, [esp + 4]
xor eax, eax xor eax, eax
in al, dx in al, dx
ret ret
global i686_panic global kernel_panic
i686_panic: kernel_panic:
cli cli
hlt hlt
global i686_EnableInterrupts global EnableInterrupts
i686_EnableInterrupts: EnableInterrupts:
sti sti
ret ret
global i686_DisableInterrupts global DisableInterrupts
i686_DisableInterrupts: DisableInterrupts:
cli cli
ret ret

View File

@ -7,7 +7,7 @@
#define UNUSED_PORT 0x80 #define UNUSED_PORT 0x80
void i686_iowait() void iowait()
{ {
i686_outb(UNUSED_PORT, 0); outb(UNUSED_PORT, 0);
} }

View File

@ -7,10 +7,10 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
void __attribute__((cdecl)) i686_outb(uint16_t port, uint8_t value); void __attribute__((cdecl)) outb(uint16_t port, uint8_t value);
uint8_t __attribute__((cdecl)) i686_inb(uint16_t port); uint8_t __attribute__((cdecl)) inb(uint16_t port);
uint8_t __attribute__((cdecl)) i686_EnableInterrupts(); uint8_t __attribute__((cdecl)) EnableInterrupts();
uint8_t __attribute__((cdecl)) i686_DisableInterrupts(); uint8_t __attribute__((cdecl)) DisableInterrupts();
void i686_iowait(); void iowait();
void __attribute__((cdecl)) i686_panic(); void __attribute__((cdecl)) kernel_panic();

View File

@ -13,7 +13,7 @@
IRQHandler g_IRQHandlers[16]; IRQHandler g_IRQHandlers[16];
void i686_IRQ_Handler(Registers* regs) void IRQ_Handler(Registers* regs)
{ {
int irq = regs->interrupt - PIC_REMAP_OFFSET; int irq = regs->interrupt - PIC_REMAP_OFFSET;
@ -27,22 +27,22 @@ void i686_IRQ_Handler(Registers* regs)
printf("Unhandled IRQ %d...\n", irq); printf("Unhandled IRQ %d...\n", irq);
} }
i686_PIC_SendEndOfInterrupt(irq); PIC_SendEndOfInterrupt(irq);
} }
void i686_IRQ_Initialize() void IRQ_Initialize()
{ {
i686_PIC_Configure(PIC_REMAP_OFFSET, PIC_REMAP_OFFSET + 8); PIC_Configure(PIC_REMAP_OFFSET, PIC_REMAP_OFFSET + 8);
// register ISR handlers for each of the 16 IRQ lines // register ISR handlers for each of the 16 IRQ lines
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
i686_ISR_RegisterHandler(PIC_REMAP_OFFSET + i, i686_IRQ_Handler); ISR_RegisterHandler(PIC_REMAP_OFFSET + i, IRQ_Handler);
// enable interrupts // enable interrupts
i686_EnableInterrupts(); EnableInterrupts();
} }
void i686_IRQ_RegisterHandler(int irq, IRQHandler handler) void IRQ_RegisterHandler(int irq, IRQHandler handler)
{ {
g_IRQHandlers[irq] = handler; g_IRQHandlers[irq] = handler;
} }

View File

@ -8,5 +8,5 @@
typedef void (*IRQHandler)(Registers* regs); typedef void (*IRQHandler)(Registers* regs);
void i686_IRQ_Initialize(); void IRQ_Initialize();
void i686_IRQ_RegisterHandler(int irq, IRQHandler handler); void IRQ_RegisterHandler(int irq, IRQHandler handler);

View File

@ -5,14 +5,14 @@
;/////////////////////; ;/////////////////////;
[bits 32] [bits 32]
extern i686_ISR_Handler extern ISR_Handler
; cpu pushes to the stack: ss, esp, eflags, cs, eip ; cpu pushes to the stack: ss, esp, eflags, cs, eip
%macro ISR_NOERRORCODE 1 %macro ISR_NOERRORCODE 1
global i686_ISR%1: global ISR%1:
i686_ISR%1: ISR%1:
push 0 ; push dummy error code push 0 ; push dummy error code
push %1 ; push interrupt number push %1 ; push interrupt number
jmp isr_common jmp isr_common
@ -20,8 +20,8 @@ i686_ISR%1:
%endmacro %endmacro
%macro ISR_ERRORCODE 1 %macro ISR_ERRORCODE 1
global i686_ISR%1: global ISR%1:
i686_ISR%1: ISR%1:
; cpu pushes an error code to the stack ; cpu pushes an error code to the stack
push %1 ; push interrupt number push %1 ; push interrupt number
jmp isr_common jmp isr_common
@ -44,7 +44,7 @@ isr_common:
mov gs, ax mov gs, ax
push esp ; pass pointer to stack to C, so we can access all the pushed information push esp ; pass pointer to stack to C, so we can access all the pushed information
call i686_ISR_Handler call ISR_Handler
add esp, 4 add esp, 4
pop eax ; restore old segment pop eax ; restore old segment

View File

@ -47,17 +47,17 @@ static const char* const g_Exceptions[] = {
"" ""
}; };
void i686_ISR_InitializeGates(); void ISR_InitializeGates();
void i686_ISR_Initialize() { void ISR_Initialize() {
i686_ISR_InitializeGates(); ISR_InitializeGates();
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
i686_IDT_EnableGate(i); IDT_EnableGate(i);
// i686_IDT_DisableGate(50); // IDT_DisableGate(50);
} }
void __attribute__((cdecl)) i686_ISR_Handler(Registers* regs) { void __attribute__((cdecl)) ISR_Handler(Registers* regs) {
if (g_ISRHandlers[regs->interrupt] != NULL) if (g_ISRHandlers[regs->interrupt] != NULL)
g_ISRHandlers[regs->interrupt](regs); g_ISRHandlers[regs->interrupt](regs);
@ -69,12 +69,12 @@ void __attribute__((cdecl)) i686_ISR_Handler(Registers* regs) {
printf(" ESP=%x EBP=%x EIP=%x EFLAGS=%x CS=%x DS=%x SS=%x\n", regs->esp, regs->ebp, regs->eip, regs->eflags, regs->cs, regs->ds, regs->ss); printf(" ESP=%x EBP=%x EIP=%x EFLAGS=%x CS=%x DS=%x SS=%x\n", regs->esp, regs->ebp, regs->eip, regs->eflags, regs->cs, regs->ds, regs->ss);
printf(" INTERRUPT=%x ERRORCODE=%x\n", regs->interrupt, regs->error); printf(" INTERRUPT=%x ERRORCODE=%x\n", regs->interrupt, regs->error);
printf("KERNEL PANIC!\n"); printf("KERNEL PANIC!\n");
i686_panic(); kernel_panic();
} }
} }
void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler) void ISR_RegisterHandler(int interrupt, ISRHandler handler)
{ {
g_ISRHandlers[interrupt] = handler; g_ISRHandlers[interrupt] = handler;
i686_IDT_EnableGate(interrupt); IDT_EnableGate(interrupt);
} }

View File

@ -18,5 +18,5 @@ typedef struct
typedef void (*ISRHandler)(Registers* regs); typedef void (*ISRHandler)(Registers* regs);
void i686_ISR_Initialize(); void ISR_Initialize();
void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler); void ISR_RegisterHandler(int interrupt, ISRHandler handler);

View File

@ -34,40 +34,40 @@ enum {
PIC_CMD_READ_ISR = 0x0B PIC_CMD_READ_ISR = 0x0B
} PIC_CMD; } PIC_CMD;
void i686_PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2) void PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2)
{ {
// init control word 1 // init control word 1
i686_outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE); outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
i686_iowait(); iowait();
i686_outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE); outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
i686_iowait(); iowait();
// init control word 2 // init control word 2
i686_outb(PIC1_DATA_PORT, offsetPic1); outb(PIC1_DATA_PORT, offsetPic1);
i686_iowait(); iowait();
i686_outb(PIC2_DATA_PORT, offsetPic2); outb(PIC2_DATA_PORT, offsetPic2);
i686_iowait(); iowait();
// init control word 3 // init control word 3
i686_outb(PIC1_DATA_PORT, PIC_ICW4_BUFFER_MASTER); // tell PIC 1 it has slave at IRQ 2 outb(PIC1_DATA_PORT, PIC_ICW4_BUFFER_MASTER); // tell PIC 1 it has slave at IRQ 2
i686_iowait(); iowait();
i686_outb(PIC2_DATA_PORT, PIC_ICW4_BUFFER_SLAVE); // tell PIC 2 its cascade ID outb(PIC2_DATA_PORT, PIC_ICW4_BUFFER_SLAVE); // tell PIC 2 its cascade ID
i686_iowait(); iowait();
// init control word 4 // init control word 4
i686_outb(PIC1_DATA_PORT, PIC_ICW4_8086); outb(PIC1_DATA_PORT, PIC_ICW4_8086);
i686_iowait(); iowait();
i686_outb(PIC2_DATA_PORT, PIC_ICW4_8086); outb(PIC2_DATA_PORT, PIC_ICW4_8086);
i686_iowait(); iowait();
// clear data registers // clear data registers
i686_outb(PIC1_DATA_PORT, 0); outb(PIC1_DATA_PORT, 0);
i686_iowait(); iowait();
i686_outb(PIC2_DATA_PORT, 0); outb(PIC2_DATA_PORT, 0);
i686_iowait(); iowait();
} }
void i686_PIC_Mask(int irq) void PIC_Mask(int irq)
{ {
uint8_t port; uint8_t port;
@ -80,11 +80,11 @@ void i686_PIC_Mask(int irq)
irq -=8; irq -=8;
port = PIC2_DATA_PORT; port = PIC2_DATA_PORT;
} }
uint8_t mask = i686_inb(port); uint8_t mask = inb(port);
i686_outb(port, mask | (1 << irq)); outb(port, mask | (1 << irq));
} }
void i686_PIC_Unmask(int irq) void PIC_Unmask(int irq)
{ {
uint8_t port; uint8_t port;
@ -97,35 +97,35 @@ void i686_PIC_Unmask(int irq)
irq -=8; irq -=8;
port = PIC2_DATA_PORT; port = PIC2_DATA_PORT;
} }
uint8_t mask = i686_inb(port); uint8_t mask = inb(port);
i686_outb(port, mask & ~(1 << irq)); outb(port, mask & ~(1 << irq));
} }
void i686_PIC_Disable() void PIC_Disable()
{ {
i686_outb(PIC1_DATA_PORT, 0xFF); outb(PIC1_DATA_PORT, 0xFF);
i686_iowait(); iowait();
i686_outb(PIC2_DATA_PORT, 0xFF); outb(PIC2_DATA_PORT, 0xFF);
i686_iowait(); iowait();
} }
void i686_PIC_SendEndOfInterrupt(int irq) void PIC_SendEndOfInterrupt(int irq)
{ {
if (irq >= 8) if (irq >= 8)
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT); outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
i686_outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT); outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
} }
uint16_t i686_PIC_ReadIRQRequestRegister() uint16_t PIC_ReadIRQRequestRegister()
{ {
i686_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR); outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR);
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR); outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR);
return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8); return inb(PIC2_COMMAND_PORT) | (inb(PIC2_COMMAND_PORT) << 8);
} }
uint16_t i686_PIC_ReadInServiceRegister() uint16_t PIC_ReadInServiceRegister()
{ {
i686_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR); outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR);
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR); outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR);
return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8); return inb(PIC2_COMMAND_PORT) | (inb(PIC2_COMMAND_PORT) << 8);
} }

View File

@ -6,10 +6,10 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
void i686_PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2); void PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2);
void i686_PIC_SendEndOfInterrupt(int irq); void PIC_SendEndOfInterrupt(int irq);
void i686_PIC_Disable(); void PIC_Disable();
void i686_PIC_Mask(int irq); void PIC_Mask(int irq);
void i686_PIC_Unmask(int irq); void PIC_Unmask(int irq);
uint16_t i686_PIC_ReadIRQRequestRegister(); uint16_t PIC_ReadIRQRequestRegister();
uint16_t i686_PIC_ReadInServiceRegister(); uint16_t PIC_ReadInServiceRegister();

View File

@ -22,8 +22,8 @@ void CMOS_RTC_Handler()
uint8_t Read_CMOS(uint8_t Register) uint8_t Read_CMOS(uint8_t Register)
{ {
uint8_t data; uint8_t data;
i686_outb(0x70, Register); outb(0x70, Register);
data = i686_inb(CMOS_DATAPORT); data = inb(CMOS_DATAPORT);
return data; return data;
} }

View File

@ -13,29 +13,85 @@
extern uint16_t DEBUG_COM_PORT; extern uint16_t DEBUG_COM_PORT;
volatile unsigned char FloppyIRQRecived = false; volatile int FloppyIRQRecived = 0;
// Honestly dont care that most of this is hard-coded, im just done with this shit
void Floppy_Handler() void Floppy_Handler()
{ {
FloppyIRQRecived = true; // IRQ Handler
FloppyIRQRecived = 1;
Serial_Printf(DEBUG_COM_PORT, "Recived IRQ From Floppy Drive.\n"); Serial_Printf(DEBUG_COM_PORT, "Recived IRQ From Floppy Drive.\n");
} }
void Floppy_Drive_Init(uint8_t drive) void Floppy_IRQ_Wait()
{ {
uint8_t Buffer; // Waits until IRQ is recived
if (drive == 1) Buffer = FLOPPY_DOR_DSEL1 && FLOPPY_DOR_DSEL1 && FLOPPY_DOR_RESET && FLOPPY_DOR_MOTA && 0 && 0 && 0; while(FloppyIRQRecived == 0);
if (drive == 2) Buffer = FLOPPY_DOR_DSEL1 && FLOPPY_DOR_DSEL1 && FLOPPY_DOR_RESET && 0 && FLOPPY_DOR_MOTB && 0 && 0; FloppyIRQRecived = 0;
i686_outb(FLOPPY_DIGITAL_OUTPUT_REGISTER, Buffer); }
Serial_Printf(DEBUG_COM_PORT, "Started Floppy Drive: %u\n", drive);
// init DMA to use phys addr 1k-64k
void Floppy_Init_DMA()
{
outb(0x0a, 0x06); //mask dma channel 2
outb(0xd8, 0xff); //reset master flip-flop
outb(0x04, 0); //address=0x1000
outb(0x04, 0x10);
outb(0xd8, 0xff); //reset master flip-flop
outb(0x05, 0xff); //count to 0x23ff (number of bytes in a 3.5" floppy disk track)
outb(0x05, 0x23);
outb(0x80, 0); //external page register = 0
outb(0x0a, 0x02); //unmask dma channel 2
}
// Prep the DMA for read transfer
void Floppy_DMA_Read()
{
outb(0x0a, 0x06); //mask dma channel 2
outb(0x0b, 0x56); //single transfer, address increment, autoinit, read, channel 2
outb(0x0a, 0x02); //unmask dma channel 2
}
// Prep DMA for write transfer
void Floppy_DMA_Write()
{
outb(0x0a, 0x06); //mask dma channel 2
outb(0x0b, 0x5a); //single transfer, address increment, autoinit, write, channel 2
outb(0x0a, 0x02); //unmask dma channel 2
}
void Floppy_Write_DOR(uint8_t command )
{
// Write the DOR
outb(FLOPPY_DOR, command);
Serial_Printf(DEBUG_COM_PORT, "Wrote %u To Floppy DOR.\n", command);
}
uint8_t Floppy_Read_Status()
{
// Returns MSR (simple innit?
return inb(FLOPPY_MSR);
}
int Floppy_Check_Busy()
{
// Explains Itself.
if (Floppy_Read_Status() & FLOPPY_MSR_MASK_BUSY)
return 1;
else
return 0;
} }
void Floppy_Send_Command (uint8_t command) void Floppy_Send_Command (uint8_t command)
{ {
i686_outb(FLOPPY_DATA_FIFO, command); // Wait for DOR then send command
Serial_Printf(DEBUG_COM_PORT, "Floppy Command Sent: %u\n", command); for(int i = 0; i < 500; i++)
if(Floppy_Read_Status() & FLOPPY_MSR_MASK_DATAREG)
return outb(FLOPPY_FIFO, command);
} }
// LBA2CHS Lives Forever! Might move it later on tho
void Floppy_LBA2CHS(FLOPPY_DISK* disk, uint32_t lba, uint16_t* cylinderOut, uint16_t* sectorOut, uint16_t* headOut) { void Floppy_LBA2CHS(FLOPPY_DISK* disk, uint32_t lba, uint16_t* cylinderOut, uint16_t* sectorOut, uint16_t* headOut) {
// sector = (LBA % sectors per track + 1) // sector = (LBA % sectors per track + 1)
*sectorOut = lba % disk->sectors +1; *sectorOut = lba % disk->sectors +1;

View File

@ -18,86 +18,39 @@ void Floppy_Handler();
void Floppy_Drive_Init(uint8_t drive); void Floppy_Drive_Init(uint8_t drive);
/* When i Said i was Rewriting this POS i meant it */
enum FLOPPY_IO {
/* DOR Command Table FLOPPY_DOR = 0x3f2,
Mnemonic bit number value meaning/usage FLOPPY_MSR = 0x3f4,
MOTD 7 0x80 Set to turn drive 3's motor ON FLOPPY_FIFO = 0x3f5, //data register
MOTC 6 0x40 Set to turn drive 2's motor ON FLOPPY_CTRL = 0x3f7
MOTB 5 0x20 Set to turn drive 1's motor ON
MOTA 4 0x10 Set to turn drive 0's motor ON
IRQ 3 8 Set to enable IRQs and DMA
RESET 2 4 Clear = enter reset mode, Set = normal operation
DSEL1 and 0 0, 1 3 "Select" drive number for next access
*/
enum FloppyDORBitflags
{
FLOPPY_DOR_MOTD = 0x80,
FLOPPY_DOR_MOTC = 0x40,
FLOPPY_DOR_MOTB = 0x20,
FLOPPY_DOR_MOTA = 0x10,
FLOPPY_DOR_IRQ = 0x08,
FLOPPY_DOR_RESET = 0x04,
FLOPPY_DOR_DSEL1 = 0x01
};
/* MSR Commands
Mnemonic Bit Value
RQM 7 0x80
DIO 6 0x40
NDMA 5 0x20
CB 4 0x10
ACTD 3 8
ACTC 2 4
ACTB 1 2
ACTA 0 1
*/
enum FloppyMSRBitflags
{
FLOPPY_MSR_RQM = 0x80, // Set if it's OK (or mandatory) to exchange bytes with the FIFO IO port
FLOPPY_MSR_DIO = 0x40, // Set if FIFO IO port expects an IN opcode
FLOPPY_MSR_NDMA = 0x20, // Set in Execution phase of PIO mode read/write commands only.
FLOPPY_MSR_CB = 0x10, // Command Busy: set when command byte received, cleared at end of Result phase
FLOPPY_MSR_ACTD = 0x08, // Drive 3 is seeking
FLOPPY_MSR_ACTC = 0x04, // Drive 2 is seeking
FLOPPY_MSR_ACTB = 0x02, // Drive 1 is seeking
FLOPPY_MSR_ACTA = 0x01, // Drive 0 is seeking
}; };
// Bottom 2 Bits of DSR match CCR enum FLOPPY_DOR_MASK {
enum FloppyRegisters
{ FLOPPY_DOR_MASK_DRIVE0 = 0, //00000000 = here for completeness sake
FLOPPY_STATUS_REGISTER_A = 0x3F0, // read-only FLOPPY_DOR_MASK_DRIVE1 = 1, //00000001
FLOPPY_STATUS_REGISTER_B = 0x3F1, // read-only FLOPPY_DOR_MASK_DRIVE2 = 2, //00000010
FLOPPY_DIGITAL_OUTPUT_REGISTER = 0x3F2, FLOPPY_DOR_MASK_DRIVE3 = 3, //00000011
FLOPPY_TAPE_DRIVE_REGISTER = 0x3F3, // Basically Useless, unless for some reason you have a tape drive FLOPPY_DOR_MASK_RESET = 4, //00000100
FLOPPY_MAIN_STATUS_REGISTER = 0x3F4, // read-only FLOPPY_DOR_MASK_DMA = 8, //00001000
FLOPPY_DATARATE_SELECT_REGISTER = 0x3F4, // write-only FLOPPY_DOR_MASK_DRIVE0_MOTOR = 16, //00010000
FLOPPY_DATA_FIFO = 0x3F5, FLOPPY_DOR_MASK_DRIVE1_MOTOR = 32, //00100000
FLOPPY_DIGITAL_INPUT_REGISTER = 0x3F7, // read-only FLOPPY_DOR_MASK_DRIVE2_MOTOR = 64, //01000000
FLOPPY_CONFIGURATION_CONTROL_REGISTER = 0x3F7 // write-only FLOPPY_DOR_MASK_DRIVE3_MOTOR = 128 //10000000
}; };
enum FloppyCommands enum FLOPPY_MSR_MASK {
{
FLOPPY_READ_TRACK = 2, // generates IRQ6 FLOPPY_MSR_MASK_DRIVE1_POS_MODE = 1, //00000001
FLOPPY_SPECIFY = 3, // * set drive parameters FLOPPY_MSR_MASK_DRIVE2_POS_MODE = 2, //00000010
FLOPPY_SENSE_DRIVE_STATUS = 4, FLOPPY_MSR_MASK_DRIVE3_POS_MODE = 4, //00000100
FLOPPY_WRITE_DATA = 5, // * write to the disk FLOPPY_MSR_MASK_DRIVE4_POS_MODE = 8, //00001000
FLOPPY_READ_DATA = 6, // * read from the disk FLOPPY_MSR_MASK_BUSY = 16, //00010000
FLOPPY_RECALIBRATE = 7, // * seek to cylinder 0 FLOPPY_MSR_MASK_DMA = 32, //00100000
FLOPPY_SENSE_INTERRUPT = 8, // * ack IRQ6, get status of last command FLOPPY_MSR_MASK_DATAIO = 64, //01000000
FLOPPY_WRITE_DELETED_DATA = 9, FLOPPY_MSR_MASK_DATAREG = 128 //10000000
FLOPPY_READ_ID = 10, // generates IRQ6
FLOPPY_READ_DELETED_DATA = 12,
FLOPPY_FORMAT_TRACK = 13, // *
FLOPPY_DUMPREG = 14,
FLOPPY_SEEK = 15, // * seek both heads to cylinder X
FLOPPY_VERSION = 16, // * used during initialization, once
FLOPPY_SCAN_EQUAL = 17,
FLOPPY_PERPENDICULAR_MODE = 18, // * used during initialization, once, maybe
FLOPPY_CONFIGURE = 19, // * set controller parameters
FLOPPY_LOCK = 20, // * protect controller params from a reset
FLOPPY_VERIFY = 22,
FLOPPY_SCAN_LOW_OR_EQUAL = 25,
FLOPPY_SCAN_HIGH_OR_EQUAL = 29
}; };

View File

@ -43,49 +43,49 @@ int Init_Serial(uint16_t COM_Port, int Baud)
{ {
uint8_t Divisor = 115200 / Baud; uint8_t Divisor = 115200 / Baud;
i686_outb(COM_Port + 1, 0x00); // Disable all interrupts outb(COM_Port + 1, 0x00); // Disable all interrupts
i686_outb(COM_Port + 3, Divisor); // Enable DLAB (set baud rate divisor) outb(COM_Port + 3, Divisor); // Enable DLAB (set baud rate divisor)
i686_outb(COM_Port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud outb(COM_Port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
i686_outb(COM_Port + 1, 0x00); // (hi byte) outb(COM_Port + 1, 0x00); // (hi byte)
i686_outb(COM_Port + 3, 0x03); // 8 bits, no parity, one stop bit outb(COM_Port + 3, 0x03); // 8 bits, no parity, one stop bit
i686_outb(COM_Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold outb(COM_Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
i686_outb(COM_Port + 4, 0x0B); // IRQs enabled, RTS/DSR set outb(COM_Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
i686_outb(COM_Port + 4, 0x1E); // Set in loopback mode, test the serial chip outb(COM_Port + 4, 0x1E); // Set in loopback mode, test the serial chip
i686_outb(COM_Port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) outb(COM_Port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent) // Check if serial is faulty (i.e: not same byte as sent)
if(i686_inb(COM_Port + 0) != 0xAE) { if(inb(COM_Port + 0) != 0xAE) {
return 1; return 1;
} }
// If serial is not faulty set it in normal operation mode // If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
i686_outb(COM_Port + 4, 0x0F); outb(COM_Port + 4, 0x0F);
return 0; return 0;
} }
int Serial_Received(uint16_t COM_Port) int Serial_Received(uint16_t COM_Port)
{ {
return i686_inb(COM_Port + 5) & 1; return inb(COM_Port + 5) & 1;
} }
char Read_Serial(uint16_t COM_Port) char Read_Serial(uint16_t COM_Port)
{ {
while (Serial_Received(COM_Port) == 0); while (Serial_Received(COM_Port) == 0);
return i686_inb(COM_Port); return inb(COM_Port);
} }
int Serial_Transmit_Empty(uint16_t COM_Port) int Serial_Transmit_Empty(uint16_t COM_Port)
{ {
return i686_inb(COM_Port + 5) & 0x20; return inb(COM_Port + 5) & 0x20;
} }
void Write_Serial(uint16_t COM_Port, char a) void Write_Serial(uint16_t COM_Port, char a)
{ {
while (Serial_Transmit_Empty(COM_Port) == 0); while (Serial_Transmit_Empty(COM_Port) == 0);
i686_outb(COM_Port,a); outb(COM_Port,a);
} }
// We do the funny... // We do the funny...
extern const char g_HexChars[]; extern const char g_HexChars[];

View File

@ -13,19 +13,19 @@
void HAL_Initialize() { void HAL_Initialize() {
// init GDT // init GDT
printf("> Initializing GDT..."); printf("> Initializing GDT...");
i686_GDT_Initialize(); GDT_Initialize();
printf("Done!\n"); printf("Done!\n");
// init IDT // init IDT
printf("> Initializing IDT..."); printf("> Initializing IDT...");
i686_IDT_Initialize(); IDT_Initialize();
printf("Done!\n"); printf("Done!\n");
// init ISR // init ISR
printf("> Initializing ISR..."); printf("> Initializing ISR...");
i686_ISR_Initialize(); ISR_Initialize();
printf("Done!\n"); printf("Done!\n");
// init IRQ // init IRQ
printf("> Initializing IRQ Handling..."); printf("> Initializing IRQ Handling...");
i686_IRQ_Initialize(); IRQ_Initialize();
printf("Done!\n"); printf("Done!\n");
} }

View File

View File

@ -42,7 +42,7 @@ void timer(Registers* regs)
int keyboard_scancode; int keyboard_scancode;
void keyboard() void keyboard()
{ {
keyboard_scancode = i686_inb(PS2_KEYBOARD_PORT); keyboard_scancode = inb(PS2_KEYBOARD_PORT);
// Debug Message, need to make a serial output thingy :) // Debug Message, need to make a serial output thingy :)
Serial_Printf(DEBUG_COM_PORT, "Keycode = %d Port = %d\n", keyboard_scancode, PS2_KEYBOARD_PORT); Serial_Printf(DEBUG_COM_PORT, "Keycode = %d Port = %d\n", keyboard_scancode, PS2_KEYBOARD_PORT);
} }
@ -61,23 +61,21 @@ void __attribute__((section(".entry"))) start(BootParams* bootParams) {
movecursorpos(19, 8); movecursorpos(19, 8);
printf("Done!\n\n\n\n\n"); printf("Done!\n\n\n\n\n");
Init_Serial(DEBUG_COM_PORT, 9600); Init_Serial(DEBUG_COM_PORT, 9600);
i686_IRQ_RegisterHandler(0, timer); IRQ_RegisterHandler(0, timer);
i686_IRQ_RegisterHandler(8, CMOS_RTC_Handler); IRQ_RegisterHandler(8, CMOS_RTC_Handler);
i686_IRQ_RegisterHandler(4, COM1_Serial_Handler); IRQ_RegisterHandler(4, COM1_Serial_Handler);
// Begin Loading Basic Drivers // Begin Loading Basic Drivers
printf("Load Keyboard Driver..."); printf("Load Keyboard Driver...");
i686_IRQ_RegisterHandler(1, keyboard); IRQ_RegisterHandler(1, keyboard);
printf("Done!\n"); printf("Done!\n");
printf("Load Basic Storage Drivers..."); printf("Load Basic Storage Drivers...");
i686_IRQ_RegisterHandler(6, Floppy_Handler); IRQ_RegisterHandler(6, Floppy_Handler);
printf("Done!\n"); printf("Done!\n");
masterFDDType = Master_FDD_Detect(); masterFDDType = Master_FDD_Detect();
slaveFDDType = Slave_FDD_Detect(); slaveFDDType = Slave_FDD_Detect();
Floppy_Drive_Init(1);
Print_Storage_Types(masterFDDType, slaveFDDType); Print_Storage_Types(masterFDDType, slaveFDDType);
// printf("Kernel Params: %s\n", bootParams->KernelParams);
@ -91,8 +89,6 @@ void __attribute__((section(".entry"))) start(BootParams* bootParams) {
bootParams->Memory.Regions[i].Begin, bootParams->Memory.Regions[i].Length, bootParams->Memory.Regions[i].Type); bootParams->Memory.Regions[i].Begin, bootParams->Memory.Regions[i].Length, bootParams->Memory.Regions[i].Type);
} }
end: end:
for (;;); for (;;);
} }

View File

@ -51,10 +51,10 @@ void setcursor(int x, int y)
{ {
int pos = y * SCREEN_WIDTH + x; int pos = y * SCREEN_WIDTH + x;
i686_outb(0x3D4, 0x0F); outb(0x3D4, 0x0F);
i686_outb(0x3D5, (uint8_t)(pos & 0xFF)); outb(0x3D5, (uint8_t)(pos & 0xFF));
i686_outb(0x3D4, 0x0E); outb(0x3D4, 0x0E);
i686_outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
} }
void clrscr() void clrscr()

View File

@ -6,5 +6,5 @@
#pragma once #pragma once
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n" #define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
#define VERSION "RD-00025" #define VERSION "RD-00027"
#define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n" #define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n"