Bad version (?)

This commit is contained in:
2021-09-14 19:02:20 +03:00
parent f551ca29ce
commit a58fee7200
58 changed files with 555 additions and 11189 deletions

View File

@ -21,7 +21,7 @@ string ConsoleCommands[] =
"restart",
"dir",
"cat",
"task"
"fork"
};
int32 ConsoleCommandsCount = 14;
@ -174,7 +174,7 @@ void _CommandMemPrintMemmap()
blocks = n - old;
used = 0;
for (; old < n; old++)
used += (MemPhGetBlock (old) != 0);
used += (MemPhGetFrame(old) != 0);
if (used <= blocks / 5) c = ' ';
else if (used > 4 * blocks / 5) c = 219;
@ -338,29 +338,39 @@ void CommandCat (string argv[], int32 argc)
}
#include <tasking.h>
void task()
{
Point p = {5, 1};
uint32 t = 0;
while (1)
{
ConsoleCursorGoto(p);
ConsoleWrite("Hello world! %u ", t++);
}
}
void CommandTask()
void CommandFork()
{
ConsoleClear();
TaskCreate(task);
Point p = {5, 2};
uint32 t = 0;
Point a = {5,1};
Point b = {5,2};
while (1)
// Child?
if (Fork() == 0)
{
ConsoleCursorGoto(p);
ConsoleWrite("%#Hello world! %u ", ColorLightBlue, t++);
uint32 i;
for (i = 0; i < 0x7fffffff; i++)
{
ConsoleCursorGoto(a);
ConsoleWrite ("[c] Hello %u", i);
if (i > 0x7ffffff0) i = 0;
}
for (;;);
}
// Not child?
else {
uint32 i;
for (i = 0; i < 0x7fffffff; i++)
{
ConsoleCursorGoto(b);
ConsoleWrite ("[p] world %u", i);
if (i > 0x7ffffff0) i = 0;
}
for (;;);
}
}

View File

@ -76,7 +76,7 @@ loop:
case 10: SystemReboot(); break;
case 11: CommandDir(params, count); break;
case 12: CommandCat(params, count); break;
case 13: CommandTask(); break;
case 13: CommandFork(); break;
default: ConsoleWrite ("%#! Command %#%s%# was not implemented (yet)!\n",
Color(0,ColorLightRed), Color(0,ColorWhite), params[0], Color(0,ColorLightRed)); break;

View File

@ -17,6 +17,7 @@ string LogAllowedDevices[] = {
"vfs",
//"mem",
"console",
"tasking",
0x0,
0x0
};
@ -118,9 +119,3 @@ int32 LogWrite (uint8 error, string device, string format, ...)
ConsoleCursorUpdateHardware();
return i;
}
void LogAssert (int32 condition, string file, int32 line)
{
if (!condition)
Panic("Assert", "Assertion failed in file %s line %d.\n", file, line);
}

View File

@ -29,7 +29,8 @@ void DriversInstall()
DriversInstall_Clock();
// Install fdc
Error ("Floppy", "Floppy driver is currently disabled.\n");
Error("Floppy", "Floppy driver is currently disabled.\n");
//IrqInstallHandler(6, FloppyIrqHandler);
//FloppyInitialize();
}

View File

@ -6,12 +6,14 @@
volatile TimeSystem _internal_time;
uint32 _internal_frequency_hz;
extern void TaskSwitch (_RegsStack32* regs);
extern void TaskingScheduler();
void TimeHandler(_RegsStack32* r)
void TimeHandler(_RegsStack32* UNUSED(r))
{
// Make sure it is initialised
if (_internal_frequency_hz == 0) return;
// Timer tick
_internal_time.Time += 1000/_internal_frequency_hz;
if (_internal_time.Time >= MILISECONDS_IN_DAY)
{
@ -19,5 +21,6 @@ void TimeHandler(_RegsStack32* r)
_internal_time.Time-=MILISECONDS_IN_DAY;
}
TaskSwitch(r);
// Launch scheduler
TaskingScheduler();
}

View File

@ -70,8 +70,8 @@ void CrashMessage(_RegsStack32 *r)
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
ConsoleCursorGoto(a); ConsoleWrite("ss=0x%x", r->ss);
ConsoleCursorGoto(b); ConsoleWrite("int_no=0x%x", r->int_no);
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
// Useful info about page fault

View File

@ -180,16 +180,13 @@ void luxInitrdInstall (MultibootInfo* info)
VfsInstallFs(&fs);
// Check for multiboot info flags to see if any modules are loaded
if ((info->Flags & 8) == 0) {
Error("Initrd", "No boot modules found!");
return;
}
if ((info->Flags & 8) == 0) return;
// Loop through each module and if it is an initrd image, mount it
MultibootModule* modules = (MultibootModule*) info->ModulesAddress;
for (i = 0; i < info->ModulesCount; i++)
if (*((uint32*) modules[i].ModuleStart) == LUXMAGIC)
if ((*(uint32*) modules[i].ModuleStart) == LUXMAGIC)
{
// Mount the device
Log("Initrd", "Found initrd image at 0x%x.\n", modules[i].ModuleStart);
@ -199,7 +196,4 @@ void luxInitrdInstall (MultibootInfo* info)
mp->FsData[0] = modules[i].ModuleStart;
mp->FsData[1] = modules[i].ModuleEnd;
}
else {
Log("Initrd", "Found module @ 0x%x, but not initrd image.\n", modules[i].ModuleStart);
}
}

View File

@ -34,7 +34,7 @@ void HalInitialize()
KeyboardInstallB(); Log("HAL", "%#[2/2]\n", ColorLightGreen);
// Install mouse driver
//MouseInstall(); Log("HAL", "Installed mouse driver\n");
MouseInstall(); Log("HAL", "Installed mouse driver\n");
// Install VFS
VfsInstall();

View File

@ -65,12 +65,10 @@ extern void ConsoleMain();
// External test routines
extern void SystemPanic();
extern int32 LogWrite (uint8 error, string device, string format, ...);
extern void LogAssert (int32 condition, string file, int32 line);
// Debug print
#define Log(dev, ...) { LogWrite(0, dev, __VA_ARGS__); }
#define Error(dev, ...) { LogWrite(1, dev, __VA_ARGS__); }
#define Panic(dev, ...) { LogWrite(1, dev, __VA_ARGS__); SystemPanic(); }
#define Assert(c) { LogAssert(c, __FILE__, __LINE__); }
#endif

View File

@ -33,6 +33,8 @@ enum PageFlags
PageFrame = 0xFFFFF000
};
typedef struct {
Page Pages[1024];
} PageTable;
@ -46,28 +48,28 @@ typedef struct {
extern PageDirectory* CurrentDirectory;
extern PageDirectory* KernelDirectory;
extern void PagingEnable ();
extern void PagingDisable ();
extern void PagingSwitchDirectory (PageDirectory* dir);
extern void PagingFlushTlb ();
extern void PagingInitialize (uint32* kernelEnd);
extern void PagingMapPage (uint32 phys, uint32 virt, uint32 flags, PageDirectory* pd);
extern void PagingUnmapPage (uint32 virt, PageDirectory* pd);
extern uint32 PagingGetPhysical (uint32 virt, PageDirectory* pd);
extern void PagingInitialize(volatile uint32* SystemMemory);
extern void PagingSwitchPageDirectory (PageDirectory* dir);
extern Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir);
extern void PagingCopyPagePhysical (uint32, uint32);
extern PageTable* PagingCloneTable (PageTable* src, uint32* physAddr);
extern PageDirectory* PagingCloneDirectory (PageDirectory* src);
/***************************************************
* Physical memory manager *
***************************************************/
extern uint32 TotalBlocks;
extern uint32 TotalFrames;
extern uint32 TotalMemory;
extern uint32 UsedBlocks;
extern uint32 UsedFrames;
extern void MemPhInitialize (uint32 SystemMemoryKb);
extern void MemPhSetBlock (uint32 Block, uint8 value);
extern uint32 MemPhGetBlock (uint32 Block);
extern uint32 MemPhAllocateBlock ();
extern void MemPhFreeBlock (uint32 addr);
extern void MemPhReserveBlocks (uint32 address, uint32 length);
void MemPhInitialize(uint32 SystemMemoryKb);
extern void MemPhSetFrame (uint32 frame, uint8 value);
uint32 MemPhGetFrame (uint32 frame);
uint32 MemPhFindFreeFrame();
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable);
void MemPhFreeFrame(Page* page);
void MemPhReserveFrames (uint32 address, uint32 length);
/***************************************************
@ -83,12 +85,12 @@ typedef struct
extern MemHeap* KernelHeap;
extern uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap);
extern int32 MemHeapCompare (uint32 a, uint32 b);
extern MemHeap* MemHeapCreate (uint32 start, uint32 end, uint32 max, uint8 flags);
extern uint32 MemHeapExpand (uint32 newsz, MemHeap* heap, PageDirectory* pd);
extern uint32 MemHeapContract (uint32 newsz, MemHeap* heap, PageDirectory* pd);
extern uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd);
extern void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd);
extern uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap);
extern int32 MemHeapCompare (uint32 a, uint32 b);
extern MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags);
extern void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd);
extern uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd);
extern uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd);
extern void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd);
#endif /* MEMORY_ADD_H_ */

View File

@ -32,7 +32,7 @@
// Memory manager
#define KERNEL_HEAP_START 0xC0000000
#define KERNEL_HEAP_INITIAL_SIZE 0x100000
#define KERNEL_HEAP_END (KERNEL_HEAP_START + KERNEL_HEAP_INITIAL_SIZE)
#define KERNEL_HEAP_END (KERNEL_HEAP_START + KERNEL_HEAP_INITIAL_SIZE)
#endif /* SETTINGS_H_ */

View File

@ -1,28 +1,33 @@
/*
* tasking.h
*
* Created on: Sep 8, 2011
* Created on: Sep 7, 2011
* Author: Tiberiu
*/
#ifndef TASKING_H_
#define TASKING_H_
#include <types.h>
#include <memory-add.h>
typedef struct _Task {
uint32 Pid;
uint32 Eip, Esp, Ebp;
PageDirectory* Pd;
uint32 StackLowerBase;
uint32 StackUpperBase;
uint8 Initialized;
struct _Task* Next;
typedef struct _Task{
uint32 Pid; // Process ID
uint32 Esp, Ebp, Eip; // Stack, base and instruction pointers
PageDirectory* Pd; // Page dir
struct _Task *Next; // Next task in a linked list
} Task;
extern void TaskInitialize();
extern void TaskSwitch ();
extern void TaskCreate (void (*func)());
extern void TaskingInitialize();
extern void TaskingScheduler();
extern void TaskingSwitch();
extern int32 Fork();
extern void TaskingSetInitialStack(uint32 addr);
extern void TaskingMoveStack (uint32 newstart, uint32 size);
extern int32 GetPid();
extern uint32 TaskingReadEip();
#endif /* TASKING_H_ */

View File

@ -1 +1 @@
#define OS_BUILD "0.1.1.50"
#define OS_BUILD "0.1.1.48"

View File

@ -28,7 +28,8 @@ uint32 _malloc_init2 (uint32 size, uint8 page_aligned, uint32* phys)
if (phys)
{
*phys = PagingGetPhysical(ret, KernelDirectory) + (ret & 0xFFF);
Page *pg = PagingGetPage(ret, 0, KernelDirectory);
*phys = (*pg & PageFrame) + (ret & 0xFFF);
Log("Mem","%#Allocated %u bytes (%spage aligned) at address 0x%x (phys=%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret, *phys);
}

View File

@ -6,6 +6,7 @@
*/
#include <memory-add.h>
// MemoryGetFree(), MemoryGetTotal(), MemoryGet blah blah...
// Returns total physical memory in bytes
uint32 MemoryGetTotal()
@ -16,13 +17,13 @@ uint32 MemoryGetTotal()
// Returns total free physical memory in bytes
uint32 MemoryGetFree()
{
return (TotalBlocks - UsedBlocks) * 0x4;
return (TotalFrames - UsedFrames) * 0x4;
}
// Total used physical memory in bytes
uint32 MemoryGetUsed()
{
return UsedBlocks * 0x4;
return UsedFrames * 0x4;
}
// Same as above functions, but in frames
@ -33,15 +34,15 @@ uint32 MemoryGetFrameSize()
uint32 MemoryGetFramesTotal()
{
return TotalBlocks;
return TotalFrames;
}
uint32 MemoryGetFramesUsed()
{
return UsedBlocks;
return UsedFrames;
}
uint32 MemoryGetFramesFree()
{
return (TotalBlocks - UsedBlocks);
}
return (TotalFrames - UsedFrames);
}

View File

@ -10,6 +10,7 @@
#include "../../drivers/cmos/cmos.h"
#include <stdio.h>
uint32 mem_kernel_end = 0;
uint8 mem_initialized = 0;
@ -41,7 +42,7 @@ void _memory_reserve_system(MultibootInfo* info)
while ((uint32)location < (info->MemoryMapAddress + info->MemoryMapLength))
{
if (location->Type > 1)
MemPhReserveBlocks((uint32)location->Address, (uint32)location->Length);
MemPhReserveFrames((uint32)location->Address, (uint32)location->Length);
location = (MultibootMemoryMapEntry*) ((uint32)location + location->Size + sizeof(uint32));
}
@ -52,35 +53,29 @@ void _memory_reserve_system(MultibootInfo* info)
Error("Mem", "%#Missing %#memory map%# info from bootloader.\n", ColorLightRed, ColorWhite, ColorLightRed);
// Standard memory hole at 15mb
MemPhReserveBlocks(0x00F00000, 0x00100000);
MemPhReserveFrames(0x00F00000, 0x00100000);
}
// Standard reserved memory areas
MemPhReserveFrames(0x0, 0x400 + 256); // Real mode IVT, BDA
MemPhReserveFrames(0x1000, 0x2400); // DMA buffer
MemPhReserveFrames(0x9FC00, 385*1024); // EBDA, Video memory, ROM area
}
void MemoryInitialize (MultibootInfo* info)
{
// Get total system memory
uint32 totalSystemMemory = _memory_get_total_mem(info);
// Initialize physical & virtual memory managers
uint32 end = mem_kernel_end + 0x80000;
MemPhInitialize(totalSystemMemory);
PagingInitialize(&end);
PagingInitialize((volatile uint32*)&mem_kernel_end);
// Reserve physical blocks
_memory_reserve_system(info);
uint32 i;
// Allocate some space for the kernel heap
for (i = KERNEL_HEAP_START; i <= KERNEL_HEAP_END; i += 0x1000)
PagingMapPage(MemPhAllocateBlock(), i, PageWriteable, KernelDirectory);
// Create the kernel heap
KernelHeap = MemHeapCreate(KERNEL_HEAP_START, KERNEL_HEAP_START
+ KERNEL_HEAP_INITIAL_SIZE, 0xCFFFF000, 3); // is kernel, writeable
Log("Mem", "Done initializing memory!\n");
Log("Mem", "Done initializing memory!");
mem_initialized = 2;
}
@ -89,5 +84,5 @@ void MemoryTempInitialize (uint32 kernel_end)
{
mem_initialized = 1;
mem_kernel_end = kernel_end;
Log("Mem", "Initialized temporary memory manager, allocating from %#0x%x.\n", ColorWhite, mem_kernel_end);
Log("Mem", "Initialized temporary memory manager, allocating from %#0x%x.\n", kernel_end);
}

View File

@ -39,9 +39,6 @@ start:
extern k_main
call k_main
cli
hlt
; Show error message, and halt system
.bad:

View File

@ -12,8 +12,10 @@ extern uint32 _end;
extern void luxInitrdInstall (MultibootInfo* info);
void k_main(MultibootInfo* info)
void k_main(MultibootInfo* info, uint32 initial_stack)
{
TaskingSetInitialStack(initial_stack);
uint32 KernelEnd = (uint32)&_end;
// Find kernel's end
@ -30,7 +32,7 @@ void k_main(MultibootInfo* info)
MemoryTempInitialize(KernelEnd);
MemoryInitialize(info);
TaskInitialize();
TaskingInitialize();
HalInitialize();
luxInitrdInstall(info);

View File

@ -6,6 +6,9 @@
#define MEMHEAP_INDEX_SIZE 0x20000
#define MEMHEAP_MINIM_SIZE 0x70000
#define FlagsKernel 1
#define FlagsWriteable 2
typedef struct
{
uint32 Magic;
@ -95,31 +98,30 @@ MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags)
}
uint32 MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
{
if (newsz <= heap->EndAddress - heap->StartAddress) return heap->EndAddress - heap->StartAddress;
if (newsz <= heap->EndAddress - heap->StartAddress) return;
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000;
if (newsz + heap->StartAddress >= heap->MaxAddress) return heap->EndAddress - heap->StartAddress;
if (newsz + heap->StartAddress >= heap->MaxAddress) return;
uint32 i;
for (i = heap->EndAddress; i < heap->StartAddress + newsz; i+=0x1000)
PagingMapPage(MemPhAllocateBlock(), i, heap->Flags, pd);
for (i = heap->EndAddress - heap->StartAddress; i < heap->StartAddress + newsz; i+=0x1000)
MemPhAllocFrame(PagingGetPage(i, 1, pd), heap->Flags & FlagsKernel, heap->Flags & FlagsWriteable);
heap->EndAddress = heap->StartAddress + newsz;
return newsz;
}
uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd)
{
if (newsz >= heap->EndAddress - heap->StartAddress) return heap->EndAddress - heap->StartAddress;
if (newsz >= heap->EndAddress - heap->StartAddress) return 0;
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000; // page align
newsz = Max(newsz, MEMHEAP_MINIM_SIZE);
uint32 i;
for (i = heap->EndAddress - 0x1000; i > heap->StartAddress + newsz; i-=0x1000)
PagingUnmapPage(i, pd);
for (i = heap->EndAddress - heap->StartAddress - 0x1000; i > newsz; i-=0x1000)
MemPhFreeFrame(PagingGetPage(i, 0, pd));
heap->EndAddress = heap->StartAddress + newsz;
return newsz;

View File

@ -6,123 +6,132 @@
*/
#include <memory-add.h>
#include <stdio.h>
/*******************************
* Data *
*******************************/
PageDirectory* CurrentDirectory;
PageDirectory* KernelDirectory;
void PagingEnable()
/*******************************
* Useful routines *
*******************************/
void PagingInitialize(volatile uint32* kernel_used)
{
uint32 tmp;
asm volatile ("mov %%cr0, %0" : "=r"(tmp));
tmp |= 0x80000000;
asm volatile ("mov %0, %%cr0" : : "r"(tmp));
Log("Mem", "Virtual memory manager initialization started. End of kernel = 0x%x\n", kernel_used);
PageDirectory* kernelPd = (PageDirectory*) kmalloc_a(sizeof(PageDirectory));
memset(kernelPd, 0, sizeof(PageDirectory));
kernelPd->PhysicalAddr = (uint32)kernelPd->TablesPhysical;
KernelDirectory = kernelPd;
uint32 i;
// Map some kernel space
for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
PagingGetPage(i, 1, kernelPd);
// Identity map
for (i = 0; i < (volatile uint32) kernel_used + 0x1000; i+=0x1000)
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0);
// Allocate kernel space
for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
MemPhAllocFrame (PagingGetPage(i, 1, kernelPd), 0, 0);
PagingSwitchPageDirectory (kernelPd);
PageDirectory* temp = PagingCloneDirectory(kernelPd);
PagingSwitchPageDirectory (temp);
}
void PagingDisable()
{
uint32 tmp;
asm volatile ("mov %%cr0, %0" : "=r"(tmp));
tmp &= 0x7FFFFFFF;
asm volatile ("mov %0, %%cr0" : : "r"(tmp));
}
void PagingSwitchDirectory(PageDirectory* dir)
void PagingSwitchPageDirectory (PageDirectory* dir)
{
CurrentDirectory = dir;
asm volatile ("mov %0, %%cr3" : : "r"(dir->PhysicalAddr));
asm volatile ("mov %0, %%cr3":: "r"(dir->PhysicalAddr));
// Enable paging
uint32 cr0;
asm volatile ("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000;
asm volatile ("mov %0, %%cr0":: "r"(cr0));
Log("Mem", "Enabled paging.\n");
}
void PagingFlushTlb ()
Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir)
{
uint32 tmp;
asm volatile ("mov %%cr3, %0" : "=r"(tmp));
asm volatile ("mov %0, %%cr3" : : "r" (tmp));
}
addr >>= 12;
void PagingInitialize(uint32* kernelEnd)
{
// Create the kernel page directory
PageDirectory* kdir = kmalloc_a(sizeof(PageDirectory));
memset(kdir, 0, sizeof(PageDirectory));
uint32 tableIndex = addr >> 10;
KernelDirectory = kdir;
if (dir->Tables[tableIndex])
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
// Set up physical address of PDEs.
kdir->PhysicalAddr = (uint32) kdir->TablesPhysical;
// Identity map the kernel
uint32 i = 0;
while (i <= *kernelEnd + 1024)
else if (make)
{
PagingMapPage(i, i, PageWriteable, kdir);
i += 0x1000;
uint32 temp;
dir->Tables[tableIndex] = (PageTable*)kmalloc_ap(sizeof(PageTable), &temp);
memset (dir->Tables[tableIndex], 0, 0x1000);
dir->TablesPhysical[tableIndex] = temp | 0x7;
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
}
// Reserve the identity mapped blocks
MemPhReserveBlocks(0x0, *kernelEnd);
PagingSwitchDirectory(kdir);
PagingEnable();
else return 0;
}
void PagingMapPage (uint32 phys, uint32 virt, uint32 flags, PageDirectory* pd)
PageTable* PagingCloneTable (PageTable* src, uint32* physAddr)
{
// Calculate pde and pte
uint32 pde = virt >> 22;
uint32 pte = (virt >> 12) & 0x3ff;
PageTable* tab = (PageTable*) kmalloc_ap(sizeof(PageTable), physAddr);
memset (tab, 0, sizeof(PageTable));
phys &= 0xFFFFF000; // Make sure address is page aligned
flags &= 0xFFF; // Make sure flags don't overflow
// See if page table exists
if (!pd->Tables[pde])
uint32 i;
for (i=0; i<1024; i++)
{
// No? allocate it
uint32 ph;
PageTable* pt = kmalloc_ap(sizeof(PageTable), &ph);
memset(pt, 0, sizeof(PageTable));
if (!(src->Pages[i] & PageFrame)) continue;
MemPhAllocFrame(&tab->Pages[i], 1, 0);
pd->Tables[pde] = pt;
pd->TablesPhysical[pde] = ph | 0x7;
if (src->Pages[i] & PagePresent) tab->Pages[i] |= PagePresent;
if (src->Pages[i] & PageWriteable) tab->Pages[i] |= PageWriteable;
if (src->Pages[i] & PageUser) tab->Pages[i] |= PageUser;
if (src->Pages[i] & PageAccessed) tab->Pages[i] |= PageAccessed;
if (src->Pages[i] & PageDirty) tab->Pages[i] |= PageDirty;
PagingCopyPagePhysical (src->Pages[i] & PageFrame, tab->Pages[i] & PageFrame);
}
// Set up the page
pd->Tables[pde]->Pages[pte] = phys | flags | 0x1; // Present, and flags
// If it is the current directory, flush the tlb to notice the change
if (pd == CurrentDirectory) PagingFlushTlb();
return tab;
}
void PagingUnmapPage (uint32 virt, PageDirectory* pd)
PageDirectory* PagingCloneDirectory (PageDirectory* src)
{
// Calculate pde and pte
uint32 pde = virt >> 22;
uint32 pte = (virt >> 12) & 0x3ff;
uint32 phys;
PageDirectory* dir = (PageDirectory*)kmalloc_ap(sizeof(PageDirectory), &phys);
if (!pd->Tables[pde] || !pd->Tables[pde]->Pages[pte]) return;
memset(dir, 0, sizeof(PageDirectory));
// Get physical address
uint32 phys = pd->Tables[pde]->Pages[pte] & PageFrame;
uint32 offset = (uint32)dir->TablesPhysical - (uint32)dir;
dir->PhysicalAddr = phys + offset;
// Free page
pd->Tables[pde]->Pages[pte] = 0;
MemPhFreeBlock(phys);
uint32 i;
for (i = 0; i < 1024; i++)
{
if (!src->Tables[i]) continue;
// If it is the current directory, flush the tlb to notice the change
if (pd == CurrentDirectory) PagingFlushTlb();
}
uint32 PagingGetPhysical (uint32 virt, PageDirectory* pd)
{
// Calculate pde and pte
uint32 pde = virt >> 22;
uint32 pte = (virt >> 12) & 0x3ff;
// Not mapped
if (!pd->Tables[pde] || !pd->Tables[pde]->Pages[pte]) return NULL;
return (pd->Tables[pde]->Pages[pte] & PageFrame);
if (KernelDirectory->Tables[i] == src->Tables[i])
{
// It is in the kernel, link it
dir->Tables[i] = src->Tables[i];
dir->TablesPhysical[i] = src->TablesPhysical[i];
}
else
{
// Copy the table
uint32 ph;
dir->Tables[i] = PagingCloneTable (src->Tables[i], &ph);
dir->TablesPhysical[i] = ph | 0x7;
}
}
return dir;
}

View File

@ -6,89 +6,103 @@
*/
#include <memory-add.h>
uint32* BlockMap;
uint32 TotalBlocks;
uint32* FrameMap;
uint32 TotalFrames;
uint32 TotalMemory;
uint32 UsedBlocks;
uint32 UsedFrames;
inline void ConvertIndexToBlock (uint32 index, uint32* address, uint32* offset)
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
{
*address = (index >> 5);
*offset = index & 0x1f;
}
inline uint32 ConvertBlockToIndex (uint32 address, uint32 offset)
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
{
return (address<<5) | offset;
}
void MemPhSetBlock (uint32 Block, uint8 value)
void MemPhSetFrame (uint32 frame, uint8 value)
{
uint32 addr, off;
ConvertIndexToBlock(Block, &addr, &off);
ConvertIndexToFrame(frame, &addr, &off);
if (value) {
if ((BlockMap[addr] & (1<<off)) == 0) UsedBlocks++;
BlockMap[addr] |= 1<<off;
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
FrameMap[addr] |= 1<<off;
}
else {
if (BlockMap[addr] & (1<<off)) UsedBlocks--;
BlockMap[addr] &= ~(1<<off);
if (FrameMap[addr] & (1<<off)) UsedFrames--;
FrameMap[addr] &= ~(1<<off);
}
}
uint32 MemPhGetBlock (uint32 Block)
uint32 MemPhGetFrame (uint32 frame)
{
uint32 addr, off;
ConvertIndexToBlock(Block, &addr, &off);
ConvertIndexToFrame(frame, &addr, &off);
return BlockMap[addr] & (1<<off);
return FrameMap[addr] & (1<<off);
}
uint32 MemPhAllocateBlock()
uint32 MemPhFindFreeFrame()
{
uint32 addr, pos;
for (addr = 0; addr < TotalBlocks >> 5; addr++)
if (BlockMap[addr] != 0xffffffff)
for (addr = 0; addr < TotalFrames >> 5; addr++)
if (FrameMap[addr] != 0xffffffff)
{
for (pos = 0; (BlockMap[addr] & (1<<pos)) != 0; pos++) ;
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
uint32 index = ConvertBlockToIndex(addr, pos);
MemPhSetBlock(index, 1);
// Return address
return (index<<12);
return ConvertFrameToIndex(addr, pos);
}
return 0xffffffff;
}
void MemPhFreeBlock(uint32 addr)
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
{
uint32 Block = addr >> 12;
if (!Block) return;
if ((*page & PageFrame) != 0) return;
MemPhSetBlock(Block, 0);
uint32 free = MemPhFindFreeFrame();
if (free == 0xffffffff) {
Panic("Mem", "%#Failed allocation free=0x%x page=0x%x\n", ColorRed, free, *page);
return;
}
MemPhSetFrame(free, 1);
*page |= PagePresent;
*page |= (isKernel) ? 0 : PageUser;
*page |= (isWriteable) ? PageWriteable : 0;
*page |= (free<<12) & PageFrame;
}
void MemPhFreeFrame(Page* page)
{
uint32 frame = *page & PageFrame;
if (!frame) return;
MemPhSetFrame(frame, 0);
*page &= ~PageFrame;
}
void MemPhInitialize(uint32 SystemMemoryKb)
{
TotalBlocks = SystemMemoryKb >> 2;
TotalFrames = SystemMemoryKb >> 2;
TotalMemory = SystemMemoryKb;
BlockMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalBlocks>>5)));
memset(BlockMap, 0, sizeof(uint32) * (1 + (TotalBlocks>>5)));
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
Log("Mem", "%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
}
void MemPhReserveBlocks (uint32 address, uint32 length)
void MemPhReserveFrames (uint32 address, uint32 length)
{
address >>= 12;
length = (length>>12) + ((length & 0xfff) > 0);
uint32 end = address + length;
for (; address < end ; address++)
MemPhSetBlock(address, 1);
MemPhSetFrame(address, 1);
}

View File

@ -1,7 +1,49 @@
; tasking.asm
;
; tasking-asm.asm
;
; Created on: Sep 6, 2011
; Author: Tiberiu
;
bits 32
global TaskReadEip
TaskReadEip:
global PagingCopyPagePhysical
PagingCopyPagePhysical:
push ebx
pushf
cli
mov ebx, [esp+12]
mov ecx, [esp+16]
; Disable paging
mov edx, cr0
and edx, 0x7fffffff
mov cr0, edx
; copy
mov edx, 1024
.loop:
mov eax, [ebx]
mov [ecx], eax
add ebx, 4
add ecx, 4
dec edx
jnz .loop
; reenable paging
mov edx, cr0
or edx, 0x80000000
mov cr0, edx
; return
popf
pop ebx
ret
global TaskingReadEip
TaskingReadEip:
pop eax
jmp eax

View File

@ -1,107 +1,141 @@
/*
* tasking-multi.c
*
* Created on: Sep 8, 2011
* Created on: Sep 7, 2011
* Author: Tiberiu
*/
#include <tasking.h>
#include <memory-add.h>
#include <debugio.h>
#include <stdio.h>
Task* TaskList;
Task* CurrentTask;
uint32 NextPid = 1;
volatile Task *CurrentTask;
volatile Task *TaskQueue;
volatile uint32 NextPid = 1;
void TaskSwitch (_RegsStack32* regs)
void TaskingInitialize()
{
MagicBreakpoint();
// Stop interrupts
asm volatile ("cli");
if (!TaskList) return;
// Relocate stack
TaskingMoveStack(0xE0000000, 0x4000);
uint32 eip = TaskReadEip();
if (eip == 0xABCDEF) return;
// Set up first task (kernel)
CurrentTask = TaskQueue = (Task*) kmalloc(sizeof(Task));
CurrentTask->Pid = NextPid ++;
CurrentTask->Esp = CurrentTask->Ebp = CurrentTask->Eip = 0;
CurrentTask->Pd = CurrentDirectory;
CurrentTask->Next = NULL;
// Save context
asm volatile ("mov %%esp, %0" : "=r"(CurrentTask->Esp));
asm volatile ("mov %%ebp, %0" : "=r"(CurrentTask->Ebp));
CurrentTask->Eip = eip;
// Reenable interrupts
asm volatile ("sti");
// Next task
CurrentTask = (!CurrentTask->Next) ? TaskList : CurrentTask->Next ;
// Switch context
PagingSwitchDirectory(CurrentTask->Pd);
// Prepare for jump
asm volatile (""
"mov %0, %%ebp; "
"mov %1, %%esp; "
"mov %2, %%ecx; "
"mov $0xABCDEF, %%eax; "
"jmp *%%ecx; "
: : "r"(CurrentTask->Ebp), "r"(CurrentTask->Esp), "r"(CurrentTask->Eip)
: "eax", "ecx");
Log("Tasking", "Initialized, currenttask: pid=%u esp=%x ebp=%x eip=%x Pd=%x Next=%x\n", CurrentTask->Pid,
CurrentTask->Esp, CurrentTask->Ebp, CurrentTask->Eip, CurrentTask->Pd, CurrentTask->Next);
}
// Fallback for new tasks
void TaskEnd ()
int32 Fork()
{
// Find parent of current task
if (CurrentTask->Pid == TaskList->Pid) TaskList = TaskList->Next;
asm volatile ("cli");
else {
Task* t = TaskList;
while (t->Next && t->Next->Pid != CurrentTask->Pid) t = t->Next;
Task* Parent = (Task*) CurrentTask;
PageDirectory* Dir = PagingCloneDirectory(CurrentDirectory);
t->Next = CurrentTask->Next;
// Create a new process
Task* n = (Task*)kmalloc(sizeof(Task));
n->Pid = NextPid++;
n->Esp = n->Ebp = 0;
n->Eip = 0;
n->Pd = Dir;
n->Next = 0;
// Add it at the end of the queue
Task* temp = (Task*) TaskQueue;
while (temp->Next) temp = temp->Next; // Find end of queue
temp->Next = n; // Add it
// Read eip
uint32 eip = TaskingReadEip();
// We could be the parent
if (CurrentTask == Parent)
{
uint32 esp, ebp;
asm volatile ("mov %%esp, %0" : "=r"(esp));
asm volatile ("mov %%ebp, %0" : "=r"(ebp));
n->Esp = esp;
n->Ebp = ebp;
n->Eip = eip;
asm volatile ("sti");
return n->Pid;
}
// Free allocated space
kfree((void*)CurrentTask->StackLowerBase);
kfree(CurrentTask);
// Wait for next task
for (;;) ;
// Or the child
else return 0;
}
void TaskCreate (void (*func)())
void TaskingScheduler()
{
// Create a new task
Task* t = kmalloc(sizeof(Task));
// Set up data
t->StackLowerBase = (uint32) kmalloc(0x1000); // Allocate some space for new stack
t->StackUpperBase = t->StackLowerBase + 0x1000;
t->Next = NULL;
t->Pd = KernelDirectory;
t->Pid = NextPid++;
// Set up stack
/*memset(&t->Regs, 0, sizeof(_RegsStack32));
t->Regs.ebp = t->StackUpperBase;
t->Regs.esp = (t->StackUpperBase - 0x4 - sizeof(_RegsStack32));
t->Regs.useresp = t->StackUpperBase - 0x4;
t->Regs.eip = (uint32) func;
*(uint32 *) (t->Regs.esp) = (uint32) TaskEnd; // Fallback function
t->Initialized = 0;
// Read eflags
asm volatile ("pushf; pop %0" : "=r"(t->Regs.eflags));*/
// Add the task to the list
Task* last = TaskList;
while (last && last->Next) last = last->Next;
if (last) last->Next = t;
// For now, just switch tasks
TaskingSwitch();
}
void TaskInitialize()
void Func()
{
Task* t = kmalloc(sizeof(Task));
t->Pid = NextPid++;
t->Pd = KernelDirectory;
t->Next = NULL;
TaskList = CurrentTask = t;
}
void TaskingSwitch()
{
// Make sure tasking is initialized, or there are at least 2 processes running
if (!CurrentTask) return;
// Save esp & epb
uint32 esp, ebp, eip;
asm volatile("mov %%esp, %0" : "=r"(esp));
asm volatile("mov %%ebp, %0" : "=r"(ebp));
eip = TaskingReadEip();
// Have we just switched tasks?
if (eip == 0xABCDE) return;
// No? Switch
// Save stack address and current instruction pointer
CurrentTask->Eip = eip;
CurrentTask->Esp = esp;
CurrentTask->Ebp = ebp;
//Log("Tasking", "Saved eip=%x esp=%x ebp=%x\n", eip, esp, ebp);
CurrentTask = CurrentTask ->Next; // Switch task
if (!CurrentTask) CurrentTask = TaskQueue; // End of queue? Start over
// Read registers
eip = CurrentTask->Eip;
esp = CurrentTask->Esp;
ebp = CurrentTask->Ebp;
//Log("Tasking", "Loaded eip=%x esp=%x ebp=%x", eip, esp, ebp);
CurrentDirectory = CurrentTask->Pd;
MagicBreakpoint();
// Put data in registers
asm volatile (" "
"cli;"
"mov %0, %%ecx;"
"mov %1, %%esp;"
"mov %2, %%ebp;"
"mov %3, %%cr3;"
"mov $0xABCDE, %%eax;"
"sti;"
"jmp *%%ecx"
: : "r"(eip), "r"(esp), "r"(ebp), "r"(CurrentDirectory->PhysicalAddr));
}
int32 GetPid()
{
return CurrentTask->Pid;
}

View File

@ -0,0 +1,51 @@
/*
* tasking-stack.c
*
* Created on: Sep 7, 2011
* Author: Tiberiu
*/
#include <memory-add.h>
uint32 InitialStack;
void TaskingSetInitialStack(uint32 addr)
{
InitialStack = addr;
}
void TaskingMoveStack (uint32 newstart, uint32 size)
{
uint32 i;
for (i = newstart; i >= newstart-size; i-= 0x1000)
MemPhAllocFrame(PagingGetPage(i, 1, CurrentDirectory), 0, 1);
// Flush TLB by rewriting cr3
uint32 t;
asm volatile ("mov %%cr3, %0" : "=r" (t));
asm volatile ("mov %0, %%cr3" : : "r" (t));
// Read old esp, ebp regs
uint32 oldStackPointer, oldBasePointer;
asm volatile ("mov %%esp, %0" : "=r"(oldStackPointer));
asm volatile ("mov %%ebp, %0" : "=r"(oldBasePointer));
uint32 offset = newstart - InitialStack;
uint32 newStackPointer = oldStackPointer + offset;
uint32 newBasePointer = oldBasePointer + offset;
// Copy stack content
memcpy((void*)newStackPointer, (void*)oldStackPointer, InitialStack-oldStackPointer);
// (Attempt to) change EBP addresses in new stack
for (i = newstart; i > newstart - size; i-=4)
{
uint32 *temp = (uint32*)i;
if (oldStackPointer < *temp && *temp < InitialStack)
*temp += offset;
}
// Set stack pointers to new stack
asm volatile ("mov %0, %%esp" : : "r" (newStackPointer));
asm volatile ("mov %0, %%ebp" : : "r" (newBasePointer));
}