mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2024-11-23 14:26:52 -08:00
fixing more stuff and adding more stuff
This commit is contained in:
parent
528fb00d49
commit
79edf9eb6e
BIN
.vscode/browse.vc.db
vendored
BIN
.vscode/browse.vc.db
vendored
Binary file not shown.
BIN
.vscode/browse.vc.db-shm
vendored
BIN
.vscode/browse.vc.db-shm
vendored
Binary file not shown.
Binary file not shown.
@ -4,14 +4,9 @@ kernel_sector equ 1 ; Sector containing the kernel (adjust for your kernel's l
|
|||||||
kernel_segments equ 4 ; Number of sectors to load (adjust for your kernel size)
|
kernel_segments equ 4 ; Number of sectors to load (adjust for your kernel size)
|
||||||
kernel_load_address equ 0x1000 ; Memory address to load the kernel
|
kernel_load_address equ 0x1000 ; Memory address to load the kernel
|
||||||
|
|
||||||
; ... (Function prototypes and int_13h implementation copied from previous response)
|
|
||||||
; Function prototypes for readability
|
|
||||||
; (These functions are not strictly necessary in NASM, but improve code organization)
|
|
||||||
; Prototype for BIOS disk read interrupt (INT 13h)
|
|
||||||
void int_13h(unsigned int ah, unsigned int al, unsigned int dx, unsigned int ch, unsigned int cl, unsigned int bx);
|
void int_13h(unsigned int ah, unsigned int al, unsigned int dx, unsigned int ch, unsigned int cl, unsigned int bx);
|
||||||
|
|
||||||
; Function prototype for error handling or printing a message
|
void error_handler(const char *message)
|
||||||
void error_handler(const char *message);
|
|
||||||
; Main kernel loading code
|
; Main kernel loading code
|
||||||
mov bx, kernel_load_address ; Set load address
|
mov bx, kernel_load_address ; Set load address
|
||||||
|
|
||||||
|
18
src/cpu/cpuid.asm
Normal file
18
src/cpu/cpuid.asm
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[bits 32]
|
||||||
|
|
||||||
|
global cpuid
|
||||||
|
|
||||||
|
cpuid:
|
||||||
|
; Input parameter in EAX register
|
||||||
|
mov eax, %edi
|
||||||
|
|
||||||
|
; Call CPUID instruction (clobbers EAX, EBX, ECX, EDX)
|
||||||
|
cpuid
|
||||||
|
|
||||||
|
; Return values in output registers
|
||||||
|
mov %esi, [esp + 4] ; eax (output)
|
||||||
|
mov %edx, [esp + 8] ; ebx (output)
|
||||||
|
mov %ecx, [esp + 12] ; ecx (output)
|
||||||
|
mov %edi, [esp + 16] ; edx (output)
|
||||||
|
|
||||||
|
ret
|
36
src/cpu/cpuid.c
Normal file
36
src/cpu/cpuid.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "cpuid.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void cpuid(uint32_t code, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
|
||||||
|
asm volatile ("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (code));
|
||||||
|
}
|
||||||
|
|
||||||
|
void identify_cpu() {
|
||||||
|
uint32_t max_leaf;
|
||||||
|
uint32_t vendor_id[4];
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
|
||||||
|
// Get the maximum supported leaf value (CPUID function)
|
||||||
|
cpuid(0, &eax, &ebx, &ecx, &edx);
|
||||||
|
max_leaf = eax;
|
||||||
|
|
||||||
|
// Get the vendor ID string
|
||||||
|
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||||
|
vendor_id[0] = eax;
|
||||||
|
vendor_id[1] = ebx;
|
||||||
|
vendor_id[2] = ecx;
|
||||||
|
vendor_id[3] = edx;
|
||||||
|
|
||||||
|
// Print the vendor ID string (assuming ASCII characters)
|
||||||
|
printf("Vendor ID: %.4s%.4s\n", (char *)&vendor_id[0], (char *)&vendor_id[1]);
|
||||||
|
|
||||||
|
// Identify basic features based on CPUID information (optional, needs further logic)
|
||||||
|
// ... (code to check specific CPU features using max_leaf and additional CPUID calls) ...
|
||||||
|
|
||||||
|
printf("Maximum leaf value: %u\n", max_leaf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
identify_cpu();
|
||||||
|
return 0;
|
||||||
|
}
|
7
src/cpu/cpuid.h
Normal file
7
src/cpu/cpuid.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef CPUID_H
|
||||||
|
#define CPUID_H
|
||||||
|
|
||||||
|
// Function prototypes for CPUID instruction
|
||||||
|
void cpuid(uint32_t code, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
|
||||||
|
|
||||||
|
#endif
|
BIN
src/drivers/io/io.bin
Normal file
BIN
src/drivers/io/io.bin
Normal file
Binary file not shown.
@ -15,8 +15,15 @@
|
|||||||
LPT3: 0x3BC
|
LPT3: 0x3BC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
IO_SUCCESS = 0,
|
||||||
|
IO_ERROR_PORT_NOT_READY,
|
||||||
|
IO_ERROR_PORT_UNAVAILABLE,
|
||||||
|
// Add more error codes as needed
|
||||||
|
} IOErrorCode;
|
||||||
|
|
||||||
// Function to initialize the ports before reading or writing
|
// Function to initialize the ports before reading or writing
|
||||||
void io_init()
|
void io_init(uint16_t port)
|
||||||
{
|
{
|
||||||
// Initialize COM1 port (0x3F8) - You can add more port initializations here if needed
|
// Initialize COM1 port (0x3F8) - You can add more port initializations here if needed
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Function to initialize the COM and LPT ports
|
// Function to initialize the COM and LPT ports
|
||||||
void io_init();
|
void io_init(uint16_t port);
|
||||||
|
|
||||||
// Function to read from the COM port
|
// Function to read from the COM port
|
||||||
char io_read_com();
|
char io_read_com();
|
||||||
|
@ -22,14 +22,20 @@ static size_t keyboard_buffer_tail = 0;
|
|||||||
void set_interrupt_vector(uint8_t vector, void (*handler)());
|
void set_interrupt_vector(uint8_t vector, void (*handler)());
|
||||||
void enable_interrupt(uint8_t vector);
|
void enable_interrupt(uint8_t vector);
|
||||||
|
|
||||||
|
bool keyboard_buffer_full()
|
||||||
|
{
|
||||||
|
return (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE == keyboard_buffer_tail;
|
||||||
|
}
|
||||||
void KeyboardInterruptHandler()
|
void KeyboardInterruptHandler()
|
||||||
{
|
{
|
||||||
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
|
if (!keyboard_buffer_full())
|
||||||
|
{uint8_t scancode = inb(KEYBOARD_DATA_PORT);
|
||||||
uint8_t keycode = translate_scancode_to_keycode(scancode);
|
uint8_t keycode = translate_scancode_to_keycode(scancode);
|
||||||
|
|
||||||
// Add scancode to buffer
|
// Add scancode to buffer
|
||||||
keyboard_buffer[keyboard_buffer_head] = scancode;
|
keyboard_buffer[keyboard_buffer_head] = scancode;
|
||||||
keyboard_buffer_head = (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE;
|
keyboard_buffer_head = (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to translate the combined extended scancode (first byte + second byte)
|
// Function to translate the combined extended scancode (first byte + second byte)
|
||||||
@ -134,7 +140,30 @@ uint8_t translate_scancode_to_keycode(uint8_t scancode)
|
|||||||
[0x51] = KEYCODE_PAGE_DOWN,
|
[0x51] = KEYCODE_PAGE_DOWN,
|
||||||
[0x52] = KEYCODE_INSERT,
|
[0x52] = KEYCODE_INSERT,
|
||||||
[0x53] = KEYCODE_DELETE,
|
[0x53] = KEYCODE_DELETE,
|
||||||
|
[0x54] = KEYCODE_HOME,
|
||||||
|
[0x55] = KEYCODE_UP,
|
||||||
|
[0x56] = KEYCODE_PAGE_UP,
|
||||||
|
[0x57] = KEYCODE_LEFT_CTRL_BREAK, // Handle Break key (adjust if needed)
|
||||||
|
[0x58] = KEYCODE_RIGHT_SHIFT,
|
||||||
|
[0x59] = KEYCODE_NUM_LOCK,
|
||||||
|
[0x5A] = KEYCODE_SCROLL_LOCK,
|
||||||
|
[0x5B] = KEYCODE_F7,
|
||||||
|
[0x5C] = KEYCODE_F8,
|
||||||
|
[0x5D] = KEYCODE_F9,
|
||||||
|
[0x5E] = KEYCODE_F10,
|
||||||
|
[0x5F] = KEYCODE_PAUSE, // Handle Pause key (adjust if needed)
|
||||||
|
[0x60] = KEYCODE_INSERT,
|
||||||
|
[0x61] = KEYCODE_DELETE,
|
||||||
|
[0x62] = KEYCODE_RIGHT,
|
||||||
|
[0x63] = KEYCODE_END,
|
||||||
|
[0x64] = KEYCODE_DOWN,
|
||||||
|
[0x65] = KEYCODE_PAGE_DOWN,
|
||||||
|
[0x66] = KEYCODE_F11,
|
||||||
|
[0x67] = KEYCODE_F12,
|
||||||
|
[0x68] = KEYCODE_UNKNOWN, // (unused)
|
||||||
|
[0x69] = KEYCODE_LED_NUM_LOCK, // Num Lock LED status
|
||||||
|
[0x6A] = KEYCODE_LED_CAPS_LOCK, // Caps Lock LED status
|
||||||
|
[0x6B] = KEYCODE_LED_SCROLL_LOCK
|
||||||
// ... (complete the rest based on the scancode table)
|
// ... (complete the rest based on the scancode table)
|
||||||
[0xE0] = 0, // Handle extended scancodes (e.g., Print Screen) separately
|
[0xE0] = 0, // Handle extended scancodes (e.g., Print Screen) separately
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ void KeyboardInterruptHandler();
|
|||||||
|
|
||||||
void keyboard_init();
|
void keyboard_init();
|
||||||
bool keyboard_buffer_empty();
|
bool keyboard_buffer_empty();
|
||||||
|
bool keyboard_buffer_full();
|
||||||
uint8_t keyboard_read_scancode();
|
uint8_t keyboard_read_scancode();
|
||||||
void set_interrupt_vector(uint8_t vector, void (*handler)());
|
void set_interrupt_vector(uint8_t vector, void (*handler)());
|
||||||
void enable_interrupt(uint8_t vector);
|
void enable_interrupt(uint8_t vector);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "ne2000.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// NE2000 registers
|
// NE2000 registers
|
||||||
@ -12,15 +13,15 @@
|
|||||||
// ... more commands ...
|
// ... more commands ...
|
||||||
|
|
||||||
// Write a value to a NE2000 register
|
// Write a value to a NE2000 register
|
||||||
void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value) {
|
void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value)
|
||||||
volatile uint8_t *ne2000_reg = (volatile uint8_t *)(base_addr + reg);
|
{
|
||||||
*ne2000_reg = value;
|
outb(base_addr + reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a value from a NE2000 register
|
// Read a value from a NE2000 register
|
||||||
uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg) {
|
uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg)
|
||||||
volatile uint8_t *ne2000_reg = (volatile uint8_t *)(base_addr + reg);
|
{
|
||||||
return *ne2000_reg;
|
return inb(base_addr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the NE2000 card
|
// Initialize the NE2000 card
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint8_t inb(uint16_t port);
|
||||||
|
void outb(uint16_t port, uint8_t value);
|
||||||
|
|
||||||
// NE2000 registers
|
// NE2000 registers
|
||||||
#define NE2000_COMMAND 0x00
|
#define NE2000_COMMAND 0x00
|
||||||
#define NE2000_PSTART 0x01
|
#define NE2000_PSTART 0x01
|
||||||
|
@ -1,3 +1,32 @@
|
|||||||
/*
|
#include "fat16.h"
|
||||||
fat16 goes here
|
#include <stdint.h>
|
||||||
*/
|
#include "fat16_io.h"
|
||||||
|
|
||||||
|
// Implementation of read_sector and write_sector functions (replace with actual disk I/O)
|
||||||
|
int read_sector(uint32_t sector_number, void *buffer)
|
||||||
|
{
|
||||||
|
// ... (Code to read a sector from disk) ...
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_sector(uint32_t sector_number, void *buffer)
|
||||||
|
{
|
||||||
|
return read_sector_from_disk(sector_number, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to parse the boot sector (replace with actual parsing logic)
|
||||||
|
int parse_boot_sector(const char *device_name)
|
||||||
|
{
|
||||||
|
// ... (Read and parse boot sector information) ...
|
||||||
|
return 0; // Or error code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to mount the FAT16 volume (replace with actual mounting logic)
|
||||||
|
int mount_fat16(const char *device_name)
|
||||||
|
{
|
||||||
|
if (parse_boot_sector(device_name) != 0)
|
||||||
|
{
|
||||||
|
return -1; // Error parsing boot sector
|
||||||
|
}
|
||||||
|
// ... (Additional mounting logic) ...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,3 +1,26 @@
|
|||||||
/*
|
#ifndef FAT16_H
|
||||||
fat16 goes here
|
#define FAT16_H
|
||||||
*/
|
|
||||||
|
#include <stdint.h>
|
||||||
|
// Define constants for sector size, cluster size, etc. (replace with actual values)
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
#define BYTES_PER_CLUSTER 4096 // Example: 8 sectors per cluster
|
||||||
|
|
||||||
|
// Define structures for FAT entry, directory entry, etc.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// ... (FAT entry fields) ...
|
||||||
|
} fat_entry_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// ... (Directory entry fields) ...
|
||||||
|
} directory_entry_t;
|
||||||
|
|
||||||
|
// Function prototypes for FAT operations
|
||||||
|
int read_sector(uint32_t sector_number, void *buffer);
|
||||||
|
int write_sector(uint32_t sector_number, void *buffer);
|
||||||
|
int mount_fat16(const char *device_name); // Mount the FAT16 volume
|
||||||
|
// ... (other function prototypes) ...
|
||||||
|
|
||||||
|
#endif
|
||||||
|
50
src/filesystem/fat16/fat16_io.c
Normal file
50
src/filesystem/fat16/fat16_io.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "fat16_io.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
// I/O port addresses for IDE controller (replace with actual values if needed)
|
||||||
|
#define PRIMARY_DATA_REGISTER 0x1F0
|
||||||
|
#define PRIMARY_ERROR_REGISTER 0x1F1
|
||||||
|
#define PRIMARY_COMMAND_REGISTER 0x1F2
|
||||||
|
#define PRIMARY_SELECT_REGISTER 0x1F6
|
||||||
|
|
||||||
|
// Define bit masks for IDE commands
|
||||||
|
#define ATA_CMD_READ_SECTORS_WITHOUT_RETRIES 0x20
|
||||||
|
#define ATA_CMD_READ_SECTORS_WITH_RETRIES 0xC4
|
||||||
|
|
||||||
|
// Function to read a sector from disk
|
||||||
|
int read_sector(uint32_t sector_number, void *buffer)
|
||||||
|
{
|
||||||
|
// 1. Prepare for disk access
|
||||||
|
outb(PRIMARY_SELECT_REGISTER, 0x00); // Select primary IDE channel
|
||||||
|
|
||||||
|
// 2. Wait for controller to become ready
|
||||||
|
while ((inb(PRIMARY_STATUS_REGISTER) & 0x02) == 0)
|
||||||
|
{
|
||||||
|
} // Wait for BUSY bit to clear
|
||||||
|
|
||||||
|
// 3. Send read command with parameters
|
||||||
|
outb(PRIMARY_COMMAND_REGISTER, ATA_CMD_READ_SECTORS_WITHOUT_RETRIES); // Replace with retries if needed
|
||||||
|
outb(PRIMARY_ERROR_REGISTER, 0); // Features (usually set to 0)
|
||||||
|
outb(PRIMARY_SELECT_REGISTER, (sector_number & 0x0FF) | 0x80); // LBA low byte with LBA bit set
|
||||||
|
outb(PRIMARY_COMMAND_REGISTER, ((sector_number >> 8) & 0xFF)); // LBA mid byte
|
||||||
|
outb(PRIMARY_COMMAND_REGISTER, ((sector_number >> 16) & 0x0F) | 0xE0); // LBA high byte with select bit
|
||||||
|
outb(PRIMARY_COMMAND_REGISTER, 1); // Number of sectors to read (1 in this case)
|
||||||
|
|
||||||
|
// 4. Wait for data transfer to complete (replace with timeout if needed)
|
||||||
|
while ((inb(PRIMARY_STATUS_REGISTER) & 0x08) == 0)
|
||||||
|
{
|
||||||
|
} // Wait for DRQ bit to set
|
||||||
|
|
||||||
|
// 5. Read data from the data register
|
||||||
|
for (int i = 0; i < 512; ++i)
|
||||||
|
{
|
||||||
|
((uint8_t *)buffer)[i] = inb(PRIMARY_DATA_REGISTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Check for errors (optional, implement error handling)
|
||||||
|
if (inb(PRIMARY_STATUS_REGISTER) & 0x01)
|
||||||
|
{
|
||||||
|
return -1; // Error occurred
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Success
|
||||||
|
}
|
19
src/filesystem/fat16/fat16_io.h
Normal file
19
src/filesystem/fat16/fat16_io.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef FAT16_IO_H
|
||||||
|
#define FAT16_IO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// I/O port addresses for IDE controller (replace with actual values if needed)
|
||||||
|
#define PRIMARY_DATA_REGISTER 0x1F0
|
||||||
|
#define PRIMARY_ERROR_REGISTER 0x1F1
|
||||||
|
#define PRIMARY_COMMAND_REGISTER 0x1F2
|
||||||
|
#define PRIMARY_SELECT_REGISTER 0x1F6
|
||||||
|
|
||||||
|
// Define bit masks for IDE commands
|
||||||
|
#define ATA_CMD_READ_SECTORS_WITHOUT_RETRIES 0x20
|
||||||
|
#define ATA_CMD_READ_SECTORS_WITH_RETRIES 0xC4
|
||||||
|
|
||||||
|
// Function prototype for reading a sector from disk
|
||||||
|
int read_sector(uint32_t sector_number, void *buffer);
|
||||||
|
|
||||||
|
#endif // FAT16_IO_H
|
BIN
src/kernel/arch/x86/gdt.bin
Normal file
BIN
src/kernel/arch/x86/gdt.bin
Normal file
Binary file not shown.
@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
#include "include/types.h"
|
#include "include/types.h"
|
||||||
|
|
||||||
|
#define IDT_ENTRY_SIZE 16
|
||||||
|
|
||||||
|
#if IDT_ENTRY_SIZE != 16
|
||||||
|
#error "idt_entry structure size mismatch!"
|
||||||
|
#endif
|
||||||
|
|
||||||
// IDT entry structure
|
// IDT entry structure
|
||||||
struct idt_entry
|
struct idt_entry
|
||||||
{
|
{
|
||||||
@ -18,4 +24,9 @@ extern struct idt_entry idt[256];
|
|||||||
// Initialize the IDT
|
// Initialize the IDT
|
||||||
void InitializeIDT();
|
void InitializeIDT();
|
||||||
|
|
||||||
|
extern void KeyboardInterruptHandler();
|
||||||
|
extern void TimerInterruptHandler();
|
||||||
|
|
||||||
|
extern void LoadIDT(struct idt_entry *entry);
|
||||||
|
|
||||||
#endif /* IDT_H */
|
#endif /* IDT_H */
|
@ -4,37 +4,117 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
typedef struct memory_region_t
|
||||||
|
{
|
||||||
|
void *start_address;
|
||||||
|
size_t size;
|
||||||
|
} memory_region_t;
|
||||||
|
|
||||||
|
// Array of allocated memory regions (example)
|
||||||
|
memory_region_t *allocated_regions;
|
||||||
|
size_t num_allocated_regions;
|
||||||
|
|
||||||
|
jmp_buf page_fault_buffer;
|
||||||
|
|
||||||
void DivideByZero()
|
void DivideByZero()
|
||||||
{
|
{
|
||||||
// Add logic to handle Divide By Zero Exception
|
// Add logic to handle Divide By Zero Exception
|
||||||
printf("Divide By Zero Exception\n");
|
printf("Divide By Zero Exception\n");
|
||||||
|
|
||||||
// Additional Exception Handling Logic:
|
// Additional Exception Handling Logic:
|
||||||
// Example: Perform specific actions for Divide By Zero scenario
|
// Example: Perform specific actions for Divide By Zero scenario
|
||||||
// - Log the exception to a file
|
// - Log the exception to a file
|
||||||
FILE *logFile = fopen("error.log", "a");
|
FILE *logFile = fopen("error.log", "a");
|
||||||
if (logFile != NULL) {
|
if (logFile != NULL)
|
||||||
fprintf(logFile, "Divide By Zero Exception occurred\n");
|
{
|
||||||
fclose(logFile);
|
fprintf(logFile, "Divide By Zero Exception occurred\n");
|
||||||
}
|
fclose(logFile);
|
||||||
|
}
|
||||||
|
|
||||||
// - Gracefully terminate the kernel
|
// - Gracefully terminate the kernel
|
||||||
printf("Exiting kernel due to Divide By Zero Exception\n");
|
printf("Exiting kernel due to Divide By Zero Exception\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoubleFault()
|
void DoubleFault()
|
||||||
{
|
{
|
||||||
// printf("Double Fault Exception");
|
printf("Double Fault Exception\n");
|
||||||
|
// Handle double fault exception (typically unrecoverable)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageFault()
|
// Function to check if address is within allocated memory (example)
|
||||||
|
int IsAddressInRange(uint16_t address)
|
||||||
{
|
{
|
||||||
// printf("Page Fault Exception");
|
for (size_t i = 0; i < num_allocated_regions; ++i)
|
||||||
|
{
|
||||||
|
if ((address >= allocated_regions[i].start_address) &&
|
||||||
|
(address < (allocated_regions[i].start_address + allocated_regions[i].size)))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for loading page from disk (replace with actual implementation)
|
||||||
|
void LoadPageFromDisk(uint16_t fault_address, void *page_buffer)
|
||||||
|
{
|
||||||
|
// Implement logic to read page data from disk based on fault_address
|
||||||
|
// and store it in the provided page_buffer
|
||||||
|
printf("** Placeholder: Load page from disk (implementation needed) **\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder for modifying paging tables (replace with actual implementation)
|
||||||
|
void NotifyCPUAboutPage(uint16_t fault_address)
|
||||||
|
{
|
||||||
|
// Implement logic to modify paging tables based on fault_address
|
||||||
|
// to point to the loaded page data
|
||||||
|
printf("** Placeholder: Modify paging tables (implementation needed) **\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageFault(uint16_t fault_address)
|
||||||
|
{
|
||||||
|
// 1. Identify the cause of the page fault
|
||||||
|
if (IsAddressInRange(fault_address))
|
||||||
|
{
|
||||||
|
// Address is within allocated memory, potentially a missing page
|
||||||
|
printf("Page fault for address 0x%x (potentially missing page)\n", fault_address);
|
||||||
|
|
||||||
|
// 2. Allocate memory for the page data (assuming OS doesn't handle this)
|
||||||
|
void *page_buffer = malloc(PAGE_SIZE); // Replace with actual page size
|
||||||
|
if (page_buffer == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to allocate memory for page data\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Load the missing page from disk
|
||||||
|
LoadPageFromDisk(fault_address, page_buffer);
|
||||||
|
|
||||||
|
// 4. Inform the CPU that the page is now available
|
||||||
|
NotifyCPUAboutPage(fault_address);
|
||||||
|
|
||||||
|
// 5. Free the temporary page buffer (if applicable)
|
||||||
|
free(page_buffer);
|
||||||
|
|
||||||
|
// 6. Resume execution with longjmp
|
||||||
|
longjmp(page_fault_buffer, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle invalid memory access
|
||||||
|
printf("Invalid memory access at 0x%x\n", fault_address);
|
||||||
|
exit(EXIT_FAILURE); // Or perform alternative error handling
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeneralProtectionFault()
|
void GeneralProtectionFault()
|
||||||
{
|
{
|
||||||
// printf("General Protection Fault Exception");
|
printf("General Protection Fault Exception\n");
|
||||||
|
// Handle general protection fault exception (access violation)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ void *malloc(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Align the size to the word size for efficiency
|
// Align the size to the word size for efficiency
|
||||||
size += sizeof(size_t) - 1;
|
|
||||||
size &= ~(sizeof(size_t) - 1);
|
size &= ~(sizeof(size_t) - 1);
|
||||||
|
|
||||||
// Search for a free block of sufficient size
|
// Search for a free block of sufficient size
|
||||||
|
Loading…
Reference in New Issue
Block a user