Basic block allocation for physical memory allocation.

- 1 block = 4096 bytes : because this will make page fault handling possibly
somewhat easier

- 1 byte in the bitmap = 8 blocks of physical memory

unsure if the allocation is perfect ... guess i'll find out some day if this is actually correct.

The bitmap needs 16kb to keep track of 2gb of physical memory. Seems a decent percentage to me.
This commit is contained in:
Nigel Barink 2022-02-26 20:44:16 +01:00
parent 7330b81a10
commit b4cff3e667
24 changed files with 472 additions and 426 deletions

View File

@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
CFLAGS = -ffreestanding -O2 -Wall -Wextra
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/PageFrameAllocator.o
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o
SRC_DIR = src
BUILD_DIR = build
@ -54,7 +54,7 @@ $(BUILD_DIR)/kterm.o:
$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/boot.o:
$(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o
$(AS) $(SRC_DIR)/kernel/boot.s -o $(BUILD_DIR)/boot.o
$(BUILD_DIR)/crti.o:
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
@ -65,8 +65,6 @@ $(BUILD_DIR)/crtn.o:
$(BUILD_DIR)/io.o:
$(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/PageDirectory.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/idt.o:
$(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -81,8 +79,6 @@ $(BUILD_DIR)/pic.o:
$(BUILD_DIR)/string.o:
$(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
$(BUILD_DIR)/PhysicalMemoryManager.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/pit.o:
$(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -97,3 +93,6 @@ $(BUILD_DIR)/time.o:
$(BUILD_DIR)/sv-terminal.o:
$(CPP) -c $(SRC_DIR)/kernel/sv-terminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/memory.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/memory.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti

View File

@ -19,7 +19,8 @@ Multiboot information can be read by the kernel.
________________________
### The goal
Writing a hobby operating system to better understand the basic building blocks of any operating system.
Writing a hobby operating system to better understand the basic building blocks of any operating system.Initially I'd like for my
operating system to be able to run bash.
________________________
### Operating System Technical specs/details

View File

@ -1,29 +1,30 @@
# TODO list
## Start planning
## Basics
<input type="checkbox" checked/> Setup Cross-Compiler \
<input type="checkbox" checked/> Multiboot to kernel \
<input type="checkbox" checked/> Printing string to the screen \
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
<input type="checkbox" checked/> Printing values/numbers to the screen \
<input type="checkbox" checked/> Basic Terminal \
<input type="checkbox" checked/> Extend Multiboot implementation \
<input type="checkbox" checked/> Output to serial port \
<input type="checkbox" checked/> Move to protected mode \
<input type="checkbox" checked/> Enabel CMOS clock \
<input type="checkbox" /> Time measurement (PIC &| PIT) \
<input type="checkbox" checked/> Time measurement (PIC &| PIT) \
<input type="checkbox" /> Detect CPU speed \
<input type="checkbox" checked/> Interrupt / exception system (API) \
<input type="checkbox" checked/> Plan your memory map (virtual, and physical) : decide where you want the data to be. \
<input type="checkbox" checked/> PCI support \
<input type="checkbox" checked/> ATA PIO Mode support \
<input type="checkbox" checked/> FAT Filesystem \
<input type="checkbox" /> Virtual filesystem \
<input type="checkbox" checked/> Keyboard support ( P/S2 Keyboard) \
<input type="checkbox" checked/> Physical memory management \
<input type="checkbox" /> Paging \
<input type="checkbox" /> Virtual memory management \
<input type="checkbox" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
<input type="checkbox" /> Enable SIMD Extensions (SSE)
## Other features I am thinking of:
<input type="checkbox" /> PCI support \
<input type="checkbox" /> ATA PIO Mode support \
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
<input type="checkbox" /> ATAPI support \
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
<input type="checkbox" checked/> Memory Management (MMU)
<input type="checkbox" /> Hardware Management system
<input type="checkbox" /> Preemptive multi tasking \
<input type="checkbox" /> Processes \
<input type="checkbox" /> Threads
@ -32,9 +33,11 @@
<input type="checkbox" /> POSIX compliance (partially) \
<input type="checkbox" /> RPC - for interprocess communication \
<input type="checkbox" /> Sync primitives - Semaphores, Mutexes, spinlocks et al. \
<input type="checkbox" /> Basic Terminal \
<input type="checkbox" /> Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \
<input type="checkbox" /> ACPI support \
<input type="checkbox" /> ATAPI support \
## Optional
<input type="checkbox" /> Basic Window server/client \
## Support for more filesystems if I like the challenge in writing these ...
<input type="checkbox" /> FAT Filesystem \
<input type="checkbox" /> EXT2 Filesystem
<input type="checkbox" /> USTAR Filesystem \

View File

@ -1,3 +1,8 @@
menuentry "BarinkOS"{
GRUB_DEFAULT=0
GRUB_TIMEOUT=-1
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUITE=true
menuentry "BarinkOS" {
multiboot /boot/myos.bin
}

9
src/kernel/bootinfo.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "memory/memoryinfo.h"
struct BootInfo{
const char* BootStructureID = "BarinkOS";
MemoryInfo* memory;
};

11
src/kernel/definitions.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
/**
* Kernel definitions
*/
#define __DEBUG__ false
#define KERNEL_VERSION 0
#define ARCHITECTURE "I386"

View File

@ -1,108 +1,123 @@
#include "kernel.h"
#define GB2 262144
extern "C" void kernel_main (void);
extern "C" void early_main(unsigned long magic, unsigned long addr){
/**
* Initialize terminal interface
* NOTE: This should be done later on , the magic value should be checked first.
*/
kterm_init();
/**
* Check Multiboot magic number
* NOTE: Printf call should not be a thing this early on ...
*/
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
printf("Invalid magic number: 0x%x\n", magic);
return;
}
extern "C" void kernel_main (BootInfo* bootinfo) {
init_serial();
pit_initialise();
/**
* Show a little banner for cuteness
*/
printf("|=== BarinkOS ===|\n");
startSuperVisorTerminal(bootinfo);
}
/**
* Use the address given as an argument as the pointer
* to a Multiboot information structure.
*/
multiboot_info_t* mbt = (multiboot_info_t*) addr;
/*
If we got a memory map from our bootloader we
should be parsing it to find out the memory regions available.
*/
if (CHECK_FLAG(mbt->flags, 6))
{
printf("Preliminary results mmap scan:\n");
mapMultibootMemoryMap(mbt);
PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/);
PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length);
PhysicalMemoryManager_deinitialise_kernel();
}
initGDT();
init_idt();
// Enable interrupts
asm volatile("STI");
CheckMBT( (multiboot_info_t *) addr);
kernel_main();
extern "C" void early_main(unsigned long magic, unsigned long addr){
/**
* Initialize terminal interface
* NOTE: This should be done later on , the magic value should be checked first.
*/
kterm_init();
/**
* Check Multiboot magic number
* NOTE: Printf call should not be a thing this early on ...
*/
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
printf("Invalid magic number: 0x%x\n", magic);
return;
}
extern "C" void kernel_main (void) {
init_serial();
pit_initialise();
while (true){
printf("SUPERVISOR:>$ " );
int characterCount = 0;
char command[10] = "";
// NOTE: lets just show a kernel prompt
uint8_t ScanCode = getKey();
while( ScanCode != 0x1C )
{
char character = getASCIIKey();
kterm_put(character );
// wHAT THE HELL
if( characterCount < 10 ){
command[characterCount] = character;
characterCount++;
}
ScanCode = getKey();
}
printf("\n");
KeyHandled();
if ( strncmp("TIME", command , characterCount ) == 0 ) {
read_rtc();
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)\n" ,year, month, day, hour, minute, second, pit_tick);
} else if(strncmp("TEST", command, characterCount) == 0){
// asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0
}
else{
printf("Unknown command\n");
}
/**
* Show a little banner for cuteness
*/
printf("|=== BarinkOS ===|\n");
delay(1000);
}
/**
* Use the address given as an argument as the pointer
* to a Multiboot information structure.
*/
multiboot_info_t* mbt = (multiboot_info_t*) addr;
/**
* Construct our own bootInfo structure
*/
BootInfo bootinfo = {};
/*
If we got a memory map from our bootloader we
should be parsing it to find out the memory regions available.
*/
if (CHECK_FLAG(mbt->flags, 6))
{
}
/*
Setup Physical memory managment
*/
MemoryInfo meminfo = {};
bootinfo.memory = &meminfo;
mapMultibootMemoryMap(bootinfo.memory , mbt);
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
PhysicalMemory memAlloc = PhysicalMemory{};
memAlloc.setup(bootinfo.memory );
/*
Mark already in use sections
*/
// Mark kernel memory as used
printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", kernel_begin , kernel_end );
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
} else{
printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len );
memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len);
}
}
printf("allocate region: 0x%x, size : 0x%x bytes\n", kernel_begin, kernel_end - kernel_begin );
memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin);
// test alloc_block
uint8_t* memory = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory);
uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory2);
memAlloc.free_block((void*) memory);
uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block();
// memAlloc.free_block((void*) memory);
}
initGDT();
init_idt();
// Enable interrupts
asm volatile("STI");
CheckMBT( (multiboot_info_t *) addr);
kernel_main(&bootinfo);
}

View File

@ -1,14 +1,20 @@
#pragma once
extern "C"{
extern "C"
{
#include "../libc/include/string.h"
}
#include "definitions.h"
#include "vga/VBE.h"
#include "tty/kterm.h"
#include "./bootloader/multiboot.h"
#include "bootinfo.h"
#include "memory/memory.h"
#include "memory/memoryinfo.h"
#include "bootcheck.h"
#include "memory/physical/PhysicalMemoryManager.h"
#include "memory/frames/PageFrameAllocator.h"
#include "gdt/gdtc.h"
#include "idt/idt.h"

View File

@ -13,26 +13,26 @@ inline void bitmap_unset(uint32_t* map , int index)
map[index/32] &= ~(1 << (index % 32));
}
inline int bitmap_first_unset( uint32_t* map , int size)
inline uint32_t bitmap_first_unset( uint32_t* map , int map_size)
{
uint32_t rem_bits = size % 32;
for(uint32_t i = 0; i < size/32; i++)
for ( int i = 0 ; i < map_size ; i ++ )
{
if(map[i] != 0xFFFFFFFF){
for(int j = 0; j < 32; j++){
if(!(map[i] & (1<< j))){
return (i*32) + j;
// a bit or more is set within this byte!
if( (map[i] & 0xFFFFFFFF) > 0 ){
// which bit is set?
for(int j = 0 ; j < 32 ; j++){
if ( (map[i] & (0x00000001 << j)) > 0)
{
printf("Found bit: byte 0x%x , bit 0x%x\n", i , j);
return (i*32)+j;
}
}
}
}
if(rem_bits){
for(uint32_t j = 0; j < rem_bits; j++){
if(!(map[size/32] & (1 << j ))){
return size + j; // Original author divided size by 32 and then multiplied it by 32 which is a net zero calculation ?!?
}
}
}
return -1;

View File

@ -1,47 +1,43 @@
#include "PageDirectory.h"
#include <stdint.h>
void PageDirectory::enable()
{
void PageDirectory::enable(){
// https://wiki.osdev.org/Setting_Up_Paging
//set each entry to not present
int i;
for(i = 0; i < 1024; i++)
{
// This sets the following flags to the pages:
// Supervisor: Only kernel-mode can access them
// Write Enabled: It can be both read from and written to
// Not Present: The page table is not present
this->page_directory[i] = 0x00000002;
}
// int i;
// for(i = 0; i < 1024; i++)
// {
// // This sets the following flags to the pages:
// // Supervisor: Only kernel-mode can access them
// // Write Enabled: It can be both read from and written to
// // Not Present: The page table is not present
// this->page_directory[i] = 0x00000002;
// }
// holds the physical address where we want to start mapping these pages to.
// in this case, we want to map these pages to the very beginning of memory.
// // holds the physical address where we want to start mapping these pages to.
// // in this case, we want to map these pages to the very beginning of memory.
//we will fill all 1024 entries in the table, mapping 4 megabytes
for(unsigned int i = 0; i < 1024; i++)
{
// As the address is page aligned, it will always leave 12 bits zeroed.
// Those bits are used by the attributes ;)
first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
}
// //we will fill all 1024 entries in the table, mapping 4 megabytes
// for(unsigned int i = 0; i < 1024; i++)
// {
// // As the address is page aligned, it will always leave 12 bits zeroed.
// // Those bits are used by the attributes ;)
// first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
// }
// attributes: supervisor level, read/write, present
this->page_directory[0] = ((unsigned int)first_page_table) | 3;
// // attributes: supervisor level, read/write, present
// this->page_directory[0] = ((unsigned int)first_page_table) | 3;
printf("Enable Paging!\n");
loadPageDirectory(this->page_directory);
enablePaging();
}
/*
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size )
{
from = from & 0xFFFFF000; // Discard the bits we don't want
for (; size > 0; from += 4096, first_pte++)
{
*first_pte = from | 1; // makr page present.
}
}
*/

View File

@ -1,17 +1,18 @@
#pragma once
#include <stdint.h>
extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging();
typedef uintptr_t address_t;
#include "./memory.h"
#include "./../tty/kterm.h"
#define KB 1024
typedef uintptr_t address_t;
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
static volatile address_t pmem_stack[MAX_PAGES];
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging();
struct page_directory_entry {};
struct page_table_entry{};
@ -21,8 +22,10 @@ struct page_table_entry{};
class PageDirectory {
public:
void enable ();
void MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size );
private:
uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
uint32_t page_directory[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
uint32_t first_page_table[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
};

View File

@ -1,38 +0,0 @@
#include "PageFrameAllocator.h"
MemoryInfo memInfo {};
void mapMultibootMemoryMap( multiboot_info_t *mbt){
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
memInfo.memorySizeInBytes += mmap->len;
} else {
memInfo.reservedMemoryInBytes += mmap->len;
}
print_Multiboot_memory_Map(mmap);
}
uint32_t memorySizeInGiB = memInfo.memorySizeInBytes / 1073741824;
printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memInfo.memorySizeInBytes, memorySizeInGiB );
printf("Reserved Memory: 0x%x bytes\n", memInfo.reservedMemoryInBytes );
}
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap){
printf(
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
(unsigned) mmap->size,
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
(unsigned) (mmap->len & 0xffffffff),
(unsigned) mmap->type
);
}

View File

@ -1,20 +0,0 @@
#pragma once
#include "../arch/i386/tty/kterm.h"
#include <stdint.h>
#include "../bootloader/multiboot.h"
struct MemoryInfo{
uint32_t memorySizeInBytes = 0;
uint32_t reservedMemoryInBytes = 0;
};
extern void *kernel_begin;
extern void *kernel_end;
void print_Multiboot_memory_Map(multiboot_memory_map_t*);
void mapMultibootMemoryMap(multiboot_info_t*);

View File

@ -1,118 +0,0 @@
#include "PhysicalMemoryManager.h"
size_t mem_size = 0;
int used_blocks = 0;
size_t max_blocks = 0;
uint32_t* pmmap = 0;
size_t pmmap_size = 0;
void PhysicalMemoryManager_initialise(uint32_t physicalmemorymap_address, size_t size )
{
mem_size = size;
max_blocks = KB_TO_BLOCKS(mem_size);
used_blocks = max_blocks;
pmmap = (uint32_t*) physicalmemorymap_address;
if(max_blocks % BLOCKS_PER_WORD)
pmmap_size++;
memset(pmmap, 0xFF, pmmap_size);
}
void PhysicalMemoryManager_region_initialise(uint32_t base, size_t size)
{
size_t blocks = size /BLOCK_SIZE;
uint32_t align = base / BLOCK_SIZE;
for(size_t i = 0 ; i < blocks; i ++)
{
bitmap_unset(pmmap, align++);
used_blocks--;
}
bitmap_set(pmmap, 0);
}
void PhysicalMemoryManager_region_deinitialise(uint32_t base, size_t size )
{
size_t blocks = size / BLOCK_SIZE;
uint32_t align = base / BLOCK_SIZE;
for(size_t i = 0 ; i < blocks; i++ )
{
bitmap_set(pmmap, align++);
used_blocks++;
}
}
void PhysicalMemoryManager_initialise_available_regions(uint32_t mmap_, uint32_t mmap_end_)
{
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*)mmap_;
multiboot_memory_map_t *mmap_end= (multiboot_memory_map_t*) mmap_end_;
for(int i = 0; mmap < mmap_end ; mmap++, i++)
{
if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE)
{
PhysicalMemoryManager_region_initialise((uint32_t) mmap->addr, (size_t) mmap->len);
}
}
}
void PhysicalMemoryManager_deinitialise_kernel()
{
extern uint8_t kernel_begin;
extern uint8_t kernel_end;
size_t kernel_size = (size_t) &kernel_end - (size_t) &kernel_begin;
uint32_t pmmap_size_aligned = pmmap_size;
if(!IS_ALIGNED(pmmap_size_aligned, BLOCK_SIZE))
{
pmmap_size_aligned = ALIGN(pmmap_size_aligned, BLOCK_SIZE);
}
PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_begin, kernel_size);
PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_end, pmmap_size_aligned);
}
void* PhysicalMemoryManager_allocate_block()
{
if(used_blocks - max_blocks <= 0)
{
return 0;
}
int p_index = bitmap_first_unset(pmmap, p_index );
if(p_index == -1){
return 0;
}
bitmap_set(pmmap, p_index);
used_blocks++;
return (void*) (BLOCK_SIZE * p_index);
}
void PhysicalMemoryManager_free_block(void* p){
if(p==0){
return ;
}
uint32_t p_addr = (uint32_t) p;
int index = p_addr / BLOCK_SIZE;
bitmap_unset(pmmap, index);
used_blocks--;
}

View File

@ -1,34 +0,0 @@
#pragma once
#include "../bootloader/multiboot.h"
#include <stdint.h>
#include <stddef.h>
#include "../../libc/include/mem.h"
#include "../kstructures/bitmap.h"
#define BLOCK_SIZE 4092
#define BLOCKS_PER_WORD 32
#define KB_TO_BLOCKS(x) (((x) * 1024 ) / BLOCK_SIZE)
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
extern void PhysicalMemoryManager_initialise(uint32_t, size_t);
extern void PhysicalMemoryManager_region_initialise(uint32_t, size_t);
extern void PhysicalMemoryManager_region_deinitialise(uint32_t,size_t);
extern void PhysicalMemoryManager_initialise_available_regions(uint32_t, uint32_t);
extern void PhysicalMemoryManager_deinitialise_kernel();
extern void* PhysicalMemoryManager_allocate_block();
extern void PhysicalMemoryManager_free_block(void* p);
extern size_t mem_size;
extern int used_blocks;
extern size_t max_blocks;
extern uint32_t* pmmap;
extern size_t pmmap_size ;

View File

@ -1,33 +0,0 @@
#pragma once
/**
* We'll need something to this effect to allocate memory in the kernel
* this will hopefully someday implement a full slab allocator
**/
enum SlabState {
empty,
partial,
full
};
class CacheSlab {
const int SlabSize = 4000;
void* start = 0x0;
};
class Allocator {
public:
Allocator();
~Allocator();
void* kmalloc( int size );
void kfree (void* address);
private:
CacheSlab** _cache;
};

View File

@ -0,0 +1,142 @@
#include "./memory.h"
uint32_t* memoryBitMap;
/*
*/
void PhysicalMemory::setup( MemoryInfo* memory) {
// calculate the maximum number of blocks
max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
used_blocks = 0;
memoryBitMap = (uint32_t*) 0x00a00000;
printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8));
//Size of memory map
uint32_t memMap_size = (max_blocks / 8 ) ;
printf("Memory Map size: 0x%x\n", memMap_size );
printf("size of int in bytes: 0x%x \n" , sizeof(int));
// Set all places in memory as free
memset(memoryBitMap, 0xFF, memMap_size );
}
// NOTE: this can only give blocks of 4kb at a time!
void* PhysicalMemory::allocate_block() {
uint8_t blocks_available = max_blocks - used_blocks;
// Are there any blocks available?
if( blocks_available <= 0)
{
printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
return 0;
}
// Find 1 free block somewhere
int free_block_index = bitmap_first_unset(memoryBitMap, (max_blocks /8) /*memMap Size*/ );
if(free_block_index == -1)
{
printf("Could not find a good block!\n");
// Could not find a block
return (void*)0xFFFF;
}
if(free_block_index == 0)
printf("Somethings wrong!!!\n");
// Set the block to be used!
bitmap_unset(memoryBitMap, free_block_index);
// Increase the used_block count!
used_blocks++;
printf("used blocks: 0x%x\n", used_blocks);
// return the pointer to the physical address
return (void*) (BLOCK_SIZE * free_block_index);
}
void PhysicalMemory::free_block(void* p) {
// If it is a null pointer we don't need to do anything.
if(p==0) {
return;
}
// calculate the index into the bitmap
int index = ((uint32_t) p) / BLOCK_SIZE;
// set the block to be free
bitmap_set(memoryBitMap, index);
used_blocks--;
printf("used blocks: 0x%x, after free\n", used_blocks);
}
void PhysicalMemory::allocate_region(uint32_t startAddress, uint32_t size) {
// every bit should be 4KiB
// every byte is 8*4KiB = 32KiB
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
int startBlock = (startAddress / 1024) / 4 / 8 ;
// printf("NumberOfBlocksToAllocate: 0x%x\n", NumberOfBlocksToAllocate);
//printf( "start block: 0x%x\n" , startBlock);
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
{
//printf("ALLOCATE BLOCK: 0x%x\n" , startBlock + i );
bitmap_unset(memoryBitMap, startBlock+ i);
used_blocks++;
}
}
void PhysicalMemory::deallocate_region(uint32_t StartAddress , uint32_t size ) {
// NOT IMPLEMENTED YET
}
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
memInfo->TotalMemory += mmap->len;
} else {
memInfo->ReservedMemory += mmap->len;
}
print_Multiboot_memory_Map(mmap);
}
}
/**
* @brief Debug Verbose functions
*
* @param mmap
*/
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
printf(
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
(unsigned) mmap->size,
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
(unsigned) (mmap->len & 0xffffffff),
(unsigned) mmap->type
);
}

View File

@ -0,0 +1,48 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#include "memoryinfo.h"
#include "../bootloader/multiboot.h"
#include "../tty/kterm.h"
#include "../../libc/include/mem.h"
#include "../kstructures/bitmap.h"
#define BLOCK_SIZE 4092
#define BLOCKS_PER_WORD 32 // A word is 16 bit in x86 machines according to my google search results!
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
extern uint32_t kernel_begin;
extern uint32_t kernel_end;
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks);
extern uint32_t* memoryBitMap;
class PhysicalMemory
{
public:
void setup(MemoryInfo* memory);
void destroy();
void free_block(void* ptr);
void* allocate_block();
void allocate_region(uint32_t, uint32_t);
void deallocate_region(uint32_t , uint32_t );
private:
size_t pmmap_size;
size_t max_blocks;
int used_blocks;
};
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt);
/**
* @brief Debug Verbose Functions
*
* @param mmap
*/
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap);

View File

@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
struct MemoryArea{
void* StartAddress;
size_t Size;
unsigned int type;
MemoryArea* Next;
}__attribute__((packed));
struct MemoryInfo {
uint32_t TotalMemory;
uint32_t ReservedMemory;
MemoryArea* MemoryRegionList;
}__attribute__((packed));

View File

@ -1,6 +1,6 @@
#include "superVisorTerminal.h"
void startSuperVisorTerminal(){
void startSuperVisorTerminal(BootInfo* bootinfo){
while (true){
printf("SUPERVISOR:>$ " );
@ -40,7 +40,16 @@ void startSuperVisorTerminal(){
printf("========= Memory ==========\n");
printf("Kernel MemoryMap:\n");
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
printf("Frames used: 0x%x blocks of 4 KiB\n", used_blocks);
printf("Frames used: 0x%x blocks of 4 KiB\n", 0);
const int bytesInGiB = 1073741824;
int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
int64_t effectiveNumberOfGib = bootinfo->memory->TotalMemory / bytesInGiB;
int64_t GiBs = effectiveNumberOfGib + bytesLeft;
printf("Available Memory: %d bytes, %d GiB\n", bootinfo->memory->TotalMemory, GiBs );
printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory);
//printf("\n\n");
//PrintPhysicalMemoryAllocation( );

View File

@ -3,6 +3,7 @@
#include "../time.h"
#include "../pit.h"
#include "../keyboard/keyboard.h"
#include "../memory/physical/PhysicalMemoryManager.h"
#include "../memory/memory.h"
#include "../bootinfo.h"
void startSuperVisorTerminal();
void startSuperVisorTerminal(BootInfo * );

View File

@ -1,8 +1,8 @@
inline void* memset (void* ptr, int value, size_t num){
for( int i = 0; i < num; i++ )
{
int* data = (int*)ptr+ i;
*data = value;
unsigned char* data = (unsigned char*)ptr+ i;
*data = (unsigned char)value;
}
return ptr;
}

21
todo.md
View File

@ -0,0 +1,21 @@
# TODO list
![Todo image](https://camo.githubusercontent.com/c43d969d9d071c8342e9a69cdd6acb433c541f431127738974ce22290c46f2b8/68747470733a2f2f692e696d6775722e636f6d2f4f764d5a4273392e6a7067)
This list keeps me focused and organised so I don't forget what
needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember
to do on a more in depth level.
## --
[ ] Setup paging \
[ ] HELP command
[ ] Setup a proper HEAP \
[ ] Setup a proper Stack \
[ ] Setup KMalloc and KFree \
[ ] Merge Functioning Feature branches into sandboxKernelDev \
[ ] Remove merged feature branches \
[ ] Merge sandboxKernelDev with dev \
[ ] Remove sandboxKernelDev branch \
[ ] Implement proper virtual filesystem