mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2025-05-15 17:11:26 -07:00
minor additions to the kernel heap and adding acpi
This commit is contained in:
parent
a9f2826014
commit
50efcc13fe
53
kernel/acpi.c
Normal file
53
kernel/acpi.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "acpi.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Function to find the RSDP (Root System Description Pointer)
|
||||||
|
acpi_rsdp_t* acpi_find_rsdp() {
|
||||||
|
// Search memory from 0x000E0000 to 0x00100000 (BIOS)
|
||||||
|
for (uint32_t addr = 0x000E0000; addr < 0x00100000; addr += 16) {
|
||||||
|
acpi_rsdp_t* rsdp = (acpi_rsdp_t*)addr;
|
||||||
|
if (memcmp(rsdp->signature, "RSD PTR ", 8) == 0) {
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (int i = 0; i < sizeof(acpi_rsdp_t); i++) {
|
||||||
|
checksum += ((uint8_t*)rsdp)[i];
|
||||||
|
}
|
||||||
|
if (checksum == 0) {
|
||||||
|
return rsdp; // Valid RSDP found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL; // RSDP not found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to get the RSDT or XSDT based on the RSDP revision
|
||||||
|
void* acpi_get_rsdt_or_xsdt(acpi_rsdp_t* rsdp) {
|
||||||
|
if (rsdp->revision >= 2) {
|
||||||
|
return (void*)rsdp->xsdt_addr; // ACPI 2.0+ uses XSDT
|
||||||
|
} else {
|
||||||
|
return (void*)rsdp->rsdt_addr; // ACPI 1.0 uses RSDT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to find the FADT table within the RSDT or XSDT
|
||||||
|
acpi_fadt_t* acpi_find_fadt(void* rsdt_or_xsdt) {
|
||||||
|
acpi_rsdt_t* rsdt = (acpi_rsdt_t*)rsdt_or_xsdt;
|
||||||
|
uint32_t num_tables = (rsdt->length - sizeof(acpi_rsdt_t)) / sizeof(uint32_t);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_tables; i++) {
|
||||||
|
uint32_t table_addr = rsdt->tables[i];
|
||||||
|
acpi_fadt_t* fadt = (acpi_fadt_t*)table_addr;
|
||||||
|
if (fadt->signature == 0x50434146) { // "FACP" in ASCII
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (int j = 0; j < fadt->length; j++) {
|
||||||
|
checksum += ((uint8_t*)fadt)[j];
|
||||||
|
}
|
||||||
|
if (checksum == 0) {
|
||||||
|
return fadt; // Valid FADT found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL; // FADT not found
|
||||||
|
}
|
47
kernel/acpi.h
Normal file
47
kernel/acpi.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef ACPI_H
|
||||||
|
#define ACPI_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// ACPI base address (replace with actual value)
|
||||||
|
#define ACPI_BASE 0xE0000000
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ACPI RSDP Structure (Root System Description Pointer)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t signature[8]; // Should be "RSD PTR "
|
||||||
|
uint8_t checksum; // Checksum for the RSDP structure
|
||||||
|
uint8_t oem_id[6]; // OEM ID string
|
||||||
|
uint8_t revision; // ACPI revision
|
||||||
|
uint32_t rsdt_addr; // 32-bit RSDT address (ACPI 1.0)
|
||||||
|
uint32_t xsdt_addr; // 64-bit XSDT address (ACPI 2.0+)
|
||||||
|
} __attribute__((packed)) acpi_rsdp_t;
|
||||||
|
|
||||||
|
// ACPI RSDT Structure (Root System Description Table)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t signature; // Should be "RSDT"
|
||||||
|
uint32_t length; // Length of the table
|
||||||
|
uint8_t revision; // Revision of the RSDT table
|
||||||
|
uint8_t checksum; // Checksum for the RSDT table
|
||||||
|
uint32_t tables[]; // Array of pointers to other tables (RSDT/XSDT entries)
|
||||||
|
} __attribute__((packed)) acpi_rsdt_t;
|
||||||
|
|
||||||
|
// ACPI FADT Structure (Fixed ACPI Description Table)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t signature; // Should be "FACP"
|
||||||
|
uint32_t length; // Length of the table
|
||||||
|
uint8_t revision; // Revision of the FADT table
|
||||||
|
uint8_t checksum; // Checksum for the FADT table
|
||||||
|
uint32_t pm_tmr_address; // Power Management Timer Address
|
||||||
|
// ... other FADT fields
|
||||||
|
} __attribute__((packed)) acpi_fadt_t;
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
|
acpi_rsdp_t* acpi_find_rsdp();
|
||||||
|
void* acpi_get_rsdt_or_xsdt(acpi_rsdp_t* rsdp);
|
||||||
|
acpi_fadt_t* acpi_find_fadt(void* rsdt_or_xsdt);
|
||||||
|
|
||||||
|
#endif /* ACPI_H */
|
50
kernel/elf.c
50
kernel/elf.c
@ -0,0 +1,50 @@
|
|||||||
|
#include "elf.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// This assumes that the elf is ELF32 and little-endian Intel X86 architecture.
|
||||||
|
|
||||||
|
// Check if a binary is a valid ELF executable.
|
||||||
|
int elf_validate(const void* data) {
|
||||||
|
const Elf32_Ehdr* header = (const Elf32_Ehdr*)data;
|
||||||
|
|
||||||
|
if (*(uint32_t*)header->e_ident != ELF_MAGIC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (header->e_type != ET_EXEC && header->e_type != ET_DYN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (header->e_machine != EM_386)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load an ELF executable into memory.
|
||||||
|
int elf_load(const void* data, void (*load_segment)(uint32_t vaddr, const void* src, uint32_t size)) {
|
||||||
|
const Elf32_Ehdr* header = (const Elf32_Ehdr*)data;
|
||||||
|
const Elf32_Phdr* ph = (const Elf32_Phdr*)((uint8_t*)data + header->e_phoff);
|
||||||
|
|
||||||
|
for (int i = 0; i < header->e_phnum; i++) {
|
||||||
|
if (ph[i].p_type != PT_LOAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const void* src = (uint8_t*)data + ph[i].p_offset;
|
||||||
|
uint32_t vaddr = ph[i].p_vaddr;
|
||||||
|
uint32_t filesz = ph[i].p_filesz;
|
||||||
|
uint32_t memsz = ph[i].p_memsz;
|
||||||
|
|
||||||
|
// Copy data segment
|
||||||
|
load_segment(vaddr, src, filesz);
|
||||||
|
|
||||||
|
// Zero remaining BSS (if any)
|
||||||
|
if (memsz > filesz) {
|
||||||
|
uint8_t* bss_start = (uint8_t*)(vaddr + filesz);
|
||||||
|
for (uint32_t j = 0; j < memsz - filesz; j++) {
|
||||||
|
bss_start[j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return header->e_entry;
|
||||||
|
}
|
52
kernel/elf.h
52
kernel/elf.h
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef ELF_H
|
||||||
|
#define ELF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ELF_MAGIC 0x464C457F // "\x7FELF" in little-endian
|
||||||
|
|
||||||
|
// ELF Types
|
||||||
|
#define ET_EXEC 2
|
||||||
|
#define ET_DYN 3
|
||||||
|
|
||||||
|
// ELF Machine
|
||||||
|
#define EM_386 3
|
||||||
|
|
||||||
|
// ELF Ident indexes
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
// Program header types
|
||||||
|
#define PT_NULL 0
|
||||||
|
#define PT_LOAD 1
|
||||||
|
|
||||||
|
// ELF Header (32-bit)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t e_ident[EI_NIDENT];
|
||||||
|
uint16_t e_type;
|
||||||
|
uint16_t e_machine;
|
||||||
|
uint32_t e_version;
|
||||||
|
uint32_t e_entry; // Entry point
|
||||||
|
uint32_t e_phoff; // Program header table offset
|
||||||
|
uint32_t e_shoff; // Section header table offset
|
||||||
|
uint32_t e_flags;
|
||||||
|
uint16_t e_ehsize;
|
||||||
|
uint16_t e_phentsize;
|
||||||
|
uint16_t e_phnum;
|
||||||
|
uint16_t e_shentsize;
|
||||||
|
uint16_t e_shnum;
|
||||||
|
uint16_t e_shstrndx;
|
||||||
|
} __attribute__((packed)) Elf32_Ehdr;
|
||||||
|
|
||||||
|
// Program Header (32-bit)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t p_type;
|
||||||
|
uint32_t p_offset;
|
||||||
|
uint32_t p_vaddr;
|
||||||
|
uint32_t p_paddr;
|
||||||
|
uint32_t p_filesz;
|
||||||
|
uint32_t p_memsz;
|
||||||
|
uint32_t p_flags;
|
||||||
|
uint32_t p_align;
|
||||||
|
} __attribute__((packed)) Elf32_Phdr;
|
||||||
|
|
||||||
|
#endif // ELF_H
|
@ -1,6 +1,63 @@
|
|||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct heap_block {
|
||||||
|
size_t size;
|
||||||
|
struct heap_block *next;
|
||||||
|
int is_free;
|
||||||
|
} heap_block_t;
|
||||||
|
|
||||||
|
static heap_block_t *free_list = NULL;
|
||||||
|
static void *heap_start_ptr = NULL;
|
||||||
|
static void *heap_end_ptr = NULL;
|
||||||
|
|
||||||
|
void heap_init(void *heap_start, void *heap_end) {
|
||||||
|
heap_start_ptr = heap_start;
|
||||||
|
heap_end_ptr = heap_end;
|
||||||
|
|
||||||
|
free_list = (heap_block_t *)heap_start;
|
||||||
|
free_list->size = (uintptr_t)heap_end - (uintptr_t)heap_start - sizeof(heap_block_t);
|
||||||
|
free_list->next = NULL;
|
||||||
|
free_list->is_free = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void *heap_alloc(size_t size) {
|
void *heap_alloc(size_t size) {
|
||||||
// Heap allocation code
|
heap_block_t *current = free_list;
|
||||||
return NULL;
|
|
||||||
|
while (current != NULL) {
|
||||||
|
if (current->is_free && current->size >= size) {
|
||||||
|
// If it's a large block, split it
|
||||||
|
if (current->size > size + sizeof(heap_block_t)) {
|
||||||
|
heap_block_t *new_block = (heap_block_t *)((uintptr_t)current + sizeof(heap_block_t) + size);
|
||||||
|
new_block->size = current->size - size - sizeof(heap_block_t);
|
||||||
|
new_block->next = current->next;
|
||||||
|
new_block->is_free = 1;
|
||||||
|
|
||||||
|
current->next = new_block;
|
||||||
|
current->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
current->is_free = 0;
|
||||||
|
return (void *)((uintptr_t)current + sizeof(heap_block_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // Out of memory
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_free(void *ptr) {
|
||||||
|
if (ptr == NULL) return;
|
||||||
|
|
||||||
|
heap_block_t *block = (heap_block_t *)((uintptr_t)ptr - sizeof(heap_block_t));
|
||||||
|
block->is_free = 1;
|
||||||
|
|
||||||
|
// Coalesce with next block
|
||||||
|
if (block->next && block->next->is_free) {
|
||||||
|
block->size += block->next->size + sizeof(heap_block_t);
|
||||||
|
block->next = block->next->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Coalesce with previous block for better compaction
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void heap_init(void *heap_start, void *heap_end);
|
||||||
|
|
||||||
void *heap_alloc(size_t size);
|
void *heap_alloc(size_t size);
|
||||||
|
void heap_free(void *ptr);
|
||||||
|
|
||||||
#endif // HEAP_H
|
#endif // HEAP_H
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
#define LPT1 0x378
|
#define LPT1 0x378
|
||||||
|
|
||||||
@ -22,6 +23,10 @@ void kmain(void) {
|
|||||||
serial_init();
|
serial_init();
|
||||||
serial_write("Serial port initialized.\n");
|
serial_write("Serial port initialized.\n");
|
||||||
|
|
||||||
|
terminal_write("Identifying CPU...\n");
|
||||||
|
identify_cpu();
|
||||||
|
serial_write("CPU identification complete.\n");
|
||||||
|
|
||||||
lpt_write('L'); // Send 'L' to LPT1 to test
|
lpt_write('L'); // Send 'L' to LPT1 to test
|
||||||
|
|
||||||
terminal_write("Initializing GDT...\n");
|
terminal_write("Initializing GDT...\n");
|
||||||
@ -53,11 +58,17 @@ void kmain(void) {
|
|||||||
serial_write("Memory map retrieved.\n");
|
serial_write("Memory map retrieved.\n");
|
||||||
|
|
||||||
terminal_write("Memory Regions:\n");
|
terminal_write("Memory Regions:\n");
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
for (uint32_t i = 0; i < mmap_size; i++) {
|
for (uint32_t i = 0; i < mmap_size; i++) {
|
||||||
terminal_write(" - Region: ");
|
terminal_write(" - Base: ");
|
||||||
// You would format and print base/length/type here
|
print_hex((uint32_t)(mmap[i].base_addr & 0xFFFFFFFF)); // Lower 32 bits
|
||||||
// (e.g., with a basic itoa and print_hex helper)
|
terminal_write(", Length: ");
|
||||||
serial_write("Memory region entry\n");
|
print_hex((uint32_t)(mmap[i].length & 0xFFFFFFFF)); // Lower 32 bits
|
||||||
|
terminal_write(", Type: ");
|
||||||
|
itoa(mmap[i].type, buf, 10);
|
||||||
|
terminal_write(buf);
|
||||||
|
terminal_write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
terminal_write("System initialized. Halting.\n");
|
terminal_write("System initialized. Halting.\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user