More kernel building

This commit is contained in:
Gregory Kenneth Bowne 2023-07-14 01:32:48 -07:00
parent de4b0dc629
commit d9d2e84f25
20 changed files with 378 additions and 9 deletions

0
.clang_complete Normal file
View File

0
.gdbinit Normal file
View File

0
.vs/ClassicOS.sln Normal file
View File

View File

View File

View File

20
.vscode/settings.json vendored
View File

@ -93,15 +93,19 @@
"cmake.sourceDirectory": "${workspaceFolder}", "cmake.sourceDirectory": "${workspaceFolder}",
"C_Cpp.default.compilerPath": "/usr/bin", "C_Cpp.default.compilerPath": "/usr/bin",
"C_Cpp.loggingLevel": "Error", "C_Cpp.loggingLevel": "Error",
"C_Cpp.default.enableConfigurationSquiggles": "", "C_Cpp.default.enableConfigurationSquiggles": true,
"C_Cpp.default.includePath": "/usr/bin", "C_Cpp.default.includePath": [
"${workspaceFolder}/**", // Include all files in the workspace folder
"/usr/include", // Standard system include path
"/usr/local/include", // Additional system include path
"/path/to/custom/includes" // Custom include path
],
"workbench.editorAssociations": { "workbench.editorAssociations": {
"*.bin": "bin", "*.bin": "default",
"*.c": "c", "*.h": "default",
"*.h": "c", "*.c": "default",
"*.cpp": "cpp", "*.json": "default",
"*.hpp": "hpp", "*.asm": "default"
"*.asm": "asm"
}, },
"C_Cpp.default.intelliSenseMode": "linux-clang-x86", "C_Cpp.default.intelliSenseMode": "linux-clang-x86",
"cmake.cmakePath": "/usr/bin/cmake" "cmake.cmakePath": "/usr/bin/cmake"

View File

@ -6,6 +6,7 @@ An x86 Operating System for 386, 486, Pentium class (P-75, 100, Pentium II, P3,
These are the versions I use, but please use the latest possible versions. These are the versions I use, but please use the latest possible versions.
NASM version 2.14 NASM version 2.14
QEMU x86_64 QEMU x86_64
GNU ld (GNU Binutils for Debian) 2.31.1 or newer GNU ld (GNU Binutils for Debian) 2.31.1 or newer

0
debug.gdb Normal file
View File

0
make.config Normal file
View File

89
src/kernel/arch/x86/gdt.c Normal file
View File

@ -0,0 +1,89 @@
#include "gdt.h"
// GDT table
struct gdt_entry gdt[3];
// GDT pointer
struct gdt_ptr gp;
// Initialize a GDT entry
void gdt_set_gate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access,
uint8_t gran)
{
gdt[num].base_low = (base & 0xFFFF);
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = (limit >> 16) & 0x0F;
gdt[num].granularity |= gran & 0xF0;
gdt[num].access = access;
}
// Initialize the GDT
void gdt_init()
{
// Set up GDT pointer
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gp.base = (uint32_t)&gdt;
// Clear GDT
memset(&gdt, 0, sizeof(gdt));
// Set up code segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
// Set up data segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
// Load GDT
asm volatile("lgdt %0" : : "m"(gp));
}
// Exception handlers
extern void divide_error();
extern void page_fault();
extern void general_protection_fault();
extern void double_fault();
// Interrupt handlers
extern void system_call();
extern void timer();
extern void keyboard();
extern void device();
// ISR table
void (*isr_table[256])(void);
// Register an ISR
void isr_register(uint8_t num, void (*handler)(void))
{
isr_table[num] = handler;
}
// ISR handler
void isr_handler(struct isr_regs *regs)
{
void (*handler)(void);
handler = isr_table[regs->int_no];
if (handler)
{
handler();
}
}
// Initialize the ISR
void isr_init()
{
// Register exception handlers
isr_register(0, divide_error);
isr_register(14, page_fault);
isr_register(13, general_protection_fault);
isr_register(8, double_fault);
// Register interrupt handlers
isr_register(0x80, system_call);
isr_register(0x20, timer);
isr_register(0x21, keyboard);
isr_register(0x30, device);
}

27
src/kernel/arch/x86/gdt.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef GDT_H
#define GDT_H
#include <stdint.h>
// GDT entry structure
struct gdt_entry
{
uint16_t limit_low; // Lower 16 bits of segment limit
uint16_t base_low; // Lower 16 bits of segment base address
uint8_t base_middle; // Middle 8 bits of segment base address
uint8_t access; // Access flags
uint8_t granularity; // Granularity and segment limit flags
uint8_t base_high; // Upper 8 bits of segment base address
} __attribute__((packed));
// GDT pointer structure
struct gdt_ptr
{
uint16_t limit; // Size of GDT in bytes - 1
uint32_t base; // Address of GDT
} __attribute__((packed));
// Initialize the GDT
void gdt_init();
#endif

55
src/kernel/arch/x86/idt.c Normal file
View File

@ -0,0 +1,55 @@
#include "idt.h"
// IDT table
struct idt_entry idt[256];
// IDT pointer
struct idt_ptr idtp;
// Exception handlers
extern void divide_error_handler();
extern void page_fault_handler();
extern void general_protection_fault_handler();
extern void double_fault_handler();
// Interrupt handlers
extern void system_call_handler();
extern void timer_handler();
extern void keyboard_handler();
extern void device_handler();
// Initialize an IDT entry
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
idt[num].always0 = 0;
idt[num].flags = flags;
}
// Initialize the IDT
void idt_init()
{
// Set up IDT pointer
idtp.limit = sizeof(idt) - 1;
idtp.base = (uint32_t)&idt;
// Clear IDT
memset(&idt, 0, sizeof(idt));
// Set up exception handlers
idt_set_gate(0, (uint32_t)divide_error_handler, 0x08, 0x8E);
idt_set_gate(14, (uint32_t)page_fault_handler, 0x08, 0x8E);
idt_set_gate(13, (uint32_t)general_protection_fault_handler, 0x08, 0x8E);
idt_set_gate(8, (uint32_t)double_fault_handler, 0x08, 0x8E);
// Set up interrupt handlers
idt_set_gate(0x80, (uint32_t)system_call_handler, 0x08, 0xEE);
idt_set_gate(0x20, (uint32_t)timer_handler, 0x08, 0x8E);
idt_set_gate(0x21, (uint32_t)keyboard_handler, 0x08, 0x8E);
idt_set_gate(0x30, (uint32_t)device_handler, 0x08, 0x8E);
// Load IDT
asm volatile("lidt %0" : : "m"(idtp));
}

36
src/kernel/arch/x86/idt.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
// IDT entry structure
struct idt_entry {
uint16_t base_lo; // Lower 16 bits of handler function address
uint16_t sel; // Kernel segment selector
uint8_t always0; // Always 0
uint8_t flags; // Flags
uint16_t base_hi; // Upper 16 bits of handler function address
} __attribute__((packed));
// IDT pointer structure
struct idt_ptr {
uint16_t limit; // Size of IDT in bytes - 1
uint32_t base; // Address of IDT
} __attribute__((packed));
// Exception handlers
void divide_error();
void page_fault();
void general_protection_fault();
void double_fault();
// Interrupt handlers
void system_call();
void timer();
void keyboard();
void device();
// Initialize the IDT
void idt_init();
#endif

View File

@ -0,0 +1,9 @@
#ifndef MEMORY_H
#define MEMORY_H
#include <stdint.h>
void *kmalloc(size_t size);
void kfree(void *ptr);
#endif /* MEMORY_H */

View File

@ -0,0 +1,19 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef struct {
uint32_t base;
uint32_t limit;
uint16_t flags;
} gdt_entry_t;
typedef struct {
uint16_t limit;
uint32_t base;
} idt_entry_t;
#endif /* TYPES_H */

64
src/kernel/arch/x86/isr.c Normal file
View File

@ -0,0 +1,64 @@
#include "isr.h"
// ISR table
void (*isr_table[256])(struct isr_regs *regs);
// Register an ISR
void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs))
{
isr_table[num] = handler;
}
// ISR handler
void isr_handler(struct isr_regs *regs)
{
void (*handler)(struct isr_regs *regs);
handler = isr_table[regs->int_no];
if (handler)
{
handler(regs);
}
}
// Exception handlers
void divide_error()
{
// Handle divide error exception
}
void page_fault()
{
// Handle page fault exception
}
void general_protection_fault()
{
// Handle general protection fault exception
}
void double_fault()
{
// Handle double fault exception
}
// Interrupt handlers
void system_call()
{
// Handle system call interrupt
}
void timer()
{
// Handle timer interrupt
}
void keyboard()
{
// Handle keyboard interrupt
}
void device()
{
// Handle device interrupt
}

36
src/kernel/arch/x86/isr.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef ISR_H
#define ISR_H
#include <stdint.h>
// Structure for storing register values during an ISR
struct isr_regs
{
uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx,
eax; // Pushed by pusha instruction
uint32_t int_no,
err_code; // Interrupt number and error code (if applicable)
uint32_t eip, cs, eflags, useresp,
ss; // Pushed by the processor automatically
};
// Register an ISR
void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs));
// ISR handler
void isr_handler(struct isr_regs *regs);
// Exception handlers
void divide_error();
void page_fault();
void general_protection_fault();
void double_fault();
// Interrupt handlers
void system_call();
void timer();
void keyboard();
void device();
#endif

View File

@ -0,0 +1,12 @@
#include "../include/memory.h"
void *kmalloc(size_t size)
{
/* TODO: Implement memory allocation */
return NULL;
}
void kfree(void *ptr)
{
/* TODO: Implement memory deallocation */
}

17
src/kernel/src/types.c Normal file
View File

@ -0,0 +1,17 @@
#include "../include/types.h"
void gdt_set_entry(gdt_entry_t *entry, uint32_t base, uint32_t limit,
uint16_t flags)
{
entry->base = base;
entry->limit = limit;
entry->flags = flags;
}
void idt_set_entry(idt_entry_t *entry, uint32_t base, uint16_t selector,
uint16_t flags)
{
entry->base = base;
entry->selector = selector;
entry->flags = flags;
}