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_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);
|
||||
|
||||
; 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
|
||||
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
|
||||
*/
|
||||
|
||||
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
|
||||
void io_init()
|
||||
void io_init(uint16_t port)
|
||||
{
|
||||
// Initialize COM1 port (0x3F8) - You can add more port initializations here if needed
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// Function to initialize the COM and LPT ports
|
||||
void io_init();
|
||||
void io_init(uint16_t port);
|
||||
|
||||
// Function to read from the COM port
|
||||
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 enable_interrupt(uint8_t vector);
|
||||
|
||||
bool keyboard_buffer_full()
|
||||
{
|
||||
return (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE == keyboard_buffer_tail;
|
||||
}
|
||||
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);
|
||||
|
||||
// Add scancode to buffer
|
||||
keyboard_buffer[keyboard_buffer_head] = scancode;
|
||||
keyboard_buffer_head = (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
[0x52] = KEYCODE_INSERT,
|
||||
[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)
|
||||
[0xE0] = 0, // Handle extended scancodes (e.g., Print Screen) separately
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ void KeyboardInterruptHandler();
|
||||
|
||||
void keyboard_init();
|
||||
bool keyboard_buffer_empty();
|
||||
bool keyboard_buffer_full();
|
||||
uint8_t keyboard_read_scancode();
|
||||
void set_interrupt_vector(uint8_t vector, void (*handler)());
|
||||
void enable_interrupt(uint8_t vector);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "ne2000.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// NE2000 registers
|
||||
@ -12,15 +13,15 @@
|
||||
// ... more commands ...
|
||||
|
||||
// Write a value to a NE2000 register
|
||||
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;
|
||||
void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value)
|
||||
{
|
||||
outb(base_addr + reg, value);
|
||||
}
|
||||
|
||||
// Read a value from a NE2000 register
|
||||
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;
|
||||
uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg)
|
||||
{
|
||||
return inb(base_addr + reg);
|
||||
}
|
||||
|
||||
// Initialize the NE2000 card
|
||||
|
@ -1,23 +1,26 @@
|
||||
#ifndef NE2000_H
|
||||
#define NE2000_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// NE2000 registers
|
||||
#define NE2000_COMMAND 0x00
|
||||
#define NE2000_PSTART 0x01
|
||||
#define NE2000_PSTOP 0x02
|
||||
// ... more registers ...
|
||||
|
||||
// NE2000 commands
|
||||
#define NE2000_CMD_START 0x02
|
||||
#define NE2000_CMD_STOP 0x01
|
||||
// ... more commands ...
|
||||
|
||||
// Function prototypes
|
||||
void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value);
|
||||
uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg);
|
||||
void ne2000_init(uint16_t base_addr);
|
||||
// ... more function prototypes ...
|
||||
|
||||
#endif // NE2000_H
|
||||
#ifndef NE2000_H
|
||||
#define NE2000_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t inb(uint16_t port);
|
||||
void outb(uint16_t port, uint8_t value);
|
||||
|
||||
// NE2000 registers
|
||||
#define NE2000_COMMAND 0x00
|
||||
#define NE2000_PSTART 0x01
|
||||
#define NE2000_PSTOP 0x02
|
||||
// ... more registers ...
|
||||
|
||||
// NE2000 commands
|
||||
#define NE2000_CMD_START 0x02
|
||||
#define NE2000_CMD_STOP 0x01
|
||||
// ... more commands ...
|
||||
|
||||
// Function prototypes
|
||||
void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value);
|
||||
uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg);
|
||||
void ne2000_init(uint16_t base_addr);
|
||||
// ... more function prototypes ...
|
||||
|
||||
#endif // NE2000_H
|
||||
|
@ -1,3 +1,32 @@
|
||||
/*
|
||||
fat16 goes here
|
||||
*/
|
||||
#include "fat16.h"
|
||||
#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 @@
|
||||
/*
|
||||
fat16 goes here
|
||||
*/
|
||||
#ifndef FAT16_H
|
||||
#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.
@ -1,21 +1,32 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include "include/types.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));
|
||||
|
||||
extern struct idt_entry idt[256];
|
||||
|
||||
// Initialize the IDT
|
||||
void InitializeIDT();
|
||||
|
||||
#endif /* IDT_H */
|
||||
#ifndef IDT_H
|
||||
#define IDT_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
|
||||
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));
|
||||
|
||||
extern struct idt_entry idt[256];
|
||||
|
||||
// Initialize the IDT
|
||||
void InitializeIDT();
|
||||
|
||||
extern void KeyboardInterruptHandler();
|
||||
extern void TimerInterruptHandler();
|
||||
|
||||
extern void LoadIDT(struct idt_entry *entry);
|
||||
|
||||
#endif /* IDT_H */
|
||||
|
@ -4,37 +4,117 @@
|
||||
#include <signal.h>
|
||||
#include <stdio.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()
|
||||
{
|
||||
// Add logic to handle Divide By Zero Exception
|
||||
printf("Divide By Zero Exception\n");
|
||||
printf("Divide By Zero Exception\n");
|
||||
|
||||
// Additional Exception Handling Logic:
|
||||
// Example: Perform specific actions for Divide By Zero scenario
|
||||
// - Log the exception to a file
|
||||
FILE *logFile = fopen("error.log", "a");
|
||||
if (logFile != NULL) {
|
||||
fprintf(logFile, "Divide By Zero Exception occurred\n");
|
||||
fclose(logFile);
|
||||
}
|
||||
// Additional Exception Handling Logic:
|
||||
// Example: Perform specific actions for Divide By Zero scenario
|
||||
// - Log the exception to a file
|
||||
FILE *logFile = fopen("error.log", "a");
|
||||
if (logFile != NULL)
|
||||
{
|
||||
fprintf(logFile, "Divide By Zero Exception occurred\n");
|
||||
fclose(logFile);
|
||||
}
|
||||
|
||||
// - Gracefully terminate the kernel
|
||||
printf("Exiting kernel due to Divide By Zero Exception\n");
|
||||
// - Gracefully terminate the kernel
|
||||
printf("Exiting kernel due to Divide By Zero Exception\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// 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
|
||||
size += sizeof(size_t) - 1;
|
||||
size &= ~(sizeof(size_t) - 1);
|
||||
|
||||
// Search for a free block of sufficient size
|
||||
|
Loading…
Reference in New Issue
Block a user