The Great Refactoring :D
This commit is contained in:
parent
66e9e959ae
commit
8af8000bcf
@ -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)
|
||||
|
||||
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
|
||||
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])
|
||||
|
||||
## 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
|
||||
- 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!
|
||||
- King Gizzard and The Lizzard Wizzard
|
||||
|
||||
@ -22,15 +22,15 @@ echo "#include \"gdt.h\"" >> $ISRS_GEN_C
|
||||
echo "" >> $ISRS_GEN_C
|
||||
|
||||
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
|
||||
|
||||
echo "" >> $ISRS_GEN_C
|
||||
echo "void i686_ISR_InitializeGates()" >> $ISRS_GEN_C
|
||||
echo "void ISR_InitializeGates()" >> $ISRS_GEN_C
|
||||
echo "{" >> $ISRS_GEN_C
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ $(BUILD_DIR)/kernel/asm/%.obj: %.asm $(HEADERS_ASM)
|
||||
@echo "--> Compiled: " $<
|
||||
|
||||
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"
|
||||
|
||||
clean:
|
||||
|
||||
@ -5,12 +5,12 @@
|
||||
;/////////////////////;
|
||||
[bits 32]
|
||||
|
||||
global i686_reboot
|
||||
i686_reboot:
|
||||
global Reboot
|
||||
Reboot:
|
||||
XOR AL, AL
|
||||
IN AL, 0x64
|
||||
TEST AL, 0x02
|
||||
JNZ i686_reboot
|
||||
JNZ Reboot
|
||||
|
||||
MOV AL, 0xFC
|
||||
OUT 0x64, AL
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
void __attribute__((cdecl)) i686_reboot();
|
||||
void __attribute__((cdecl)) Reboot();
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
;/////////////////////;
|
||||
[bits 32]
|
||||
|
||||
; void __attribute__((cdecl)) i686_GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment);
|
||||
global i686_GDT_Load
|
||||
i686_GDT_Load:
|
||||
; void __attribute__((cdecl)) GDT_Load(GDTDescriptor* descriptor, uint16_t codeSegment, uint16_t dataSegment);
|
||||
global GDT_Load
|
||||
GDT_Load:
|
||||
; make new call frame
|
||||
push ebp ; save old call frame
|
||||
mov ebp, esp ; initialize new call frame
|
||||
|
||||
@ -85,8 +85,8 @@ GDTEntry 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() {
|
||||
i686_GDT_Load(&g_GDTDescriptor, i686_GDT_CODE_SEGMENT, i686_GDT_DATA_SEGMENT);
|
||||
void GDT_Initialize() {
|
||||
GDT_Load(&g_GDTDescriptor, GDT_CODE_SEGMENT, GDT_DATA_SEGMENT);
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
#define i686_GDT_CODE_SEGMENT 0x8
|
||||
#define i686_GDT_DATA_SEGMENT 0x10
|
||||
#define GDT_CODE_SEGMENT 0x8
|
||||
#define GDT_DATA_SEGMENT 0x10
|
||||
|
||||
void i686_GDT_Initialize();
|
||||
void GDT_Initialize();
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,9 +5,9 @@
|
||||
;/////////////////////;
|
||||
[bits 32]
|
||||
|
||||
; void __attribute__((cdecl)) i686_IDT_Load(IDTDescriptor* idtDescriptor);
|
||||
global i686_IDT_Load
|
||||
i686_IDT_Load:
|
||||
; void __attribute__((cdecl)) IDT_Load(IDTDescriptor* idtDescriptor);
|
||||
global IDT_Load
|
||||
IDT_Load:
|
||||
|
||||
; make new call frame
|
||||
push ebp ; save old call frame
|
||||
|
||||
@ -26,9 +26,9 @@ IDTEntry g_IDT[256];
|
||||
|
||||
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].SegmentSelector = segmentDescriptor;
|
||||
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;
|
||||
}
|
||||
|
||||
void i686_IDT_EnableGate(int interupt) {
|
||||
void IDT_EnableGate(int interupt) {
|
||||
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);
|
||||
}
|
||||
|
||||
void i686_IDT_Initialize() {
|
||||
i686_IDT_Load(&g_IDTDescriptor);
|
||||
void IDT_Initialize() {
|
||||
IDT_Load(&g_IDTDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@ -7,10 +7,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void i686_IDT_Initialize();
|
||||
void i686_IDT_DisableGate(int interupt);
|
||||
void i686_IDT_EnableGate(int interupt);
|
||||
void i686_IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags);
|
||||
void IDT_Initialize();
|
||||
void IDT_DisableGate(int interupt);
|
||||
void IDT_EnableGate(int interupt);
|
||||
void IDT_SetGate(int interupt, void* base, uint16_t segmentDescriptor, uint8_t flags);
|
||||
|
||||
typedef enum {
|
||||
IDT_FLAG_GATE_TASK = 0x5,
|
||||
|
||||
@ -4,33 +4,33 @@
|
||||
;Tyler McGurrin ;
|
||||
;/////////////////////;
|
||||
|
||||
global i686_outb
|
||||
i686_outb:
|
||||
global outb
|
||||
outb:
|
||||
[bits 32]
|
||||
mov dx, [esp + 4]
|
||||
mov al, [esp + 8]
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
global i686_inb
|
||||
i686_inb:
|
||||
global inb
|
||||
inb:
|
||||
[bits 32]
|
||||
mov dx, [esp + 4]
|
||||
xor eax, eax
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
global i686_panic
|
||||
i686_panic:
|
||||
global kernel_panic
|
||||
kernel_panic:
|
||||
cli
|
||||
hlt
|
||||
|
||||
global i686_EnableInterrupts
|
||||
i686_EnableInterrupts:
|
||||
global EnableInterrupts
|
||||
EnableInterrupts:
|
||||
sti
|
||||
ret
|
||||
|
||||
global i686_DisableInterrupts
|
||||
i686_DisableInterrupts:
|
||||
global DisableInterrupts
|
||||
DisableInterrupts:
|
||||
cli
|
||||
ret
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#define UNUSED_PORT 0x80
|
||||
|
||||
void i686_iowait()
|
||||
void iowait()
|
||||
{
|
||||
i686_outb(UNUSED_PORT, 0);
|
||||
outb(UNUSED_PORT, 0);
|
||||
}
|
||||
@ -7,10 +7,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void __attribute__((cdecl)) i686_outb(uint16_t port, uint8_t value);
|
||||
uint8_t __attribute__((cdecl)) i686_inb(uint16_t port);
|
||||
uint8_t __attribute__((cdecl)) i686_EnableInterrupts();
|
||||
uint8_t __attribute__((cdecl)) i686_DisableInterrupts();
|
||||
void __attribute__((cdecl)) outb(uint16_t port, uint8_t value);
|
||||
uint8_t __attribute__((cdecl)) inb(uint16_t port);
|
||||
uint8_t __attribute__((cdecl)) EnableInterrupts();
|
||||
uint8_t __attribute__((cdecl)) DisableInterrupts();
|
||||
|
||||
void i686_iowait();
|
||||
void __attribute__((cdecl)) i686_panic();
|
||||
void iowait();
|
||||
void __attribute__((cdecl)) kernel_panic();
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
IRQHandler g_IRQHandlers[16];
|
||||
|
||||
void i686_IRQ_Handler(Registers* regs)
|
||||
void IRQ_Handler(Registers* regs)
|
||||
{
|
||||
int irq = regs->interrupt - PIC_REMAP_OFFSET;
|
||||
|
||||
@ -27,22 +27,22 @@ void i686_IRQ_Handler(Registers* regs)
|
||||
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
|
||||
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
|
||||
i686_EnableInterrupts();
|
||||
EnableInterrupts();
|
||||
}
|
||||
|
||||
void i686_IRQ_RegisterHandler(int irq, IRQHandler handler)
|
||||
void IRQ_RegisterHandler(int irq, IRQHandler handler)
|
||||
{
|
||||
g_IRQHandlers[irq] = handler;
|
||||
}
|
||||
@ -8,5 +8,5 @@
|
||||
|
||||
typedef void (*IRQHandler)(Registers* regs);
|
||||
|
||||
void i686_IRQ_Initialize();
|
||||
void i686_IRQ_RegisterHandler(int irq, IRQHandler handler);
|
||||
void IRQ_Initialize();
|
||||
void IRQ_RegisterHandler(int irq, IRQHandler handler);
|
||||
@ -5,14 +5,14 @@
|
||||
;/////////////////////;
|
||||
[bits 32]
|
||||
|
||||
extern i686_ISR_Handler
|
||||
extern ISR_Handler
|
||||
|
||||
; cpu pushes to the stack: ss, esp, eflags, cs, eip
|
||||
|
||||
%macro ISR_NOERRORCODE 1
|
||||
|
||||
global i686_ISR%1:
|
||||
i686_ISR%1:
|
||||
global ISR%1:
|
||||
ISR%1:
|
||||
push 0 ; push dummy error code
|
||||
push %1 ; push interrupt number
|
||||
jmp isr_common
|
||||
@ -20,8 +20,8 @@ i686_ISR%1:
|
||||
%endmacro
|
||||
|
||||
%macro ISR_ERRORCODE 1
|
||||
global i686_ISR%1:
|
||||
i686_ISR%1:
|
||||
global ISR%1:
|
||||
ISR%1:
|
||||
; cpu pushes an error code to the stack
|
||||
push %1 ; push interrupt number
|
||||
jmp isr_common
|
||||
@ -44,7 +44,7 @@ isr_common:
|
||||
mov gs, ax
|
||||
|
||||
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
|
||||
|
||||
pop eax ; restore old segment
|
||||
|
||||
@ -47,17 +47,17 @@ static const char* const g_Exceptions[] = {
|
||||
""
|
||||
};
|
||||
|
||||
void i686_ISR_InitializeGates();
|
||||
void ISR_InitializeGates();
|
||||
|
||||
void i686_ISR_Initialize() {
|
||||
i686_ISR_InitializeGates();
|
||||
void ISR_Initialize() {
|
||||
ISR_InitializeGates();
|
||||
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)
|
||||
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(" INTERRUPT=%x ERRORCODE=%x\n", regs->interrupt, regs->error);
|
||||
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;
|
||||
i686_IDT_EnableGate(interrupt);
|
||||
IDT_EnableGate(interrupt);
|
||||
}
|
||||
@ -18,5 +18,5 @@ typedef struct
|
||||
|
||||
typedef void (*ISRHandler)(Registers* regs);
|
||||
|
||||
void i686_ISR_Initialize();
|
||||
void i686_ISR_RegisterHandler(int interrupt, ISRHandler handler);
|
||||
void ISR_Initialize();
|
||||
void ISR_RegisterHandler(int interrupt, ISRHandler handler);
|
||||
@ -34,40 +34,40 @@ enum {
|
||||
PIC_CMD_READ_ISR = 0x0B
|
||||
} 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
|
||||
i686_outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
|
||||
i686_iowait();
|
||||
outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
|
||||
iowait();
|
||||
outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITITALIZE);
|
||||
iowait();
|
||||
|
||||
// init control word 2
|
||||
i686_outb(PIC1_DATA_PORT, offsetPic1);
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_DATA_PORT, offsetPic2);
|
||||
i686_iowait();
|
||||
outb(PIC1_DATA_PORT, offsetPic1);
|
||||
iowait();
|
||||
outb(PIC2_DATA_PORT, offsetPic2);
|
||||
iowait();
|
||||
|
||||
// init control word 3
|
||||
i686_outb(PIC1_DATA_PORT, PIC_ICW4_BUFFER_MASTER); // tell PIC 1 it has slave at IRQ 2
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_DATA_PORT, PIC_ICW4_BUFFER_SLAVE); // tell PIC 2 its cascade ID
|
||||
i686_iowait();
|
||||
outb(PIC1_DATA_PORT, PIC_ICW4_BUFFER_MASTER); // tell PIC 1 it has slave at IRQ 2
|
||||
iowait();
|
||||
outb(PIC2_DATA_PORT, PIC_ICW4_BUFFER_SLAVE); // tell PIC 2 its cascade ID
|
||||
iowait();
|
||||
|
||||
// init control word 4
|
||||
i686_outb(PIC1_DATA_PORT, PIC_ICW4_8086);
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_DATA_PORT, PIC_ICW4_8086);
|
||||
i686_iowait();
|
||||
outb(PIC1_DATA_PORT, PIC_ICW4_8086);
|
||||
iowait();
|
||||
outb(PIC2_DATA_PORT, PIC_ICW4_8086);
|
||||
iowait();
|
||||
|
||||
// clear data registers
|
||||
i686_outb(PIC1_DATA_PORT, 0);
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_DATA_PORT, 0);
|
||||
i686_iowait();
|
||||
outb(PIC1_DATA_PORT, 0);
|
||||
iowait();
|
||||
outb(PIC2_DATA_PORT, 0);
|
||||
iowait();
|
||||
}
|
||||
|
||||
void i686_PIC_Mask(int irq)
|
||||
void PIC_Mask(int irq)
|
||||
{
|
||||
uint8_t port;
|
||||
|
||||
@ -80,11 +80,11 @@ void i686_PIC_Mask(int irq)
|
||||
irq -=8;
|
||||
port = PIC2_DATA_PORT;
|
||||
}
|
||||
uint8_t mask = i686_inb(port);
|
||||
i686_outb(port, mask | (1 << irq));
|
||||
uint8_t mask = inb(port);
|
||||
outb(port, mask | (1 << irq));
|
||||
}
|
||||
|
||||
void i686_PIC_Unmask(int irq)
|
||||
void PIC_Unmask(int irq)
|
||||
{
|
||||
uint8_t port;
|
||||
|
||||
@ -97,35 +97,35 @@ void i686_PIC_Unmask(int irq)
|
||||
irq -=8;
|
||||
port = PIC2_DATA_PORT;
|
||||
}
|
||||
uint8_t mask = i686_inb(port);
|
||||
i686_outb(port, mask & ~(1 << irq));
|
||||
uint8_t mask = inb(port);
|
||||
outb(port, mask & ~(1 << irq));
|
||||
}
|
||||
|
||||
void i686_PIC_Disable()
|
||||
void PIC_Disable()
|
||||
{
|
||||
i686_outb(PIC1_DATA_PORT, 0xFF);
|
||||
i686_iowait();
|
||||
i686_outb(PIC2_DATA_PORT, 0xFF);
|
||||
i686_iowait();
|
||||
outb(PIC1_DATA_PORT, 0xFF);
|
||||
iowait();
|
||||
outb(PIC2_DATA_PORT, 0xFF);
|
||||
iowait();
|
||||
}
|
||||
|
||||
void i686_PIC_SendEndOfInterrupt(int irq)
|
||||
void PIC_SendEndOfInterrupt(int irq)
|
||||
{
|
||||
if (irq >= 8)
|
||||
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
|
||||
i686_outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
|
||||
outb(PIC2_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);
|
||||
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR);
|
||||
return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8);
|
||||
outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR);
|
||||
outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR);
|
||||
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);
|
||||
i686_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR);
|
||||
return i686_inb(PIC2_COMMAND_PORT) | (i686_inb(PIC2_COMMAND_PORT) << 8);
|
||||
outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR);
|
||||
outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR);
|
||||
return inb(PIC2_COMMAND_PORT) | (inb(PIC2_COMMAND_PORT) << 8);
|
||||
}
|
||||
@ -6,10 +6,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
void i686_PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2);
|
||||
void i686_PIC_SendEndOfInterrupt(int irq);
|
||||
void i686_PIC_Disable();
|
||||
void i686_PIC_Mask(int irq);
|
||||
void i686_PIC_Unmask(int irq);
|
||||
uint16_t i686_PIC_ReadIRQRequestRegister();
|
||||
uint16_t i686_PIC_ReadInServiceRegister();
|
||||
void PIC_Configure(uint8_t offsetPic1, uint8_t offsetPic2);
|
||||
void PIC_SendEndOfInterrupt(int irq);
|
||||
void PIC_Disable();
|
||||
void PIC_Mask(int irq);
|
||||
void PIC_Unmask(int irq);
|
||||
uint16_t PIC_ReadIRQRequestRegister();
|
||||
uint16_t PIC_ReadInServiceRegister();
|
||||
@ -22,8 +22,8 @@ void CMOS_RTC_Handler()
|
||||
uint8_t Read_CMOS(uint8_t Register)
|
||||
{
|
||||
uint8_t data;
|
||||
i686_outb(0x70, Register);
|
||||
data = i686_inb(CMOS_DATAPORT);
|
||||
outb(0x70, Register);
|
||||
data = inb(CMOS_DATAPORT);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -13,29 +13,85 @@
|
||||
|
||||
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()
|
||||
{
|
||||
FloppyIRQRecived = true;
|
||||
// IRQ Handler
|
||||
FloppyIRQRecived = 1;
|
||||
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;
|
||||
if (drive == 1) Buffer = FLOPPY_DOR_DSEL1 && FLOPPY_DOR_DSEL1 && FLOPPY_DOR_RESET && FLOPPY_DOR_MOTA && 0 && 0 && 0;
|
||||
if (drive == 2) Buffer = FLOPPY_DOR_DSEL1 && FLOPPY_DOR_DSEL1 && FLOPPY_DOR_RESET && 0 && FLOPPY_DOR_MOTB && 0 && 0;
|
||||
i686_outb(FLOPPY_DIGITAL_OUTPUT_REGISTER, Buffer);
|
||||
Serial_Printf(DEBUG_COM_PORT, "Started Floppy Drive: %u\n", drive);
|
||||
// Waits until IRQ is recived
|
||||
while(FloppyIRQRecived == 0);
|
||||
FloppyIRQRecived = 0;
|
||||
}
|
||||
|
||||
void Floppy_Send_Command(uint8_t command)
|
||||
// init DMA to use phys addr 1k-64k
|
||||
void Floppy_Init_DMA()
|
||||
{
|
||||
i686_outb(FLOPPY_DATA_FIFO, command);
|
||||
Serial_Printf(DEBUG_COM_PORT, "Floppy Command Sent: %u\n", command);
|
||||
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)
|
||||
{
|
||||
// Wait for DOR then send 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) {
|
||||
// sector = (LBA % sectors per track + 1)
|
||||
*sectorOut = lba % disk->sectors +1;
|
||||
|
||||
@ -18,86 +18,39 @@ void Floppy_Handler();
|
||||
void Floppy_Drive_Init(uint8_t drive);
|
||||
|
||||
|
||||
/* When i Said i was Rewriting this POS i meant it */
|
||||
|
||||
|
||||
/* DOR Command Table
|
||||
Mnemonic bit number value meaning/usage
|
||||
MOTD 7 0x80 Set to turn drive 3's motor ON
|
||||
MOTC 6 0x40 Set to turn drive 2's motor ON
|
||||
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
|
||||
enum FLOPPY_IO {
|
||||
|
||||
FLOPPY_DOR = 0x3f2,
|
||||
FLOPPY_MSR = 0x3f4,
|
||||
FLOPPY_FIFO = 0x3f5, //data register
|
||||
FLOPPY_CTRL = 0x3f7
|
||||
};
|
||||
|
||||
// Bottom 2 Bits of DSR match CCR
|
||||
enum FloppyRegisters
|
||||
{
|
||||
FLOPPY_STATUS_REGISTER_A = 0x3F0, // read-only
|
||||
FLOPPY_STATUS_REGISTER_B = 0x3F1, // read-only
|
||||
FLOPPY_DIGITAL_OUTPUT_REGISTER = 0x3F2,
|
||||
FLOPPY_TAPE_DRIVE_REGISTER = 0x3F3, // Basically Useless, unless for some reason you have a tape drive
|
||||
FLOPPY_MAIN_STATUS_REGISTER = 0x3F4, // read-only
|
||||
FLOPPY_DATARATE_SELECT_REGISTER = 0x3F4, // write-only
|
||||
FLOPPY_DATA_FIFO = 0x3F5,
|
||||
FLOPPY_DIGITAL_INPUT_REGISTER = 0x3F7, // read-only
|
||||
FLOPPY_CONFIGURATION_CONTROL_REGISTER = 0x3F7 // write-only
|
||||
enum FLOPPY_DOR_MASK {
|
||||
|
||||
FLOPPY_DOR_MASK_DRIVE0 = 0, //00000000 = here for completeness sake
|
||||
FLOPPY_DOR_MASK_DRIVE1 = 1, //00000001
|
||||
FLOPPY_DOR_MASK_DRIVE2 = 2, //00000010
|
||||
FLOPPY_DOR_MASK_DRIVE3 = 3, //00000011
|
||||
FLOPPY_DOR_MASK_RESET = 4, //00000100
|
||||
FLOPPY_DOR_MASK_DMA = 8, //00001000
|
||||
FLOPPY_DOR_MASK_DRIVE0_MOTOR = 16, //00010000
|
||||
FLOPPY_DOR_MASK_DRIVE1_MOTOR = 32, //00100000
|
||||
FLOPPY_DOR_MASK_DRIVE2_MOTOR = 64, //01000000
|
||||
FLOPPY_DOR_MASK_DRIVE3_MOTOR = 128 //10000000
|
||||
};
|
||||
|
||||
enum FLOPPY_MSR_MASK {
|
||||
|
||||
FLOPPY_MSR_MASK_DRIVE1_POS_MODE = 1, //00000001
|
||||
FLOPPY_MSR_MASK_DRIVE2_POS_MODE = 2, //00000010
|
||||
FLOPPY_MSR_MASK_DRIVE3_POS_MODE = 4, //00000100
|
||||
FLOPPY_MSR_MASK_DRIVE4_POS_MODE = 8, //00001000
|
||||
FLOPPY_MSR_MASK_BUSY = 16, //00010000
|
||||
FLOPPY_MSR_MASK_DMA = 32, //00100000
|
||||
FLOPPY_MSR_MASK_DATAIO = 64, //01000000
|
||||
FLOPPY_MSR_MASK_DATAREG = 128 //10000000
|
||||
};
|
||||
|
||||
enum FloppyCommands
|
||||
{
|
||||
FLOPPY_READ_TRACK = 2, // generates IRQ6
|
||||
FLOPPY_SPECIFY = 3, // * set drive parameters
|
||||
FLOPPY_SENSE_DRIVE_STATUS = 4,
|
||||
FLOPPY_WRITE_DATA = 5, // * write to the disk
|
||||
FLOPPY_READ_DATA = 6, // * read from the disk
|
||||
FLOPPY_RECALIBRATE = 7, // * seek to cylinder 0
|
||||
FLOPPY_SENSE_INTERRUPT = 8, // * ack IRQ6, get status of last command
|
||||
FLOPPY_WRITE_DELETED_DATA = 9,
|
||||
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
|
||||
};
|
||||
@ -43,49 +43,49 @@ int Init_Serial(uint16_t COM_Port, int Baud)
|
||||
{
|
||||
uint8_t Divisor = 115200 / Baud;
|
||||
|
||||
i686_outb(COM_Port + 1, 0x00); // Disable all interrupts
|
||||
i686_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
|
||||
i686_outb(COM_Port + 1, 0x00); // (hi byte)
|
||||
i686_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
|
||||
i686_outb(COM_Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
i686_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 + 1, 0x00); // Disable all interrupts
|
||||
outb(COM_Port + 3, Divisor); // Enable DLAB (set baud rate divisor)
|
||||
outb(COM_Port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||
outb(COM_Port + 1, 0x00); // (hi byte)
|
||||
outb(COM_Port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
outb(COM_Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
outb(COM_Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
outb(COM_Port + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||
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)
|
||||
if(i686_inb(COM_Port + 0) != 0xAE) {
|
||||
if(inb(COM_Port + 0) != 0xAE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If serial is not faulty set it in normal operation mode
|
||||
// (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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while (Serial_Received(COM_Port) == 0);
|
||||
|
||||
return i686_inb(COM_Port);
|
||||
return inb(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)
|
||||
{
|
||||
while (Serial_Transmit_Empty(COM_Port) == 0);
|
||||
|
||||
i686_outb(COM_Port,a);
|
||||
outb(COM_Port,a);
|
||||
}
|
||||
// We do the funny...
|
||||
extern const char g_HexChars[];
|
||||
|
||||
@ -13,19 +13,19 @@
|
||||
void HAL_Initialize() {
|
||||
// init GDT
|
||||
printf("> Initializing GDT...");
|
||||
i686_GDT_Initialize();
|
||||
GDT_Initialize();
|
||||
printf("Done!\n");
|
||||
// init IDT
|
||||
printf("> Initializing IDT...");
|
||||
i686_IDT_Initialize();
|
||||
IDT_Initialize();
|
||||
printf("Done!\n");
|
||||
// init ISR
|
||||
printf("> Initializing ISR...");
|
||||
i686_ISR_Initialize();
|
||||
ISR_Initialize();
|
||||
printf("Done!\n");
|
||||
// init IRQ
|
||||
printf("> Initializing IRQ Handling...");
|
||||
i686_IRQ_Initialize();
|
||||
IRQ_Initialize();
|
||||
printf("Done!\n");
|
||||
|
||||
}
|
||||
@ -42,7 +42,7 @@ void timer(Registers* regs)
|
||||
int keyboard_scancode;
|
||||
void keyboard()
|
||||
{
|
||||
keyboard_scancode = i686_inb(PS2_KEYBOARD_PORT);
|
||||
keyboard_scancode = inb(PS2_KEYBOARD_PORT);
|
||||
// Debug Message, need to make a serial output thingy :)
|
||||
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);
|
||||
printf("Done!\n\n\n\n\n");
|
||||
Init_Serial(DEBUG_COM_PORT, 9600);
|
||||
i686_IRQ_RegisterHandler(0, timer);
|
||||
i686_IRQ_RegisterHandler(8, CMOS_RTC_Handler);
|
||||
i686_IRQ_RegisterHandler(4, COM1_Serial_Handler);
|
||||
IRQ_RegisterHandler(0, timer);
|
||||
IRQ_RegisterHandler(8, CMOS_RTC_Handler);
|
||||
IRQ_RegisterHandler(4, COM1_Serial_Handler);
|
||||
|
||||
// Begin Loading Basic Drivers
|
||||
printf("Load Keyboard Driver...");
|
||||
i686_IRQ_RegisterHandler(1, keyboard);
|
||||
IRQ_RegisterHandler(1, keyboard);
|
||||
printf("Done!\n");
|
||||
|
||||
printf("Load Basic Storage Drivers...");
|
||||
i686_IRQ_RegisterHandler(6, Floppy_Handler);
|
||||
IRQ_RegisterHandler(6, Floppy_Handler);
|
||||
printf("Done!\n");
|
||||
masterFDDType = Master_FDD_Detect();
|
||||
slaveFDDType = Slave_FDD_Detect();
|
||||
Floppy_Drive_Init(1);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
end:
|
||||
for (;;);
|
||||
}
|
||||
|
||||
@ -51,10 +51,10 @@ void setcursor(int x, int y)
|
||||
{
|
||||
int pos = y * SCREEN_WIDTH + x;
|
||||
|
||||
i686_outb(0x3D4, 0x0F);
|
||||
i686_outb(0x3D5, (uint8_t)(pos & 0xFF));
|
||||
i686_outb(0x3D4, 0x0E);
|
||||
i686_outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, (uint8_t)(pos & 0xFF));
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
void clrscr()
|
||||
|
||||
@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
||||
#define VERSION "RD-00025"
|
||||
#define VERSION "RD-00027"
|
||||
#define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user