summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md34
-rw-r--r--kernel/kernel.c11
-rw-r--r--kernel/mem.c88
-rw-r--r--kernel/mem.h31
-rw-r--r--kernel/multiboot.c6
-rw-r--r--kernel/multiboot.h2
-rw-r--r--kernel/scheduler.c4
-rw-r--r--kernel/smp.c4
-rw-r--r--kernel/vmem.c18
9 files changed, 104 insertions, 94 deletions
diff --git a/README.md b/README.md
index 207957c..66218c6 100644
--- a/README.md
+++ b/README.md
@@ -98,32 +98,16 @@ Discontinued Features
Todos
-----
-* ipxe (network drivers?)
-* io_wait?
-* cpuid (i686) check apic?
-* lapic / spurious . ioapic
-* newlib reentrant struct!!
-* Interrupts between BSP and APS ?
-* Do not forget to flush TLB
-* APIC / at least LAPIC? HPET timer?
-* Check 16bit stack alignment before ALL calls from assembler!
-* Ethernet driver E1000 / NS2000 & Networking stack
+* Unit Tests
+* Newlib Reeentrancy Struct
+* Ethernet driver E1000 / NS2000 & Networking stack (ipxe network drivers?)
* Porting (ncurses, gcc, binutils, vim, apache...)
-* Check VESA mode and adapt console (text/gui)
-* cpu sleep if nothing to do
-* use other cpus
-* pdirectory contains bad bad hardcoded shit
-* remap stack
-* upper half kernel
-* do not disable paging on context swtiches..
-* fork/clone
-* sbrk()
-* ESP collisions / TSS-ESP0
-* kbfree() and real pgdirectory alloc
-* implement posix(?) getdents instead of our own readdir.
-* Turning on some gcc optimizations breaks the kernel?
-* Writing to files (at least in ext2 ram image)
-* mutex
+* Posix getdents
+* GCC optimizations (break kernel?)
+* Writing to ext2 RAM-image
+* Mutes
+* Flush TLB
+* GUI / Window Manager (update\_rect, etc..)
REFERENCES
==========
diff --git a/kernel/kernel.c b/kernel/kernel.c
index dfcab3f..2fdb09b 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -46,12 +46,13 @@ void kernel_main(uint32_t eax,uint32_t ebx)
// -- DISABLE LEGACY PIC -- //
klog("Remapping & Disabling Programmable Interrupt Controller (PIC) ...");
+ fixme("io_wait & spurious interrupts");
asm_pic_setup();
// -- GET CONFIGS -- //
klog("Read Multiboot Structures ...");
multiboot_information *cfg_multiboot;
- cfg_multiboot=multiboot_read(eax, ebx);
+ cfg_multiboot=multiboot_read(eax, ebx,true);
klog("Read Advanced Power Configuration Interface (ACPI) Structures ...");
acpi_information cfg_acpi;
@@ -67,15 +68,21 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Interrupt Vector Table (IVT) init ...");
interrupts_init(0x08);
interrupts_install();
- fixme("register interrupt callback funcs");
+ fixme("register interrupt callback funcs (instead hardcoded dispatcher)");
// -- MEMORY MANAGEMENT -- //
klog("Memory init ... ");
uint32_t kernel_blocks=mem_init(cfg_multiboot);
klog("Vritual Memory / Paging init ... ");
+ fixme("do not disable anymore on context switching!");
+ fixme("write convenneint management funcs as: mapCPU, mapKErnel, map USerspace..");
+
pdirectory *dir=vmem_init(kernel_blocks,(uint32_t)cfg_multiboot->framebuffer_addr,cfg_acpi.local_apic_address,cfg_acpi.io_apic_address);
+
+ fixme("move stack?");
+
// -- RAM IMAGE -- //
klog("Ram Filesystem init ... ");
fs_mount(cfg_multiboot);
diff --git a/kernel/mem.c b/kernel/mem.c
index 7052e6c..79cfe9b 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -1,5 +1,6 @@
-#include <stdint.h>
#include "kernel.h"
+#include "mem.h"
+#include <stdint.h>
#include "multiboot.h"
#define PMMNGR_BLOCKS_PER_BYTE 8
@@ -7,7 +8,7 @@
#define PMMNGR_MAX_BLOCKS 1048576 // 4096*1048576 = 2^32 bytes (maxium addressable memory ~4GB)
#define PMMNGR_MAP_SIZE PMMNGR_MAX_BLOCKS/PMMNGR_BLOCKS_PER_BYTE/4
-// defined in linker.ld and multiboot.s
+// defined in linker.ld and asm_start.s
extern uint32_t kernel_start[];
extern uint32_t kernel_end[];
extern uint32_t stack_top[];
@@ -15,13 +16,12 @@ extern uint32_t stack_bottom[];
//memory map bit array. Each bit represents a 4KB memory block,
//so uint32_t represents 8*4 blocks
-static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE]; //32Kb
+static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE]; //128KiB
+//track number of free blocks
static uint32_t mem_free_blocks; //number of free blocks
-static uint32_t mem_max_block; //index of highest usable block
-static uint32_t mem_min_block; //index of lowset block available for alloc
-char *memmap_type_to_string[]=
+static char *memmap_type_to_string[]=
{
"Usable",
"Reserved",
@@ -30,30 +30,25 @@ char *memmap_type_to_string[]=
"Bad Memory"
};
-uint32_t mem_get_free_blocks_count()
-{
- return mem_free_blocks;
-}
-
// bit funcs!
-void mmap_set(int bit)
+static void mmap_set(int bit)
{
_mmngr_memory_map[bit / 32] |= (1 << (bit % 32));
}
-void mmap_unset(int bit)
+static void mmap_unset(int bit)
{
_mmngr_memory_map[bit / 32] &= ~ (1 << (bit % 32));
}
-int mmap_test(int bit)
+static int mmap_test(int bit)
{
return _mmngr_memory_map[bit / 32] & (1 << (bit % 32));
}
//
// By default, Set all of memory is in use
-void pmmngr_init ()
+static void pmmngr_init ()
{
mem_free_blocks=0;
@@ -64,9 +59,9 @@ void pmmngr_init ()
}
//find the first free bit
-int mmap_first_free ()
+static int mmap_first_free ()
{
- for (int i=0; i<mem_max_block ; i++)
+ for (int i=0; i<PMMNGR_MAP_SIZE; i++)
if (_mmngr_memory_map[i] != 0xffffffff)
for (int j=0; j<32; j++)
{
@@ -76,33 +71,38 @@ int mmap_first_free ()
return -1;
}
-void pmmngr_init_region (uint32_t base, uint32_t size)
+// work with regions
+static void pmmngr_init_region (uint32_t base, uint32_t size)
{
uint32_t align = base / PMMNGR_BLOCK_SIZE;
- uint32_t blocks = size / PMMNGR_BLOCK_SIZE;
+ uint32_t end_align = (base+size-1) / PMMNGR_BLOCK_SIZE;
+ uint32_t blocks = end_align-align+1;
for (; blocks>0; blocks--)
{
+// if(mmap_test(align))kpanic("already initialized");
mmap_unset (align++);
mem_free_blocks++;
}
}
-void pmmngr_deinit_region (uint32_t base, uint32_t size)
+static void pmmngr_deinit_region (uint32_t base, uint32_t size)
{
uint32_t align = base / PMMNGR_BLOCK_SIZE;
- uint32_t blocks = size / PMMNGR_BLOCK_SIZE;
+ uint32_t end_align = (base+size-1) / PMMNGR_BLOCK_SIZE;
+ uint32_t blocks = end_align-align+1;
if(size%PMMNGR_BLOCK_SIZE)blocks++;
for (; blocks>0; blocks--)
{
+// if(mmap_test(align))kpanic("already de-initialized");
mmap_set (align++);
mem_free_blocks--;
}
}
-void* pmmngr_alloc_block ()
+void* mem_alloc_block ()
{
int frame = mmap_first_free ();
@@ -122,7 +122,7 @@ void* pmmngr_alloc_block ()
}
-void pmmngr_free_block (void* p)
+void mem_free_block (void* p)
{
uint32_t addr = (uint32_t)(uint32_t*)p;
int frame = addr / PMMNGR_BLOCK_SIZE;
@@ -142,29 +142,33 @@ void pmmngr_free_block (void* p)
//klog("free block (%d) 0x%08X)",frame,addr);
}
+uint32_t mem_get_free_blocks_count()
+{
+ return mem_free_blocks;
+}
-// returns index of first block outside of kerel-land
+/** initialize physical memory manager */
uint32_t mem_init(multiboot_information *info)
{
+ klog("markers in kernel binary:");
+ klog("kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end);
+ klog("initial stack at: 0x%08X- 0x%08X",stack_top,stack_bottom);
+
fixme("check if kernel size does not exceed memory limits!");
- fixme("move stack");
+ fixme("communicate pages to vmmem to identity map in kernel!");
if(info->flags&&1<<6)
{
- klog("memory map of length %d provided by bootloader",info->mmap_length);
+ klog("Memory map of length %d provided by bootloader",info->mmap_length);
}
else kpanic("Unable to continue without memory map, sorry!");
- pmmngr_init (); //clear memmap
+ pmmngr_init (); //mark all memory as used
uint64_t memmap=info->mmap_addr;
uint64_t length=info->mmap_length;
- klog("kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end);
- klog("initial stack at: 0x%08X- 0x%08X",stack_top,stack_bottom);
-
- // count available mem and track high_end of usable memory
- uint32_t total_mem=0, highest_end;
+ uint32_t total_mem=0;
// iterate : print memory map, calc blocks, deinit
for(uint32_t mmap_addr=memmap;mmap_addr<memmap+length;)
@@ -182,7 +186,6 @@ uint32_t mem_init(multiboot_information *info)
if(mmap->type==1||mmap->type==3)
{
total_mem+=mem;
- highest_end=mmap->base_addr+mmap->length-1;
pmmngr_init_region(mmap->base_addr,mmap->length);
}
@@ -190,8 +193,8 @@ uint32_t mem_init(multiboot_information *info)
mmap_addr+=mmap->size+4;
}
- uint32_t blocks=highest_end/4096+1;
- mem_max_block=blocks/32+1;
+ // deinit first page (coz address=0 reserved for failure)
+ pmmngr_deinit_region(0,4096);
// deinit modules memory
if(info->flags&&1<<3)
@@ -201,8 +204,6 @@ uint32_t mem_init(multiboot_information *info)
{
klog("mod 0x%08X-0x%08X : %s",
mod->mod_start,mod->mod_end, mod->string);
-
- mem_min_block=mod->mod_end/PMMNGR_BLOCK_SIZE+1;
pmmngr_deinit_region(mod->mod_start,((uint32_t)mod->mod_end-(uint32_t)mod->mod_start)+1);
@@ -213,17 +214,8 @@ uint32_t mem_init(multiboot_information *info)
// deinitialize kernel
pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1);
- // we deinit everything below mem_min_block anyway
- //pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE);
-
- pmmngr_deinit_region(0,4096); // deinit first page (coz address=0 reserved for failure)
-
+ klog("Free 4K blocks: %d",mem_free_blocks);
klog("Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024);
- klog(
- "Free 4K blocks: %d (first free: %d)",mem_free_blocks,mem_min_block);
-
- return mem_min_block;
+ return 0;
}
-
-
diff --git a/kernel/mem.h b/kernel/mem.h
index 76d12b0..6871e11 100644
--- a/kernel/mem.h
+++ b/kernel/mem.h
@@ -1,6 +1,31 @@
+/**
+ * @file
+ *
+ * Physical Memory Manager
+ * =======================
+ *
+ * Allocating and Deallocating memory pagewise. Run mem_init() first.
+ *
+ *
+ * Memory Map
+ * ----------
+ * This will allow to mark a bit on/off for each page to indicte if it is
+ * currently used or not.
+ *
+ * Remember that we have 4096 bytes per page so we need 1048576 bits to
+ * cover the whole 32bit addressable memory 2^32 byte (4GB).
+ *
+ * This results in a 128KiB map we which allocate statically.
+ */
+
#include "multiboot.h"
-typedef uint32_t physical_address;
-physical_address* pmmngr_alloc_block ();
-void pmmngr_free_block (physical_address* p);
+
+/**
+ * Init the physical memory manager. Please provide the multiboot_information
+ * strucutre filled by your bootloader (as grub).
+ * This is required for memory map et al.
+ */
uint32_t mem_init(multiboot_information *info);
+void* mem_alloc_block ();
+void mem_free_block(void* p);
uint32_t mem_get_free_blocks_count();
diff --git a/kernel/multiboot.c b/kernel/multiboot.c
index ee84180..ada9a4e 100644
--- a/kernel/multiboot.c
+++ b/kernel/multiboot.c
@@ -1,13 +1,15 @@
#include "kernel.h"
#include "multiboot.h"
-multiboot_information* multiboot_read(uint32_t eax, uint32_t ebx)
+multiboot_information* multiboot_read(uint32_t eax, uint32_t ebx, bool silent)
{
if(eax!=0x2badb002)kpanic("EAX was not set properly by your bootlaoder!");
- klog("multiboot struct at addr: 0x%08X",ebx);
multiboot_information *info;
info=ebx;
+ if(silent) return info; // silence is golden
+
+ klog("multiboot struct at addr: 0x%08X",ebx);
klog("multiboot flags: 0x%08X",info->flags);
diff --git a/kernel/multiboot.h b/kernel/multiboot.h
index 09f7286..1c9c713 100644
--- a/kernel/multiboot.h
+++ b/kernel/multiboot.h
@@ -68,6 +68,6 @@ typedef struct multiboot_mod_struct
}multiboot_mod;
-multiboot_information* multiboot_read(uint32_t eax, uint32_t ebx);
+multiboot_information* multiboot_read(uint32_t eax, uint32_t ebx,bool silent);
#endif
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 20c6f35..0f511f4 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -232,14 +232,14 @@ volatile uint32_t task_fork(uint32_t pid)
{
//TODO: what will happen if we get rescheduled!?!?!
int ret=add_task(pid,vmem_new_space_dir(task_list[pid].vmem,false));
- klog("[%d] forked -> [%d] (free blocks remaining: %d )", pid, ret,mem_get_free_blocks_count());
+ klog("[%d] forked -> [%d] (free blocks remaining: %d )", pid, ret,0);
return ret;
}
volatile uint32_t task_clone(uint32_t pid)
{
//TODO: what will happen if we get rescheduled!?!?!
int ret=add_task(pid,vmem_new_space_dir(task_list[pid].vmem,true));
- klog("[%d] cloned -> [%d] (free blocks remaining: %d )", pid, ret,mem_get_free_blocks_count());
+ klog("[%d] cloned -> [%d] (free blocks remaining: %d )", pid, ret,0);
return ret;
}
diff --git a/kernel/smp.c b/kernel/smp.c
index 9434a47..aa1a878 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -183,8 +183,8 @@ void kernel_ap()
// this will start all our application processors!
void smp_start_aps(acpi_information *pros)
{
- fixme("how to support IPI addressing more than 16cpus?");
- // TODO: check if local APIC is present via CPUID (P6 (i686) and above)
+ fixme("how to support IPI addressing more than 16cpus?");
+ fixme("check via cpuid if apic exist?");
local_apic_addr=pros->local_apic_address;
io_apic_addr=pros->io_apic_address;
diff --git a/kernel/vmem.c b/kernel/vmem.c
index 3b5be30..ffe9a8e 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -138,7 +138,7 @@ void pd_entry_enable_global (pd_entry e)
uint8_t vmmngr_alloc_page (pt_entry* e)
{
// allocate a free physical frame
- void* p = pmmngr_alloc_block ();
+ void* p = mem_alloc_block ();
if (!p) return 0;
// map it to the page
@@ -151,7 +151,7 @@ uint8_t vmmngr_alloc_page (pt_entry* e)
void vmmngr_free_page (pt_entry* e)
{
void* p = (void*)pt_entry_pfn (*e);
- if (p) pmmngr_free_block (p);
+ if (p) mem_free_block (p);
pt_entry_del_attrib (e, I86_PTE_PRESENT);
}
@@ -186,10 +186,10 @@ void vmem_free_dir(pdirectory *dir)
for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
{
pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ];
- pmmngr_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
+ mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
}
- pmmngr_free_block(pd_entry_get_frame (entry));
+ mem_free_block(pd_entry_get_frame (entry));
virt_addr+=1024*4096;
}
@@ -205,14 +205,14 @@ void vmem_free_dir(pdirectory *dir)
for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
{
pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ];
- pmmngr_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
+ mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager
}
- pmmngr_free_block(pd_entry_get_frame (entry));
+ mem_free_block(pd_entry_get_frame (entry));
virt_addr+=1024*4096;
}
- pmmngr_free_block(dir);
+ mem_free_block(dir);
x86_paging_enable();
}
@@ -484,7 +484,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
{
//klog("i = %d",i);
- phys_addr=pmmngr_alloc_block(); // get free space from the memory manager
+ phys_addr=mem_alloc_block(); // get free space from the memory manager
if (!phys_addr)kpanic("unable to alloc spce for frame");
// if this is not init , copy contents from current space!
@@ -540,7 +540,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only)
for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096)
{
- phys_addr=pmmngr_alloc_block(); // get free space from the memory manager
+ phys_addr=mem_alloc_block(); // get free space from the memory manager
if (!phys_addr)kpanic("unable to alloc spce for frame");
// if this is not init , copy contents from current space!