Merge into main the new state of the operating system/kernel #1
11
Makefile
11
Makefile
@ -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
|
||||
|
@ -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
|
||||
|
37
features.md
37
features.md
@ -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 \
|
||||
|
@ -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
9
src/kernel/bootinfo.h
Normal 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
11
src/kernel/definitions.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Kernel definitions
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define __DEBUG__ false
|
||||
#define KERNEL_VERSION 0
|
||||
|
||||
#define ARCHITECTURE "I386"
|
@ -1,108 +1,123 @@
|
||||
#include "kernel.h"
|
||||
#define GB2 262144
|
||||
|
||||
extern "C" void kernel_main (void);
|
||||
extern "C" void kernel_main (BootInfo* bootinfo) {
|
||||
init_serial();
|
||||
pit_initialise();
|
||||
|
||||
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();
|
||||
startSuperVisorTerminal(bootinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Multiboot magic number
|
||||
* NOTE: Printf call should not be a thing this early on ...
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a little banner for cuteness
|
||||
*/
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
|
||||
|
||||
/**
|
||||
* 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 (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||
printf("Invalid magic number: 0x%x\n", magic);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a little banner for cuteness
|
||||
*/
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
|
||||
|
||||
/**
|
||||
* Use the address given as an argument as the pointer
|
||||
* to a Multiboot information structure.
|
||||
*/
|
||||
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
||||
if (CHECK_FLAG(mbt->flags, 6))
|
||||
{
|
||||
|
||||
/*
|
||||
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);
|
||||
Setup Physical memory managment
|
||||
*/
|
||||
MemoryInfo meminfo = {};
|
||||
bootinfo.memory = &meminfo;
|
||||
|
||||
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();
|
||||
}
|
||||
mapMultibootMemoryMap(bootinfo.memory , mbt);
|
||||
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
|
||||
|
||||
initGDT();
|
||||
init_idt();
|
||||
// Enable interrupts
|
||||
asm volatile("STI");
|
||||
PhysicalMemory memAlloc = PhysicalMemory{};
|
||||
memAlloc.setup(bootinfo.memory );
|
||||
|
||||
/*
|
||||
Mark already in use sections
|
||||
*/
|
||||
|
||||
CheckMBT( (multiboot_info_t *) addr);
|
||||
// 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;
|
||||
|
||||
kernel_main();
|
||||
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){
|
||||
|
||||
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");
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
};
|
@ -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
|
||||
);
|
||||
}
|
@ -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*);
|
@ -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--;
|
||||
|
||||
}
|
@ -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 ;
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
142
src/kernel/memory/memory.cpp
Normal file
142
src/kernel/memory/memory.cpp
Normal 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
|
||||
);
|
||||
}
|
||||
|
48
src/kernel/memory/memory.h
Normal file
48
src/kernel/memory/memory.h
Normal 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);
|
20
src/kernel/memory/memoryinfo.h
Normal file
20
src/kernel/memory/memoryinfo.h
Normal 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));
|
||||
|
||||
|
||||
|
@ -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( );
|
||||
|
||||
|
@ -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 * );
|
@ -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
21
todo.md
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user