[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
255
Kernel/debug/commands.c
Normal file
255
Kernel/debug/commands.c
Normal file
@@ -0,0 +1,255 @@
|
||||
#include <debugio.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <memory-add.h>
|
||||
#include "../hal/mouse/mouse.h"
|
||||
#include "../drivers/floppy/floppy.h"
|
||||
|
||||
string ConsoleCommands[] =
|
||||
{
|
||||
"osver",
|
||||
"time",
|
||||
"cls",
|
||||
"help",
|
||||
"dump",
|
||||
"mem",
|
||||
"crash",
|
||||
"mouse",
|
||||
"read",
|
||||
"reboot",
|
||||
"restart",
|
||||
};
|
||||
|
||||
int32 ConsoleCommandsCount = 11;
|
||||
|
||||
/*****************************************
|
||||
* osver - get os info *
|
||||
*****************************************/
|
||||
void CommandOsver()
|
||||
{
|
||||
ConsoleWrite ("%#%s%# 32bit operating system\n", Color(0,ColorYellow), OS_STRING, Color(0,ColorLightGray));
|
||||
|
||||
int32 i = 0;
|
||||
for (i = 0; i < 30; i++)
|
||||
ConsoleWrite ("%#%c", ColorDarkGray, 205);
|
||||
|
||||
ConsoleWrite ("\n%#OS version: %#%s\n", ColorDarkGray, ColorLightGray, OS_VERSION);
|
||||
ConsoleWrite ("%#Build: %#%s ", ColorDarkGray, ColorLightGray, OS_BUILD);
|
||||
ConsoleWrite ("%#built on %#%s %#at %#%s\n", ColorDarkGray, ColorLightGray, OS_BUILD_DATE, ColorDarkGray, ColorLightGray, OS_BUILD_TIME);
|
||||
ConsoleWrite ("%#(c) Copyright %#CTA Systems Inc.\n", ColorDarkGray ,ColorLightGray);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* time - get date and time *
|
||||
*****************************************/
|
||||
void CommandTime()
|
||||
{
|
||||
const char* Months[] = {
|
||||
"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
||||
};
|
||||
|
||||
const char* Weekdays[] = {
|
||||
"", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
|
||||
};
|
||||
|
||||
|
||||
Time time = TimeConvertToTime(TimeGetInternalTime());
|
||||
|
||||
ConsoleWrite ("Current time: ");
|
||||
ConsoleWrite ("%#%d:%d%d:%d%d.%d%d%d\n", Color(0,ColorLightGreen) ,(int)time.Hour,
|
||||
time.Minute/10, time.Minute%10, time.Second/10, time.Second%10, time.Milisecond/100, (time.Milisecond/10)%10, time.Milisecond%10);
|
||||
|
||||
ConsoleWrite ("Date: %#%s, %s %d, %d\n", Color(0,ColorLightGreen), Weekdays[time.WeekDay],
|
||||
Months[time.Month], time.Day, time.Year);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* help - help provider *
|
||||
*****************************************/
|
||||
void CommandHelp(string params[], int32 count)
|
||||
{
|
||||
if (count <= 1)
|
||||
{
|
||||
ConsoleWrite ("Available commands:\n");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ConsoleCommandsCount; i++)
|
||||
ConsoleWrite(" > %#%s\n", Color(0,ColorWhite), ConsoleCommands[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleWrite("%#! Help for %s command is not implemented yet.\n", Color(0,ColorLightRed), params[1]);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* dump - dumps memory content *
|
||||
*****************************************/
|
||||
inline char hex (int32 digit)
|
||||
{
|
||||
return (digit < 10) ? (digit + '0') : (digit - 10 + 'A');
|
||||
}
|
||||
|
||||
void CommandDump (string argv[], int32 argc)
|
||||
{
|
||||
unsigned pause = 1, i = 0;
|
||||
|
||||
// Verify correct number of arguments
|
||||
if (argc < 3) {
|
||||
ConsoleWrite("%#! Correct syntax: %#dump %#[start_address] [end_address]\n",
|
||||
ColorLightRed, ColorWhite, ColorLightGray);
|
||||
ConsoleWrite("%#Start %#and %#end %#addresses are in hex.\n",
|
||||
ColorLightGray, ColorDarkGray, ColorLightGray, ColorDarkGray);
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable pause
|
||||
if (argc==4 && strcmp(argv[3], "!p") == 0)
|
||||
pause = 0;
|
||||
|
||||
// Dump memory
|
||||
unsigned char *start, *end;
|
||||
start = (unsigned char *) ConvertStringToIntHex(argv[1]);
|
||||
end = (unsigned char *) ConvertStringToIntHex(argv[2]);
|
||||
unsigned char* count;
|
||||
|
||||
while (start <= end) {
|
||||
// Write address
|
||||
ConsoleWrite("%#%x%#: ", Color(0,ColorLightMagenta), (unsigned int)start, Color(0,ColorLightGray));
|
||||
|
||||
// Write hex data
|
||||
for (count = start; count < start+16; count++) {
|
||||
if (*count == 0) ConsoleWrite ("%#00 ", Color(0,ColorDarkGray));
|
||||
else ConsoleWrite ("%#%c%c ", Color(0,ColorWhite), hex(*count/16), hex(*count%16));
|
||||
}
|
||||
|
||||
// Write ASCII data
|
||||
ConsoleWrite(" ");
|
||||
for (count = start; count < start+16; count++) {
|
||||
if (*count < 32) ConsoleWrite(".");
|
||||
else ConsoleWrite("%#%c", Color(0,ColorLightGreen), *count);
|
||||
}
|
||||
|
||||
// New line
|
||||
ConsoleWrite("\n\r");
|
||||
start+=16; i++;
|
||||
|
||||
// Pause
|
||||
if ((i%22 == 0) && (pause==1)) {
|
||||
ConsoleWrite("\n\r%#Press %#any key %#to continue scrolling, %#Esc %#to exit.",
|
||||
0x8, 0x7, 0x8, 0x7, 0x8);
|
||||
Key k = ReadKey();
|
||||
if (k.Scancode == KeyboardKeyEscape) return;
|
||||
ConsoleWrite("\n\n\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define _CommandMemTotalRows 10
|
||||
void _CommandMemPrintMemmap()
|
||||
{
|
||||
uint8 color = Color(ColorGreen, ColorRed);
|
||||
uint32 total = MemoryGetFramesTotal();
|
||||
|
||||
char c = ' ';
|
||||
|
||||
// Print memory map
|
||||
int32 i, old = 0, n = 0, blocks, used;
|
||||
for (i = 0; i < 80; i++)
|
||||
ConsoleWrite("%#%c", ColorLightGray, 220);
|
||||
|
||||
for (i = 1; i <= 80*_CommandMemTotalRows; i++, old++)
|
||||
{
|
||||
n = (total * i) / (80 * _CommandMemTotalRows);
|
||||
|
||||
blocks = n - old;
|
||||
used = 0;
|
||||
for (; old < n; old++)
|
||||
used += (MemPhGetFrame(old) != 0);
|
||||
|
||||
if (used <= blocks / 5) c = ' ';
|
||||
else if (used > 4 * blocks / 5) c = 219;
|
||||
else if (used <= 2 * blocks / 5) c = 176;
|
||||
else if (used <= 3 * blocks / 5) c = 177;
|
||||
else c = 178;
|
||||
|
||||
ConsoleWrite("%#%c", color, c);
|
||||
}
|
||||
|
||||
for (i = 0; i < 80; i++)
|
||||
ConsoleWrite("%#%c", ColorDarkGray, 223);
|
||||
}
|
||||
|
||||
void CommandMem (string argv[], int32 argc)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
ConsoleWrite ("Physical memory map:\n");
|
||||
|
||||
_CommandMemPrintMemmap();
|
||||
|
||||
ConsoleWrite ("Free space: %#%ukb (%u frames)\n", ColorLightMagenta, MemoryGetFree(), MemoryGetFramesFree());
|
||||
ConsoleWrite ("Used space: %#%ukb (%u frames)\n\n", ColorLightMagenta, MemoryGetUsed(), MemoryGetFramesUsed());
|
||||
ConsoleWrite ("Total space: %#%ukb (%u frames)\n", ColorLightMagenta, MemoryGetTotal(), MemoryGetFramesTotal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "alloc") == 0)
|
||||
{
|
||||
uint32 addr = 0;
|
||||
if (argc < 3) addr = (uint32)kmalloc(0x4);
|
||||
else addr = (uint32)kmalloc(ConvertStringToUInt(argv[2]));
|
||||
|
||||
ConsoleWrite("Returned address: %#0x%x\n", ColorWhite, addr);
|
||||
}
|
||||
|
||||
else if (strcmp(argv[1], "free") == 0)
|
||||
{
|
||||
if (argc < 3) {
|
||||
ConsoleWrite ("%#! Missing parameter: address to free.", ColorRed);
|
||||
return;
|
||||
}
|
||||
|
||||
kfree((void*)ConvertStringToIntHex(argv[2]));
|
||||
ConsoleWrite("Done.\n");
|
||||
}
|
||||
|
||||
else ConsoleWrite("%#! Invalid command. Available commands are: alloc, free.", ColorLightRed);
|
||||
}
|
||||
|
||||
void CommandCrash()
|
||||
{
|
||||
int a = 10, b = 0;
|
||||
ConsoleWrite ("%d", a/b);
|
||||
}
|
||||
|
||||
void CommandMouse()
|
||||
{
|
||||
MouseState s = MouseGetState();
|
||||
ConsoleWrite("X=%d Y=%d Buttons=", s.Position.X, s.Position.Y);
|
||||
|
||||
if (!s.Buttons) ConsoleWrite("<none>");
|
||||
if (s.Buttons & 1) ConsoleWrite("<left>");
|
||||
if (s.Buttons & 2) ConsoleWrite("<right>");
|
||||
if (s.Buttons & 4) ConsoleWrite("<mid>");
|
||||
|
||||
ConsoleWrite("\n");
|
||||
}
|
||||
|
||||
void CommandRead(string argv[], int32 argc)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
ConsoleWrite("%#! Missing parameter - sector!\n", ColorLightRed);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 sector = ConvertStringToUInt(argv[1]);
|
||||
ConsoleWrite("Returned value: 0x%x\n", FloppyRead(0, sector));
|
||||
}
|
||||
255
Kernel/debug/commands.c~
Normal file
255
Kernel/debug/commands.c~
Normal file
@@ -0,0 +1,255 @@
|
||||
#include <debugio.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <memory-add.h>
|
||||
#include "../hal/mouse/mouse.h"
|
||||
#include "../drivers/floppy/floppy.h"
|
||||
|
||||
string ConsoleCommands[] =
|
||||
{
|
||||
"osver",
|
||||
"time",
|
||||
"cls",
|
||||
"help",
|
||||
"dump",
|
||||
"mem",
|
||||
"crash",
|
||||
"mouse",
|
||||
"read",
|
||||
"reboot",
|
||||
"restart",
|
||||
};
|
||||
|
||||
int32 ConsoleCommandsCount = 11;
|
||||
|
||||
/*****************************************
|
||||
* osver - get os info *
|
||||
*****************************************/
|
||||
void CommandOsver()
|
||||
{
|
||||
ConsoleWrite ("%#%s%# 32bit operating system\n", Color(0,ColorYellow), OS_STRING, Color(0,ColorLightGray));
|
||||
|
||||
int32 i = 0;
|
||||
for (i = 0; i < 30; i++)
|
||||
ConsoleWrite ("%#%c", ColorDarkGray, 205);
|
||||
|
||||
ConsoleWrite ("\n%#OS version: %#%s\n", ColorDarkGray, ColorLightGray, OS_VERSION);
|
||||
ConsoleWrite ("%#Build: %#%s ", ColorDarkGray, ColorLightGray, OS_BUILD);
|
||||
ConsoleWrite ("%#built on %#%s %#at %#%s\n", ColorDarkGray, ColorLightGray, OS_BUILD_DATE, ColorDarkGray, ColorLightGray, OS_BUILD_TIME);
|
||||
ConsoleWrite ("%#(c) Copyright %#CTA Systems Inc.\n", ColorDarkGray ,ColorLightGray);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* time - get date and time *
|
||||
*****************************************/
|
||||
void CommandTime()
|
||||
{
|
||||
const char* Months[] = {
|
||||
"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
||||
};
|
||||
|
||||
const char* Weekdays[] = {
|
||||
"", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
|
||||
};
|
||||
|
||||
|
||||
Time time = TimeConvertToTime(TimeGetInternalTime());
|
||||
|
||||
ConsoleWrite ("Current time: ");
|
||||
ConsoleWrite ("%#%d:%d%d:%d%d.%d%d%d\n", Color(0,ColorLightGreen) ,(int)time.Hour,
|
||||
time.Minute/10, time.Minute%10, time.Second/10, time.Second%10, time.Milisecond/100, (time.Milisecond/10)%10, time.Milisecond%10);
|
||||
|
||||
ConsoleWrite ("Date: %#%s, %s %d, %d\n", Color(0,ColorLightGreen), Weekdays[time.WeekDay],
|
||||
Months[time.Month], time.Day, time.Year);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* help - help provider *
|
||||
*****************************************/
|
||||
void CommandHelp(string params[], int32 count)
|
||||
{
|
||||
if (count <= 1)
|
||||
{
|
||||
ConsoleWrite ("Available commands:\n");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ConsoleCommandsCount; i++)
|
||||
ConsoleWrite(" > %#%s\n", Color(0,ColorWhite), ConsoleCommands[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleWrite("%#! Help for %s command is not implemented yet.\n", Color(0,ColorLightRed), params[1]);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* dump - dumps memory content *
|
||||
*****************************************/
|
||||
inline char hex (int32 digit)
|
||||
{
|
||||
return (digit < 10) ? (digit + '0') : (digit - 10 + 'A');
|
||||
}
|
||||
|
||||
void CommandDump (string argv[], int32 argc)
|
||||
{
|
||||
unsigned pause = 1, i = 0;
|
||||
|
||||
// Verify correct number of arguments
|
||||
if (argc < 3) {
|
||||
ConsoleWrite("%#! Correct syntax: %#dump %#[start_address] [end_address]\n",
|
||||
ColorLightRed, ColorWhite, ColorLightGray);
|
||||
ConsoleWrite("%#Start %#and %#end %#addresses are in hex.\n",
|
||||
ColorLightGray, ColorDarkGray, ColorLightGray, ColorDarkGray);
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable pause
|
||||
if (argc==4 && strcmp(argv[3], "!p") == 0)
|
||||
pause = 0;
|
||||
|
||||
// Dump memory
|
||||
unsigned char *start, *end;
|
||||
start = (unsigned char *) ConvertStringToIntHex(argv[1]);
|
||||
end = (unsigned char *) ConvertStringToIntHex(argv[2]);
|
||||
unsigned char* count;
|
||||
|
||||
while (start <= end) {
|
||||
// Write address
|
||||
ConsoleWrite("%#%x%#: ", Color(0,ColorLightMagenta), (unsigned int)start, Color(0,ColorLightGray));
|
||||
|
||||
// Write hex data
|
||||
for (count = start; count < start+16; count++) {
|
||||
if (*count == 0) ConsoleWrite ("%#00 ", Color(0,ColorDarkGray));
|
||||
else ConsoleWrite ("%#%c%c ", Color(0,ColorWhite), hex(*count/16), hex(*count%16));
|
||||
}
|
||||
|
||||
// Write ASCII data
|
||||
ConsoleWrite(" ");
|
||||
for (count = start; count < start+16; count++) {
|
||||
if (*count < 32) ConsoleWrite(".");
|
||||
else ConsoleWrite("%#%c", Color(0,ColorLightGreen), *count);
|
||||
}
|
||||
|
||||
// New line
|
||||
ConsoleWrite("\n\r");
|
||||
start+=16; i++;
|
||||
|
||||
// Pause
|
||||
if ((i%22 == 0) && (pause==1)) {
|
||||
ConsoleWrite("\n\r%#Press %#any key %#to continue scrolling, %#Esc %#to exit.",
|
||||
0x8, 0x7, 0x8, 0x7, 0x8);
|
||||
Key k = ReadKey();
|
||||
if (k.Scancode == KeyboardKeyEscape) return;
|
||||
ConsoleWrite("\n\n\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define _CommandMemTotalRows 10
|
||||
void _CommandMemPrintMemmap()
|
||||
{
|
||||
uint8 color = Color(ColorGreen, ColorRed);
|
||||
uint32 total = MemoryGetFramesTotal();
|
||||
|
||||
char c = ' ';
|
||||
|
||||
// Print memory map
|
||||
int32 i, old = 0, n = 0, blocks, used;
|
||||
for (i = 0; i < 80; i++)
|
||||
ConsoleWrite("%#%c", ColorLightGray, 220);
|
||||
|
||||
for (i = 1; i <= 80*_CommandMemTotalRows; i++, old++)
|
||||
{
|
||||
n = (total * i) / (80 * _CommandMemTotalRows);
|
||||
|
||||
blocks = n - old;
|
||||
used = 0;
|
||||
for (; old < n; old++)
|
||||
used += (MemPhGetFrame(old) != 0);
|
||||
|
||||
if (used <= blocks / 5) c = ' ';
|
||||
else if (used > 4 * blocks / 5) c = 219;
|
||||
else if (used <= 2 * blocks / 5) c = 176;
|
||||
else if (used <= 3 * blocks / 5) c = 177;
|
||||
else c = 178;
|
||||
|
||||
ConsoleWrite("%#%c", color, c);
|
||||
}
|
||||
|
||||
for (i = 0; i < 80; i++)
|
||||
ConsoleWrite("%#%c", ColorDarkGray, 223);
|
||||
}
|
||||
|
||||
void CommandMem (string argv[], int32 argc)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
ConsoleWrite ("Memory map:\n");
|
||||
|
||||
_CommandMemPrintMemmap();
|
||||
|
||||
ConsoleWrite ("Free space: %#%ukb (%u frames)\n", ColorLightMagenta, MemoryGetFree(), MemoryGetFramesFree());
|
||||
ConsoleWrite ("Used space: %#%ukb (%u frames)\n\n", ColorLightMagenta, MemoryGetUsed(), MemoryGetFramesUsed());
|
||||
ConsoleWrite ("Total space: %#%ukb (%u frames)\n", ColorLightMagenta, MemoryGetTotal(), MemoryGetFramesTotal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "alloc") == 0)
|
||||
{
|
||||
uint32 addr = 0;
|
||||
if (argc < 3) addr = (uint32)kmalloc(0x4);
|
||||
else addr = (uint32)kmalloc(ConvertStringToUInt(argv[2]));
|
||||
|
||||
ConsoleWrite("Returned address: %#0x%x\n", ColorWhite, addr);
|
||||
}
|
||||
|
||||
else if (strcmp(argv[1], "free") == 0)
|
||||
{
|
||||
if (argc < 3) {
|
||||
ConsoleWrite ("%#! Missing parameter: address to free.", ColorRed);
|
||||
return;
|
||||
}
|
||||
|
||||
kfree((void*)ConvertStringToIntHex(argv[2]));
|
||||
ConsoleWrite("Done.\n");
|
||||
}
|
||||
|
||||
else ConsoleWrite("%#! Invalid command. Available commands are: alloc, free.", ColorLightRed);
|
||||
}
|
||||
|
||||
void CommandCrash()
|
||||
{
|
||||
int a = 10, b = 0;
|
||||
ConsoleWrite ("%d", a/b);
|
||||
}
|
||||
|
||||
void CommandMouse()
|
||||
{
|
||||
MouseState s = MouseGetState();
|
||||
ConsoleWrite("X=%d Y=%d Buttons=", s.Position.X, s.Position.Y);
|
||||
|
||||
if (!s.Buttons) ConsoleWrite("<none>");
|
||||
if (s.Buttons & 1) ConsoleWrite("<left>");
|
||||
if (s.Buttons & 2) ConsoleWrite("<right>");
|
||||
if (s.Buttons & 4) ConsoleWrite("<mid>");
|
||||
|
||||
ConsoleWrite("\n");
|
||||
}
|
||||
|
||||
void CommandRead(string argv[], int32 argc)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
ConsoleWrite("%#! Missing parameter - sector!\n", ColorLightRed);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 sector = ConvertStringToUInt(argv[1]);
|
||||
ConsoleWrite("Returned value: 0x%x\n", FloppyRead(0, sector));
|
||||
}
|
||||
131
Kernel/debug/console-base.c
Normal file
131
Kernel/debug/console-base.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <debugio.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint8* VideoPtr = (uint8*) 0xb8000;
|
||||
|
||||
Point ConsoleCursor = {0, 0};
|
||||
UPoint ConsoleSize = {80, 25};
|
||||
|
||||
uint8 ConsoleDefaultColor = CONSOLE_DEFAULT_COLOR;
|
||||
|
||||
/**************************************
|
||||
* Basic console operations *
|
||||
**************************************/
|
||||
void ConsoleClear()
|
||||
{
|
||||
uint32 temp;
|
||||
|
||||
for (temp = 0; temp < ConsoleSize.X * ConsoleSize.Y; temp++)
|
||||
{
|
||||
VideoPtr[2 * temp] = 0;
|
||||
VideoPtr[2 * temp + 1] = ConsoleDefaultColor;
|
||||
}
|
||||
|
||||
ConsoleCursor.X = ConsoleCursor.Y = 0;
|
||||
ConsoleCursorUpdateHardware();
|
||||
}
|
||||
|
||||
void ConsoleScroll (uint32 lines)
|
||||
{
|
||||
// Sanity check, don't scroll too much
|
||||
if (lines > ConsoleSize.Y) lines = ConsoleSize.Y;
|
||||
|
||||
uint32 x, y;
|
||||
for (y = 0; y < ConsoleSize.Y - lines; y++)
|
||||
for (x = 0; x < 2*ConsoleSize.X; x++)
|
||||
VideoPtr[y * ConsoleSize.X * 2 + x] = VideoPtr[(y+lines)*ConsoleSize.X*2 + x];
|
||||
|
||||
for (y = ConsoleSize.Y - lines; y < ConsoleSize.Y; y++)
|
||||
for (x = 0; x < ConsoleSize.X; x++)
|
||||
{
|
||||
VideoPtr[2 * (y * ConsoleSize.X + x)] = 0;
|
||||
VideoPtr[2 * (y * ConsoleSize.X + x) + 1] = ConsoleDefaultColor;
|
||||
}
|
||||
|
||||
ConsoleCursor.Y -= lines;
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Cursor position *
|
||||
**************************************/
|
||||
Point ConsoleGetCursor()
|
||||
{
|
||||
return ConsoleCursor;
|
||||
}
|
||||
|
||||
extern void ConsoleSetCursor(Point p)
|
||||
{
|
||||
ConsoleCursor = p;
|
||||
}
|
||||
|
||||
void ConsoleCursorIncreasePos (int32 delta)
|
||||
{
|
||||
// Increase X, Y positions
|
||||
ConsoleCursor.Y += delta / ConsoleSize.X;
|
||||
ConsoleCursor.X += delta % ConsoleSize.X;
|
||||
|
||||
// Next line if X > Screen width
|
||||
while (ConsoleCursor.X >= (int32)ConsoleSize.X)
|
||||
{
|
||||
ConsoleCursor.Y++;
|
||||
ConsoleCursor.X -= ConsoleSize.X;
|
||||
}
|
||||
|
||||
// Previous line if X < 0
|
||||
while (ConsoleCursor.X < 0)
|
||||
{
|
||||
ConsoleCursor.Y--;
|
||||
ConsoleCursor.X += ConsoleSize.X;
|
||||
}
|
||||
|
||||
// Scroll if Y > Screen height
|
||||
if (ConsoleCursor.Y >= (int32)ConsoleSize.Y)
|
||||
ConsoleScroll(1);
|
||||
}
|
||||
|
||||
void ConsoleCursorNewline()
|
||||
{
|
||||
ConsoleCursor.X = 0;
|
||||
|
||||
if (++ConsoleCursor.Y >= (int32)ConsoleSize.Y)
|
||||
ConsoleScroll(1);
|
||||
}
|
||||
|
||||
void ConsoleCursorUpdateHardware()
|
||||
{
|
||||
uint16 temp = (uint16) (ConsoleCursor.Y * ConsoleSize.X + ConsoleCursor.X);
|
||||
uint16* port = (uint16*) 0x463 ;
|
||||
|
||||
outportb(*port, 14);
|
||||
outportb(*port + 1, (temp >> 8) & 0xff);
|
||||
outportb(*port, 15);
|
||||
outportb(*port + 1, temp & 0xff);
|
||||
}
|
||||
|
||||
uint8 Color (uint8 back, uint8 fore)
|
||||
{
|
||||
return ((back<<4) | fore);
|
||||
}
|
||||
|
||||
void ConsoleSetDefaultColor(uint8 color)
|
||||
{
|
||||
ConsoleDefaultColor = color;
|
||||
}
|
||||
|
||||
uint8 ConsoleGetDefaultColor ()
|
||||
{
|
||||
return ConsoleDefaultColor;
|
||||
}
|
||||
|
||||
UPoint ConsoleGetSize()
|
||||
{
|
||||
return ConsoleSize;
|
||||
}
|
||||
|
||||
void ConsoleCursorGoto(Point p)
|
||||
{
|
||||
if (p.X >= 0 && p.X < (int32)ConsoleSize.X) ConsoleCursor.X = p.X;
|
||||
if (p.Y >= 0 && p.Y < (int32)ConsoleSize.Y) ConsoleCursor.Y = p.Y;
|
||||
}
|
||||
162
Kernel/debug/console-in.c
Normal file
162
Kernel/debug/console-in.c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <debugio.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "../hal/keyboard/keyboard.h"
|
||||
|
||||
// extern uint8* VideoPtr;
|
||||
extern UPoint ConsoleCursor;
|
||||
// extern UPoint ConsoleSize;
|
||||
// extern uint8 ConsoleDefaultColor;
|
||||
|
||||
extern void _write_char (char c);
|
||||
extern void _write_string (string s);
|
||||
|
||||
int _next_word_index (string s, int32 direction, int32 current, int32 len)
|
||||
{
|
||||
int32 tmp = current;
|
||||
|
||||
if (direction < 0) {
|
||||
--tmp;
|
||||
while ((isspace((unsigned char)s[tmp]) || ispunct((unsigned char)s[tmp])) && tmp > 0) --tmp;
|
||||
while (isalnum((unsigned char)s[tmp]) && tmp > 0) --tmp;
|
||||
|
||||
if (tmp != 0) tmp++;
|
||||
}
|
||||
|
||||
else {
|
||||
++tmp;
|
||||
while (isalnum((unsigned char)s[tmp]) && tmp < len) ++tmp;
|
||||
while ((isspace((unsigned char)s[tmp]) || ispunct((unsigned char)s[tmp])) && tmp < len) ++tmp;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void _string_crop (string s, int32 start, int32 end, int32* len)
|
||||
{
|
||||
int32 i;
|
||||
for (i = end; i < *len; i++)
|
||||
s[i-(end-start)] = s[i];
|
||||
|
||||
*len = *len - (end - start);
|
||||
s[*len] = 0;
|
||||
}
|
||||
|
||||
void _string_insert (string s, char what, int32 position, int32* len)
|
||||
{
|
||||
int32 i;
|
||||
for (i = *len; i > position; i--)
|
||||
s[i] = s[i-1];
|
||||
|
||||
s[position] = what;
|
||||
*len = *len + 1;
|
||||
|
||||
s[*len] = 0;
|
||||
}
|
||||
|
||||
void ConsoleReadString (string s, int32 buffer_size, char end_char)
|
||||
{
|
||||
Key key;
|
||||
int32 cursor=0, length = 0, old_length = 0;
|
||||
UPoint cursor_original = ConsoleCursor;
|
||||
|
||||
s[0] = 0;
|
||||
|
||||
do {
|
||||
// Read a key from keyboard
|
||||
key = ReadKey();
|
||||
|
||||
// Process scancode
|
||||
switch (key.Scancode)
|
||||
{
|
||||
// Left arrow
|
||||
case KeyboardKeyLeft:
|
||||
if (cursor > 0)
|
||||
{
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
|
||||
cursor = _next_word_index(s, -1, cursor, length);
|
||||
else --cursor;
|
||||
}
|
||||
break;
|
||||
|
||||
// Right arrow
|
||||
case KeyboardKeyRight:
|
||||
if (cursor < length)
|
||||
{
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
|
||||
cursor = _next_word_index(s, 1, cursor, length);
|
||||
else ++cursor;
|
||||
}
|
||||
break;
|
||||
|
||||
// Delete key
|
||||
case KeyboardKeyDelete:
|
||||
{
|
||||
if (cursor == length) break;
|
||||
|
||||
int32 start_d = cursor, end_d;
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
|
||||
end_d = _next_word_index(s, 1, cursor, length);
|
||||
else end_d = cursor + 1;
|
||||
|
||||
_string_crop(s, start_d, end_d, &length);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Backspace key
|
||||
case KeyboardKeyBackspace:
|
||||
{
|
||||
if (cursor == 0) break;
|
||||
|
||||
int32 end = cursor;
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyRightCtrl) || KeyboardGetKeyStatus(KeyboardKeyLeftCtrl))
|
||||
cursor = _next_word_index(s, -1, cursor, length);
|
||||
else cursor --;
|
||||
|
||||
_string_crop(s, cursor, end, &length);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Home key
|
||||
case KeyboardKeyHome:
|
||||
cursor = 0; break;
|
||||
|
||||
// End key
|
||||
case KeyboardKeyEnd:
|
||||
cursor = length; break;
|
||||
|
||||
// Rest of keys
|
||||
default:
|
||||
// Ignore non-character keys
|
||||
if (key.Character == 0 || iscntrl(key.Character)) break;
|
||||
|
||||
_string_insert(s, key.Character, cursor, &length);
|
||||
++cursor;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Redraw string
|
||||
ConsoleCursor = cursor_original;
|
||||
|
||||
// Remove old string if still there
|
||||
int32 i;
|
||||
if (old_length > length)
|
||||
for (i = 0; i < old_length; i++)
|
||||
_write_char(' ');
|
||||
|
||||
old_length = length;
|
||||
ConsoleCursor = cursor_original;
|
||||
_write_string(s);
|
||||
|
||||
ConsoleCursor = cursor_original;
|
||||
ConsoleCursorIncreasePos(cursor);
|
||||
ConsoleCursorUpdateHardware();
|
||||
|
||||
} while (key.Character != end_char && length < buffer_size);
|
||||
|
||||
ConsoleWriteChar('\n');
|
||||
}
|
||||
|
||||
155
Kernel/debug/console-out.c
Normal file
155
Kernel/debug/console-out.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <debugio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern uint8* VideoPtr;
|
||||
|
||||
extern UPoint ConsoleCursor;
|
||||
extern UPoint ConsoleSize;
|
||||
|
||||
extern uint8 ConsoleDefaultColor;
|
||||
|
||||
/**************************************
|
||||
* Write operations*
|
||||
**************************************/
|
||||
void _write_char(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
ConsoleCursorNewline(); break;
|
||||
|
||||
case '\r':
|
||||
ConsoleCursor.X = 0; break;
|
||||
|
||||
case '\t':
|
||||
ConsoleCursorIncreasePos(6 - ConsoleCursor.X % 6); break;
|
||||
|
||||
case '\b':
|
||||
ConsoleCursorIncreasePos(-1);
|
||||
VideoPtr[2 * (ConsoleCursor.Y * ConsoleSize.X + ConsoleCursor.X)] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
VideoPtr[2 * (ConsoleCursor.Y * ConsoleSize.X + ConsoleCursor.X)] = c;
|
||||
VideoPtr[2 * (ConsoleCursor.Y * ConsoleSize.X + ConsoleCursor.X) + 1] = ConsoleDefaultColor;
|
||||
|
||||
ConsoleCursorIncreasePos(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _write_string (string s)
|
||||
{
|
||||
int32 len = strlen(s), i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
_write_char(s[i]);
|
||||
}
|
||||
|
||||
|
||||
void ConsoleWriteChar (char c)
|
||||
{
|
||||
_write_char(c);
|
||||
ConsoleCursorUpdateHardware();
|
||||
}
|
||||
|
||||
void ConsoleWriteString (string s)
|
||||
{
|
||||
_write_string(s);
|
||||
ConsoleCursorUpdateHardware();
|
||||
}
|
||||
|
||||
int32 ConsoleWrite (string format, ...)
|
||||
{
|
||||
if (!format || !*format) return 0;
|
||||
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
uint32 i, len = strlen(format);
|
||||
|
||||
uint8 temp_color = ConsoleDefaultColor;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (format[i] != '%') _write_char(format[i]);
|
||||
else
|
||||
{
|
||||
++i;
|
||||
switch (format[i]) {
|
||||
// Character
|
||||
case 'c': {
|
||||
char c = va_arg (args, char);
|
||||
_write_char(c);
|
||||
break;
|
||||
}
|
||||
|
||||
// String
|
||||
case 's': {
|
||||
int32* c = (int32*) va_arg (args, string);
|
||||
_write_string((string)c);
|
||||
break;
|
||||
}
|
||||
|
||||
// Integers
|
||||
case 'd':
|
||||
case 'i': {
|
||||
int32 c = va_arg(args, int32); char temp[32];
|
||||
ConvertIntToString(temp, c, 10);
|
||||
_write_string(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
// Integers - hex
|
||||
case 'X':
|
||||
case 'x': {
|
||||
int32 c = va_arg(args, int32); char temp[32];
|
||||
ConvertUIntToString(temp, c, 16);
|
||||
_write_string(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
// Integers - unsigned
|
||||
case 'u': {
|
||||
int32 c = va_arg(args, uint32); char temp[32];
|
||||
ConvertUIntToString (temp, c, 10);
|
||||
_write_string(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
// Colors
|
||||
case '#': {
|
||||
uint8 c = va_arg(args, uint8);
|
||||
ConsoleDefaultColor = c;
|
||||
break; }
|
||||
|
||||
default: va_end(args); return 1;
|
||||
};
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
ConsoleDefaultColor = temp_color;
|
||||
ConsoleCursorUpdateHardware();
|
||||
return i;
|
||||
}
|
||||
|
||||
void ConsoleSetChar(Point pos, char c)
|
||||
{
|
||||
VideoPtr[2 * (pos.Y * ConsoleSize.X + pos.X)] = c;
|
||||
}
|
||||
|
||||
void ConsoleSetColor(Point pos, uint8 color)
|
||||
{
|
||||
VideoPtr[2 * (pos.Y * ConsoleSize.X + pos.X) + 1] = color;
|
||||
}
|
||||
|
||||
char ConsoleGetChar(Point pos)
|
||||
{
|
||||
return (char)VideoPtr[2 * (pos.Y * ConsoleSize.X + pos.X)];
|
||||
}
|
||||
|
||||
uint8 ConsoleGetColor (Point pos)
|
||||
{
|
||||
return VideoPtr[2 * (pos.Y * ConsoleSize.X + pos.X) + 1];
|
||||
}
|
||||
93
Kernel/debug/console.c
Normal file
93
Kernel/debug/console.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <debugio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "commands.c"
|
||||
|
||||
void _process_command (string params[16], int32 count);
|
||||
void _command_does_not_exist(string command);
|
||||
|
||||
void ConsoleMain()
|
||||
{
|
||||
char buffer[512];
|
||||
string params[CONSOLE_MAX_PARAMS];
|
||||
|
||||
CommandOsver();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Read a string
|
||||
ConsoleWrite("\n%#] ", Color(ColorBlack, ColorYellow));
|
||||
ConsoleReadString(buffer, 512, '\n');
|
||||
|
||||
// Split buffer in params
|
||||
params[0] = buffer;
|
||||
|
||||
int32 i=0, len = strlen(buffer), param_count = 0;
|
||||
|
||||
while (i < len && param_count < CONSOLE_MAX_PARAMS)
|
||||
{
|
||||
// Skip spaces before
|
||||
while (i < len && isspace(buffer[i])) buffer[i++] = 0;
|
||||
if (i == len) break;
|
||||
|
||||
params[param_count++] = &buffer[i];
|
||||
|
||||
// Skip non-spaces
|
||||
while (i < len && !isspace(buffer[i])) i++;
|
||||
}
|
||||
|
||||
// Send command to processing
|
||||
_process_command(params, param_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _process_command (string params[CONSOLE_MAX_PARAMS], int32 count)
|
||||
{
|
||||
int32 Cmd = -1;
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
ConsoleWrite ("%#! You must enter a command!\n", Color(0, ColorLightRed));
|
||||
return;
|
||||
}
|
||||
|
||||
// Lookup command in list
|
||||
int32 i;
|
||||
for (i = 0; i < ConsoleCommandsCount && Cmd == -1; i++)
|
||||
if (strcmp(params[0], ConsoleCommands[i]) == 0) Cmd = i;
|
||||
|
||||
switch (Cmd)
|
||||
{
|
||||
case -1: _command_does_not_exist(params[0]); break;
|
||||
case 0: CommandOsver(); break;
|
||||
case 1: CommandTime(); break;
|
||||
case 2: ConsoleClear(); break;
|
||||
case 3: CommandHelp(params, count); break;
|
||||
case 4: CommandDump (params, count); break;
|
||||
case 5: CommandMem(params, count); break;
|
||||
case 6: CommandCrash(); break;
|
||||
case 7: CommandMouse(); break;
|
||||
case 8: CommandRead(params, count); break;
|
||||
case 9:
|
||||
case 10: SystemReboot(); break;
|
||||
|
||||
default: ConsoleWrite ("%#! Command %#%s%# was not implemented (yet)!\n",
|
||||
Color(0,ColorLightRed), Color(0,ColorWhite), params[0], Color(0,ColorLightRed)); break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _command_does_not_exist(string command)
|
||||
{
|
||||
if (strlen(command) > 20)
|
||||
{
|
||||
command[18] = command[19] = command[20] = '.';
|
||||
command[21] = null;
|
||||
}
|
||||
|
||||
ConsoleWrite ("%#! Command %#%s%# does not exist!\n",
|
||||
Color(0,ColorLightRed), Color(0,ColorWhite), command, Color(0,ColorLightRed));
|
||||
|
||||
}
|
||||
63
Kernel/drivers/cmos/cmos.c
Normal file
63
Kernel/drivers/cmos/cmos.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include "cmos.h"
|
||||
|
||||
uint8 CmosRead (uint8 address)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
void CmosWrite (uint8 address, uint8 val)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
outportb(0x71, val);
|
||||
}
|
||||
|
||||
void CmosSetRTC (const Time* time)
|
||||
{
|
||||
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
uint8 year = time->Year % 100;
|
||||
uint8 century = time->Year / 100;
|
||||
|
||||
CmosWrite (0, (BCD) ? (time->Second%10) | (time->Second/10*16) : time->Second); // Seconds
|
||||
CmosWrite (2, (BCD) ? (time->Minute%10) | (time->Minute/10*16) : time->Minute); // Minutes
|
||||
|
||||
if (ampm && time->Hour > 12) // Hours
|
||||
CmosWrite (4, (BCD) ? (((time->Hour - 12) % 10) | ((time->Hour - 12)/10*16) | 0x80) : (time->Hour | 0x80) );
|
||||
|
||||
else if (ampm && time->Hour == 0) // Midnight convention: 12 PM = 00:00
|
||||
CmosWrite (4, (BCD) ? 0x92 : 0x8C);
|
||||
|
||||
else CmosWrite (4, (BCD) ? (time->Hour%10) | (time->Hour/10*16) : time->Hour); // 24h / AM
|
||||
|
||||
CmosWrite (7, (BCD) ? (time->Day%10) | (time->Day/10*16) : time->Day); // Day
|
||||
CmosWrite (8, (BCD) ? (time->Month%10) | (time->Month/10*16) : time->Month); // Month
|
||||
CmosWrite (9, (BCD) ? (year%10) | (year/10*16) : year); // Year
|
||||
CmosWrite (0x32, (BCD) ? (century%10) | (century/10*16) : century); // Century
|
||||
}
|
||||
|
||||
void CmosGetRTC(Time* tim)
|
||||
{
|
||||
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char am_pm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
tim->Second = (BCD) ? (CmosRead(0x00)%16) + 10*(CmosRead(0x00)/16): CmosRead(0x00);
|
||||
tim->Minute = (BCD) ? (CmosRead(0x02)%16) + 10*(CmosRead(0x02)/16): CmosRead(0x02);
|
||||
|
||||
// Time is PM
|
||||
if (am_pm && (CmosRead(0x04)&80)) {
|
||||
tim->Hour = (BCD) ? ((CmosRead(0x04)-0x80)%16) + 10*((CmosRead(0x04)-0x80)/16): CmosRead(0x04)-0x80;
|
||||
tim->Hour += 12;
|
||||
}
|
||||
// 24Hour format, or AM
|
||||
else tim->Hour = (BCD) ? (CmosRead(0x04)%16) + 10*(CmosRead(0x04)/16): CmosRead(0x04);
|
||||
|
||||
tim->WeekDay = (BCD) ? (CmosRead(0x06)%16) + 10*(CmosRead(0x06)/16): CmosRead(0x06);
|
||||
tim->Day = (BCD) ? (CmosRead(0x07)%16) + 10*(CmosRead(0x07)/16): CmosRead(0x07);
|
||||
tim->Month = (BCD) ? (CmosRead(0x08)%16) + 10*(CmosRead(0x08)/16): CmosRead(0x08);
|
||||
tim->Year = (BCD) ? (CmosRead(0x09)%16) + 10*(CmosRead(0x09)/16): CmosRead(0x09);
|
||||
tim->Year += 100 * ((BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32));
|
||||
}
|
||||
12
Kernel/drivers/cmos/cmos.h
Normal file
12
Kernel/drivers/cmos/cmos.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __CMOS__H
|
||||
#define __CMOS__H
|
||||
|
||||
#include <types.h>
|
||||
#include <time.h>
|
||||
|
||||
extern uint8 CmosRead (uint8 address);
|
||||
extern void CmosWrite (uint8 address, uint8 val);
|
||||
extern void CmosSetRTC (const Time* time);
|
||||
extern void CmosGetRTC(Time* tim);
|
||||
|
||||
#endif
|
||||
111
Kernel/drivers/dma/dma.c
Normal file
111
Kernel/drivers/dma/dma.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* dma.c
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dma.h"
|
||||
|
||||
void DmaSetAddress (uint8 channel, uint8 low, uint8 high)
|
||||
{
|
||||
uint16 port = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 0: port = DmaRegisterChannel0Address; break;
|
||||
case 1: port = DmaRegisterChannel1Address; break;
|
||||
case 2: port = DmaRegisterChannel2Address; break;
|
||||
case 3: port = DmaRegisterChannel3Address; break;
|
||||
case 4: port = DmaRegisterChannel4Address; break;
|
||||
case 5: port = DmaRegisterChannel5Address; break;
|
||||
case 6: port = DmaRegisterChannel6Address; break;
|
||||
case 7: port = DmaRegisterChannel7Address; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
outportb(port, low); iowait();
|
||||
outportb(port, high);
|
||||
}
|
||||
|
||||
void DmaSetCount (uint8 channel, uint8 low, uint8 high)
|
||||
{
|
||||
uint16 port = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 0: port = DmaRegisterChannel0Count; break;
|
||||
case 1: port = DmaRegisterChannel1Count; break;
|
||||
case 2: port = DmaRegisterChannel2Count; break;
|
||||
case 3: port = DmaRegisterChannel3Count; break;
|
||||
case 4: port = DmaRegisterChannel4Count; break;
|
||||
case 5: port = DmaRegisterChannel5Count; break;
|
||||
case 6: port = DmaRegisterChannel6Count; break;
|
||||
case 7: port = DmaRegisterChannel7Count; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
outportb(port, low); iowait();
|
||||
outportb(port, high);
|
||||
}
|
||||
|
||||
void DmaSetExternalPageRegisters (uint8 channel, uint8 val)
|
||||
{
|
||||
uint16 port = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case 1: port = DmaRegisterChannel1PageAddress; break;
|
||||
case 2: port = DmaRegisterChannel2PageAddress; break;
|
||||
case 3: port = DmaRegisterChannel3PageAddress; break;
|
||||
case 5: port = DmaRegisterChannel5PageAddress; break;
|
||||
case 6: port = DmaRegisterChannel6PageAddress; break;
|
||||
case 7: port = DmaRegisterChannel7PageAddress; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
outportb(port, val);
|
||||
}
|
||||
|
||||
void DmaResetFlipFlop (uint8 channel)
|
||||
{
|
||||
uint16 port = (channel < 4) ? DmaRegisterFlipFlopReset : 2*DmaRegisterFlipFlopReset+0xC0;
|
||||
outportb(port, 0);
|
||||
}
|
||||
|
||||
void DmaReset ()
|
||||
{
|
||||
outportb(DmaRegisterMasterReset, 0);
|
||||
}
|
||||
|
||||
void DmaUnmaskAll()
|
||||
{
|
||||
outportb(DmaRegisterMaskReset, 0);
|
||||
}
|
||||
|
||||
void DmaMaskChannel(uint8 channel)
|
||||
{
|
||||
if (channel >= 8) return;
|
||||
uint16 port = (channel < 4) ? (DmaRegisterSingleChannelMask) : (2*DmaRegisterSingleChannelMask + 0xC0);
|
||||
|
||||
outportb(port, channel%4 | 4);
|
||||
}
|
||||
|
||||
void DmaUnmaskChannel (uint8 channel)
|
||||
{
|
||||
if (channel >= 8) return;
|
||||
uint16 port = (channel < 4) ? (DmaRegisterSingleChannelMask) : (2*DmaRegisterSingleChannelMask + 0xC0);
|
||||
|
||||
outportb(port, channel%4);
|
||||
}
|
||||
|
||||
void DmaSetMode (uint8 channel, uint8 mode)
|
||||
{
|
||||
if (channel >= 8) return;
|
||||
uint16 port = (channel < 4) ? (DmaRegisterMode) : (2*DmaRegisterMode + 0xC0);
|
||||
|
||||
DmaMaskChannel(channel);
|
||||
outportb(port, (channel%4) | mode );
|
||||
DmaUnmaskAll();
|
||||
}
|
||||
80
Kernel/drivers/dma/dma.h
Normal file
80
Kernel/drivers/dma/dma.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* dma.h
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef DMA_H_
|
||||
#define DMA_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
enum DmaRegisters
|
||||
{
|
||||
DmaRegisterStatus = 0x08,
|
||||
DmaRegisterCommand = 0x08,
|
||||
DmaRegisterRequest = 0x09,
|
||||
DmaRegisterSingleChannelMask = 0x0A,
|
||||
DmaRegisterMode = 0x0B,
|
||||
DmaRegisterFlipFlopReset = 0x0C,
|
||||
DmaRegisterIntermediate = 0x0D,
|
||||
DmaRegisterMasterReset = 0x0D,
|
||||
DmaRegisterMaskReset = 0x0E,
|
||||
DmaRegisterMultichannelMask = 0x0F,
|
||||
|
||||
DmaRegisterChannel0Address = 0x00,
|
||||
DmaRegisterChannel1Address = 0x02,
|
||||
DmaRegisterChannel2Address = 0x04,
|
||||
DmaRegisterChannel3Address = 0x06,
|
||||
DmaRegisterChannel4Address = 0xC0,
|
||||
DmaRegisterChannel5Address = 0xC4,
|
||||
DmaRegisterChannel6Address = 0xC8,
|
||||
DmaRegisterChannel7Address = 0xCC,
|
||||
|
||||
DmaRegisterChannel0Count = 0x01,
|
||||
DmaRegisterChannel1Count = 0x03,
|
||||
DmaRegisterChannel2Count = 0x05,
|
||||
DmaRegisterChannel3Count = 0x07,
|
||||
DmaRegisterChannel4Count = 0xC2,
|
||||
DmaRegisterChannel5Count = 0xC6,
|
||||
DmaRegisterChannel6Count = 0xCA,
|
||||
DmaRegisterChannel7Count = 0xCE,
|
||||
|
||||
DmaRegisterChannel1PageAddress = 0x83,
|
||||
DmaRegisterChannel2PageAddress = 0x81,
|
||||
DmaRegisterChannel3PageAddress = 0x82,
|
||||
DmaRegisterChannel5PageAddress = 0x8B,
|
||||
DmaRegisterChannel6PageAddress = 0x89,
|
||||
DmaRegisterChannel7PageAddress = 0x8A
|
||||
};
|
||||
|
||||
enum DmaModes
|
||||
{
|
||||
DmaModeChannelMask = 0x3,
|
||||
|
||||
DmaModeSelfTest = 0,
|
||||
DmaModeWrite = 0x8,
|
||||
DmaModeRead = 0x4,
|
||||
DmaModeAutoReinit = 0x10,
|
||||
DmaModeDown = 0x20,
|
||||
|
||||
DmaModeTransferOnDemand = 0,
|
||||
DmaModeTransferSingleDma = 0x40,
|
||||
DmaModeTransferBlockDma = 0x80,
|
||||
DmaModeTransferCascade = 0xC0
|
||||
};
|
||||
|
||||
extern void DmaSetAddress (uint8 channel, uint8 low, uint8 high);
|
||||
extern void DmaSetCount (uint8 channel, uint8 low, uint8 high);
|
||||
extern void DmaSetExternalPageRegisters (uint8 channel, uint8 val);
|
||||
extern void DmaSetMode (uint8 channel, uint8 mode);
|
||||
|
||||
extern void DmaResetFlipFlop (uint8 channel);
|
||||
extern void DmaReset ();
|
||||
|
||||
extern void DmaMaskChannel(uint8 channel);
|
||||
extern void DmaUnmaskChannel (uint8 channel);
|
||||
extern void DmaUnmaskAll ();
|
||||
|
||||
#endif /* DMA_H_ */
|
||||
34
Kernel/drivers/drivers.c
Normal file
34
Kernel/drivers/drivers.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "drivers.h"
|
||||
#include "cmos/cmos.h"
|
||||
#include "pit/pit.h"
|
||||
#include "floppy/floppy.h"
|
||||
#include "time.h"
|
||||
#include "../hal/cpu/irq.h"
|
||||
#include <debugio.h>
|
||||
|
||||
void DriversInstall_Clock()
|
||||
{
|
||||
// Set up PIT
|
||||
PitSetFrequency(PIT_FREQUENCY);
|
||||
|
||||
// Update internal clock
|
||||
Time time;
|
||||
CmosGetRTC(&time);
|
||||
|
||||
TimeSetInternalTime(TimeConvertToTimeSystem(time));
|
||||
|
||||
Log("%#[Drivers] %#Read RTC time: ", ColorWhite, ColorLightGray);
|
||||
Log("%#%u/%u/%u %u:%u:%u.%u\n", ColorLightCyan, time.Month, time.Day,
|
||||
time.Year, time.Hour, time.Minute, time.Second, time.Milisecond);
|
||||
}
|
||||
|
||||
|
||||
void DriversInstall()
|
||||
{
|
||||
// Install clock
|
||||
DriversInstall_Clock();
|
||||
|
||||
// Install fdc
|
||||
IrqInstallHandler(6, FloppyIrqHandler);
|
||||
FloppyInitialize();
|
||||
}
|
||||
6
Kernel/drivers/drivers.h
Normal file
6
Kernel/drivers/drivers.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __DRIVERS__H
|
||||
#define __DRIVERS__H
|
||||
|
||||
extern void DriversInstall();
|
||||
|
||||
#endif
|
||||
384
Kernel/drivers/floppy/floppy.c
Normal file
384
Kernel/drivers/floppy/floppy.c
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* floppy.c
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
#include <stdio.h>
|
||||
#include <types.h>
|
||||
#include <time.h>
|
||||
#include <storage.h>
|
||||
#include "floppy.h"
|
||||
#include "../dma/dma.h"
|
||||
#include "../cmos/cmos.h"
|
||||
|
||||
FloppyType fdTypes[] = {
|
||||
/* Sectors
|
||||
* | Sectors per track
|
||||
* | | Heads
|
||||
* | | | Tracks
|
||||
* | | | | Gap1
|
||||
* | | | | | Data rate
|
||||
* | | | | | | Spec1
|
||||
* | | | | | | | SRT HLT HUT Motor Spinup time
|
||||
* | | | | | | | | | | | Motor Spindown time
|
||||
* | | | | | | | | | | | | Interrupt timeout
|
||||
* | | | | | | | | | | | | | Disk type name string*/
|
||||
{ 0, 0,0, 0,0x00,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, "none"},
|
||||
{ 720, 9,2,40,0x2A,0x01,0xDF,0x0C,0x04,0x00,1000,1000,3000, "5.25\" 360k"},
|
||||
{ 2400,15,2,80,0x1B,0x00,0xDF,0x0A,0x08,0x00, 400,1000,3000, "5.25\" 1.2M"},
|
||||
{ 1440, 9,2,80,0x2A,0x02,0xDF,0x0F,0x04,0x00,1000,1000,3000, "3.5\" 720k"},
|
||||
{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00, 400,1000,3000, "3.5\" 1.44M"},
|
||||
//{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00,2000,3000,3000, "3.5\" 1.44M"},
|
||||
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M AMI BIOS"},
|
||||
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M"},
|
||||
};
|
||||
|
||||
int8 fd0, fd1;
|
||||
|
||||
/**************************************
|
||||
* IRQ handler etc *
|
||||
**************************************/
|
||||
volatile uint8 FloppyIrqFired;
|
||||
void FloppyIrqHandler(_RegsStack32* UNUSED(r))
|
||||
{
|
||||
FloppyIrqFired = 1;
|
||||
}
|
||||
|
||||
void FloppyWaitIrq()
|
||||
{
|
||||
TimerStart(fdTypes[4].InterruptTimeout);
|
||||
|
||||
while (!FloppyIrqFired && !TimerIsDone());
|
||||
|
||||
if (!FloppyIrqFired) {
|
||||
Error("%#[Floppy] %#Irq timeout [%ums] !\n", ColorBrown, ColorLightRed, fdTypes[4].InterruptTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Installation *
|
||||
**************************************/
|
||||
void FloppyInitialize()
|
||||
{
|
||||
// Detect drives
|
||||
uint8 fd = CmosRead(0x10);
|
||||
fd0 = fd >> 4;
|
||||
fd1 = fd & 0xf;
|
||||
|
||||
if (fd0 > 6) fd0 = 0;
|
||||
if (fd1 > 6) fd1 = 0;
|
||||
|
||||
if (!fd0 && !fd1) {
|
||||
Error("%#[Floppy] %#No supported floppy drives found.", ColorBrown, ColorLightRed);
|
||||
outportb(FloppyRegisterDigitalOutput, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("%#[Floppy] %#Detected floppy drives:", ColorBrown, ColorLightGray);
|
||||
if (fd0) Log(" %#fd0=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd0].Name);
|
||||
if (fd1) Log(" %#fd1=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd1].Name);
|
||||
Log("\n");
|
||||
|
||||
|
||||
// Reset floppy controller
|
||||
FloppyReset();
|
||||
|
||||
// Configure and lock
|
||||
FloppyConfigure();
|
||||
FloppySendCommand(FloppyCommandLock | 0x80);
|
||||
FloppyReadData();
|
||||
|
||||
// Enable perpendicular mode for 3.5" ED floppies
|
||||
if (fd0 > 4)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandPerpendicularMode);
|
||||
FloppySendCommand(1);
|
||||
}
|
||||
if (fd1 > 4)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandPerpendicularMode);
|
||||
FloppySendCommand(2);
|
||||
}
|
||||
|
||||
// Initialize DMA
|
||||
FloppyInitDma();
|
||||
}
|
||||
|
||||
void FloppyInitDma()
|
||||
{
|
||||
DmaMaskChannel(2);
|
||||
DmaResetFlipFlop(2);
|
||||
DmaSetAddress(2, 0, 0x10);
|
||||
DmaResetFlipFlop(2);
|
||||
DmaSetCount(2, 0xff, 0x23);
|
||||
DmaSetExternalPageRegisters(2,0);
|
||||
DmaUnmaskChannel(2);
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Controller reset *
|
||||
**************************************/
|
||||
void FloppyReset()
|
||||
{
|
||||
FloppyIrqFired = 0; int32 i = 0;
|
||||
|
||||
Log("%#[Floppy] %#Resetting...\n", ColorBrown, ColorLightGray);
|
||||
|
||||
// Clear reset bit from DOR
|
||||
outportb(FloppyRegisterDigitalOutput, 0);
|
||||
for (i = 0; i < 1000; i++);
|
||||
outportb(FloppyRegisterDigitalOutput, 4|8);
|
||||
|
||||
// Wait for IRQ6
|
||||
FloppyWaitIrq(fd0);
|
||||
|
||||
// Recalibrate every drive
|
||||
if (fd0)
|
||||
{
|
||||
FloppyMotor(0,1);
|
||||
FloppySelectDrive(0);
|
||||
FloppyRecalibrate(0);
|
||||
FloppyMotor(0,0);
|
||||
}
|
||||
|
||||
if (fd1)
|
||||
{
|
||||
FloppyMotor(1,1);
|
||||
FloppySelectDrive(1);
|
||||
FloppyRecalibrate(1);
|
||||
FloppyMotor(1,0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Configure floppy controller *
|
||||
**************************************/
|
||||
void FloppyConfigure()
|
||||
{
|
||||
FloppySendCommand(FloppyCommandConfigure);
|
||||
FloppySendCommand(0);
|
||||
FloppySendCommand(1<<6 | 7);
|
||||
FloppySendCommand(0);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Base commands *
|
||||
**************************************/
|
||||
void FloppySendCommand (uint8 command)
|
||||
{
|
||||
int32 t;
|
||||
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
|
||||
|
||||
outportb (FloppyRegisterFIFO, command);
|
||||
|
||||
}
|
||||
|
||||
uint8 FloppyReadData ()
|
||||
{
|
||||
int32 t;
|
||||
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
|
||||
|
||||
return inportb (FloppyRegisterFIFO);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Sense interrupt *
|
||||
**************************************/
|
||||
void FloppySenseInterrupt(uint8 *st0, uint8 *cyl)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandSenseInterrupt);
|
||||
*st0 = FloppyReadData();
|
||||
*cyl = FloppyReadData();
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Specify *
|
||||
**************************************/
|
||||
void FloppySpecify (uint8 fd)
|
||||
{
|
||||
FloppySendCommand(FloppyCommandSpecify);
|
||||
FloppySendCommand((fdTypes[fd].SRT << 4) | fdTypes[fd].HUT);
|
||||
FloppySendCommand(fdTypes[fd].HLT << 1);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Motor on/off *
|
||||
**************************************/
|
||||
void FloppyMotor (uint8 fd_number, uint8 status)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 fd = (fd_number == 0) ? fd0 : fd1;
|
||||
uint8 temp = inportb(FloppyRegisterDigitalOutput);
|
||||
|
||||
// Turn motor on/off
|
||||
if (status) temp |= 0x1<<(4+fd_number);
|
||||
else temp &= ~(0x1<<(4+fd_number));
|
||||
outportb(FloppyRegisterDigitalOutput, temp);
|
||||
|
||||
// Wait for spinup/spindown
|
||||
if (status) TimerStart(fdTypes[fd].Spinup);
|
||||
else TimerStart(fdTypes[fd].Spindown);
|
||||
|
||||
Log("%#[Floppy] %#Waiting for motor...\n", ColorBrown, ColorLightGray);
|
||||
while (!TimerIsDone());
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Select drive *
|
||||
**************************************/
|
||||
void FloppySelectDrive(uint8 number)
|
||||
{
|
||||
if (number >= 2) return;
|
||||
uint8 fd = (number == 0) ? fd0 : fd1;
|
||||
|
||||
// Set CCR
|
||||
outportb(FloppyRegisterConfigurationControl, fdTypes[fd].DataRate);
|
||||
|
||||
// Specify
|
||||
FloppySpecify(fd);
|
||||
|
||||
// Select drive
|
||||
uint8 dor = inportb(FloppyRegisterDigitalOutput);
|
||||
dor = (dor & ~0xFF) | number;
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* RECALIBRATE *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppyRecalibrate(uint8 fd_number)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 st0, cyl, timeout = 10;
|
||||
do {
|
||||
Log("%#[Floppy] %#Recalibrating: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
FloppySendCommand(FloppyCommandRecalibrate);
|
||||
FloppySendCommand(fd_number);
|
||||
FloppyWaitIrq();
|
||||
|
||||
FloppySenseInterrupt(&st0, &cyl);
|
||||
|
||||
timeout--;
|
||||
} while((st0 & 0x20) == 0 && timeout > 0);
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* SEEK *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppySeek(uint8 fd_number, uint8 cylinder, uint8 head)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
|
||||
uint8 st0, cyl, timeout = 10;
|
||||
do {
|
||||
Log("%#[Floppy] %#Seeking: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
FloppySendCommand(FloppyCommandSeek);
|
||||
FloppySendCommand(head<<2 | fd_number);
|
||||
FloppySendCommand(cylinder);
|
||||
FloppyWaitIrq();
|
||||
|
||||
FloppySenseInterrupt(&st0, &cyl);
|
||||
|
||||
timeout--;
|
||||
} while(cyl != cylinder && timeout > 0);
|
||||
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* READ/WRITE *
|
||||
* motor must be on, drive selected *
|
||||
**************************************/
|
||||
void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector)
|
||||
{
|
||||
if (fd_number >= 2) return;
|
||||
uint8 fd = (fd_number == 0) ? fd0 : fd1;
|
||||
|
||||
uint8 timeout = 10;
|
||||
uint8 result[7], i, error;
|
||||
do
|
||||
{
|
||||
error = 0;
|
||||
Log("%#[Floppy] %#Read/write operation: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
|
||||
FloppyIrqFired = 0;
|
||||
|
||||
if (isWrite) FloppySendCommand(FloppyCommandWriteData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
|
||||
else FloppySendCommand(FloppyCommandReadData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
|
||||
|
||||
FloppySendCommand(head<<2 | fd_number);
|
||||
FloppySendCommand(cylinder);
|
||||
FloppySendCommand(head);
|
||||
FloppySendCommand(sector);
|
||||
FloppySendCommand(2);
|
||||
FloppySendCommand(fdTypes[fd].SectorsPerTrack);
|
||||
FloppySendCommand(fdTypes[fd].Gap);
|
||||
FloppySendCommand(0xff);
|
||||
|
||||
FloppyWaitIrq();
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
result[i] = FloppyReadData();
|
||||
|
||||
// Disk is write protected, don't try again
|
||||
if (result[1] & 2)
|
||||
{
|
||||
Error("%#[Floppy] %#Error: disk is write protected!\n", ColorBrown, ColorLightRed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Any other error - try again
|
||||
if (result[0] & 0xC8) error = 1;
|
||||
if (result[1] & 0xB5) error = 1;
|
||||
if (result[2] & 0x77) error = 1;
|
||||
if (result[6] & 0x02) error = 1;
|
||||
|
||||
timeout--;
|
||||
} while (timeout > 0 && !error);
|
||||
}
|
||||
|
||||
uint32 FloppyRead(uint8 drive, uint32 lba)
|
||||
{
|
||||
if (drive >= 2) return 0;
|
||||
uint8 fd = (drive == 0) ? fd0 : fd1;
|
||||
|
||||
// Convert LBA to CHS
|
||||
uint32 cyl=0, head=0, sect=1;
|
||||
ConvertLbaToChs(fdTypes[fd].SectorsPerTrack, lba, &cyl, &head, §);
|
||||
Log("%#[Floppy] %#Converted LBA=%u to Cyl=%u Head=%u Sect=%u\n", ColorBrown, ColorLightGray, lba, cyl, head, sect);
|
||||
|
||||
FloppyInitDma();
|
||||
|
||||
// Reset drive if necessary
|
||||
if ((inportb(FloppyRegisterMainStatus) & 0xC0) != 0x80)
|
||||
FloppyReset();
|
||||
|
||||
// Start motor, select drive
|
||||
FloppyMotor(drive, 1);
|
||||
FloppySelectDrive(drive);
|
||||
|
||||
// Seek to correct location
|
||||
FloppySeek(drive, cyl, head);
|
||||
|
||||
// Start DMA read
|
||||
DmaMaskChannel(2);
|
||||
DmaSetMode(2, 0x46);
|
||||
DmaUnmaskChannel(2);
|
||||
|
||||
FloppyRW(0, drive, head, cyl, sect);
|
||||
|
||||
FloppyMotor(drive, 0);
|
||||
|
||||
return 0x1000;
|
||||
}
|
||||
|
||||
// Log("%#[Drivers] %#Initializing blah blah %d...", ColorWhite, ColorLightGray,PIT_FREQUENCY);
|
||||
86
Kernel/drivers/floppy/floppy.h
Normal file
86
Kernel/drivers/floppy/floppy.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* floppy.h
|
||||
*
|
||||
* Created on: Aug 20, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef FLOPPY_H_
|
||||
#define FLOPPY_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
enum FloppyRegisters
|
||||
{
|
||||
FloppyRegisterStatusA = 0x3F0, // read-only
|
||||
FloppyRegisterStatusB = 0x3F1, // read-only
|
||||
FloppyRegisterDigitalOutput = 0x3F2,
|
||||
FloppyRegisterTapeDrive = 0x3F3,
|
||||
FloppyRegisterMainStatus = 0x3F4, // read-only
|
||||
FloppyRegisterDatarateSelect = 0x3F4, // write-only
|
||||
FloppyRegisterFIFO = 0x3F5,
|
||||
FloppyRegisterDigitalInput = 0x3F7, // read-only
|
||||
FloppyRegisterConfigurationControl = 0x3F7 // write-only
|
||||
};
|
||||
|
||||
enum FloppyCommands
|
||||
{
|
||||
FloppyCommandReadTrack = 2, // generates IRQ6
|
||||
FloppyCommandSpecify = 3, // * set drive parameters
|
||||
FloppyCommandSenseDriveStatus = 4,
|
||||
FloppyCommandWriteData = 5, // * write to the disk
|
||||
FloppyCommandReadData = 6, // * read from the disk
|
||||
FloppyCommandRecalibrate = 7, // * seek to cylinder 0
|
||||
FloppyCommandSenseInterrupt = 8, // * ack IRQ6, get status of last command
|
||||
FloppyCommandWriteDeletedData = 9,
|
||||
FloppyCommandReadID = 10, // generates IRQ6
|
||||
FloppyCommandReadDeletedData = 12,
|
||||
FloppyCommandFormatTrack = 13, // *
|
||||
FloppyCommandSeek = 15, // * seek both heads to cylinder X
|
||||
FloppyCommandVersion = 16, // * used during initialization, once
|
||||
FloppyCommandScanEqual = 17,
|
||||
FloppyCommandPerpendicularMode = 18, // * used during initialization, once, maybe
|
||||
FloppyCommandConfigure = 19, // * set controller parameters
|
||||
FloppyCommandLock = 20, // * protect controller params from a reset
|
||||
FloppyCommandVerify = 22,
|
||||
FloppyCommandScanLowOrEqual = 25,
|
||||
FloppyCommandScanHighOrEqual = 29,
|
||||
|
||||
FloppyModeMultitrack = 0x80,
|
||||
FloppyModeMagneticEncoding = 0x40, // always set for read/write/verify/format
|
||||
FloppyModeSkip = 0x20
|
||||
};
|
||||
|
||||
enum FloppyMSRMasks
|
||||
{
|
||||
FloppyMsrRQM = 0x80,
|
||||
FloppyMsrDIO = 0x40,
|
||||
FloppyMsrNDMA = 0x20,
|
||||
FloppyMsrBusy = 0x10
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32 Size, SectorsPerTrack, Heads, Tracks;
|
||||
uint8 Gap, DataRate, Spec1, SRT, HLT, HUT;
|
||||
uint32 Spinup, Spindown, InterruptTimeout;
|
||||
string Name;
|
||||
} FloppyType;
|
||||
|
||||
extern void FloppyInitialize();
|
||||
extern void FloppyIrqHandler(_RegsStack32 *r);
|
||||
extern void FloppyWaitIrq();
|
||||
extern void FloppyInitDma();
|
||||
|
||||
extern void FloppyReset();
|
||||
extern void FloppyConfigure();
|
||||
extern void FloppySendCommand (uint8 command);
|
||||
extern uint8 FloppyReadData ();
|
||||
extern void FloppySenseInterrupt(uint8 *st0, uint8 *cyl);
|
||||
extern void FloppySpecify (uint8 fd);
|
||||
extern void FloppyMotor (uint8 fd_number, uint8 status);
|
||||
extern void FloppySelectDrive(uint8 number);
|
||||
extern void FloppyRecalibrate(uint8 fd_number);
|
||||
extern void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector);
|
||||
extern uint32 FloppyRead(uint8 drive, uint32 lba);
|
||||
|
||||
#endif /* FLOPPY_H_ */
|
||||
13
Kernel/drivers/pit/pit.c
Normal file
13
Kernel/drivers/pit/pit.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "pit.h"
|
||||
|
||||
void PitSetFrequency(uint32 frequency)
|
||||
{
|
||||
uint32 divisor = 1193180 / frequency; // Calculate the divisor
|
||||
outportb(0x43, 0x36); // Set our command byte 0x36
|
||||
outportb(0x40, divisor & 0xff); // Set low byte
|
||||
outportb(0x40, divisor>>8); // Set high byte
|
||||
|
||||
TimeSetInternalFrequency(frequency);
|
||||
}
|
||||
7
Kernel/drivers/pit/pit.h
Normal file
7
Kernel/drivers/pit/pit.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __PIT__H
|
||||
#define __PIT__H
|
||||
|
||||
extern void PitSetFrequency(uint32 frequency);
|
||||
|
||||
|
||||
#endif
|
||||
19
Kernel/hal/clock/clock.c
Normal file
19
Kernel/hal/clock/clock.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <time.h>
|
||||
#include "clock.h"
|
||||
|
||||
#define MILISECONDS_IN_DAY 86400000
|
||||
|
||||
volatile TimeSystem _internal_time;
|
||||
uint32 _internal_frequency_hz;
|
||||
|
||||
void TimeHandler(_RegsStack32* UNUSED(r))
|
||||
{
|
||||
if (_internal_frequency_hz == 0) return;
|
||||
|
||||
_internal_time.Time += 1000/_internal_frequency_hz;
|
||||
if (_internal_time.Time >= MILISECONDS_IN_DAY)
|
||||
{
|
||||
_internal_time.Date++;
|
||||
_internal_time.Time-=MILISECONDS_IN_DAY;
|
||||
}
|
||||
}
|
||||
9
Kernel/hal/clock/clock.h
Normal file
9
Kernel/hal/clock/clock.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __CLOCK__H
|
||||
#define __CLOCK__H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
extern void TimeHandler(_RegsStack32 *r);
|
||||
|
||||
|
||||
#endif
|
||||
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
@@ -0,0 +1,23 @@
|
||||
; GLOBAL DESCRIPTOR TABLE
|
||||
;
|
||||
;
|
||||
|
||||
bits 32
|
||||
; !!! GDT !!!
|
||||
; This will set up our new segment registers. We need to do
|
||||
; something special in order to set CS. We do what is called a
|
||||
; far jump. A jump that includes a segment as well as an offset.
|
||||
|
||||
global GdtFlush ; Allows the C code to link to this
|
||||
extern gp ; Says that 'gp' is in another file
|
||||
GdtFlush:
|
||||
lgdt [gp] ; Load the GDT with our 'gp' which is a special pointer
|
||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!
|
||||
flush2:
|
||||
ret ; Returns back to the C code!
|
||||
74
Kernel/hal/cpu/gdt.c
Normal file
74
Kernel/hal/cpu/gdt.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/******************************************************************
|
||||
* gdt.c - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains function prototypes for setting up the GDT *
|
||||
******************************************************************/
|
||||
#define MAX_DESCRIPTORS 5
|
||||
#include "gdt.h"
|
||||
|
||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
|
||||
struct GdtEntry gdt[MAX_DESCRIPTORS];
|
||||
struct GdtPointer gp;
|
||||
|
||||
|
||||
/* Setup a descriptor in the Global Descriptor Table */
|
||||
void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (num >= MAX_DESCRIPTORS) return;
|
||||
|
||||
/* Setup the descriptor base address */
|
||||
gdt[num].base_low = (base & 0xFFFF);
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
|
||||
/* Setup the descriptor limits */
|
||||
gdt[num].limit_low = (limit & 0xFFFF);
|
||||
gdt[num].granularity = ((limit >> 16) & 0x0F);
|
||||
|
||||
/* Finally, set up the granularity and access flags */
|
||||
gdt[num].granularity |= (gran & 0xF0);
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
struct GdtEntry* GdtGetGate(int num)
|
||||
{
|
||||
if (num>MAX_DESCRIPTORS) return 0;
|
||||
return &gdt[num];
|
||||
}
|
||||
|
||||
/* Should be called by main. This will setup the special GDT
|
||||
* pointer, set up the first 3 entries in our GDT, and then
|
||||
* finally call gdt_flush() in our assembler file in order
|
||||
* to tell the processor where the new GDT is and update the
|
||||
* new segment registers */
|
||||
void GdtInstall()
|
||||
{
|
||||
/* Setup the GDT pointer and limit */
|
||||
gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
|
||||
gp.base = (unsigned int)&gdt;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
GdtSetGate(0, 0, 0, 0, 0);
|
||||
|
||||
/* The second entry is our Code Segment. The base address
|
||||
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
||||
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
||||
* Please check the table above in the tutorial in order
|
||||
* to see exactly what each value means */
|
||||
GdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
|
||||
/* The third entry is our Data Segment. It's EXACTLY the
|
||||
* same as our code segment, but the descriptor type in
|
||||
* this entry's access byte says it's a Data Segment */
|
||||
GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
/* User mode Code segment*/
|
||||
GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
/* User mode data segment*/
|
||||
GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
/* Flush out the old GDT and install the new changes! */
|
||||
GdtFlush();
|
||||
}
|
||||
|
||||
38
Kernel/hal/cpu/gdt.h
Normal file
38
Kernel/hal/cpu/gdt.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/******************************************************************
|
||||
* gdt.h - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for GDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __GDT_H
|
||||
#define __GDT_H
|
||||
|
||||
/* Defines a GDT entry. We say packed, because it prevents the
|
||||
* compiler from doing things that it thinks is best: Prevent
|
||||
* compiler "optimization" by packing */
|
||||
struct GdtEntry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Special pointer which includes the limit: The max bytes
|
||||
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
|
||||
struct GdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This will be a function in start.asm. We use this to properly
|
||||
* reload the new segment registers */
|
||||
extern void GdtInstall();
|
||||
extern void GdtFlush();
|
||||
extern void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
extern struct GdtEntry* GdtGetGate(int num);
|
||||
|
||||
#endif
|
||||
9
Kernel/hal/cpu/idt-asm.asm
Normal file
9
Kernel/hal/cpu/idt-asm.asm
Normal file
@@ -0,0 +1,9 @@
|
||||
bits 32
|
||||
|
||||
; !!! IDT !!!
|
||||
; Loads the IDT defined in '_idtp'
|
||||
global IdtLoad
|
||||
extern idtp
|
||||
IdtLoad:
|
||||
lidt [idtp]
|
||||
ret
|
||||
45
Kernel/hal/cpu/idt.c
Normal file
45
Kernel/hal/cpu/idt.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include "idt.h"
|
||||
|
||||
extern void IdtLoad();
|
||||
/* Declare an IDT of 256 entries. */
|
||||
struct IdtEntry idt[256];
|
||||
struct IdtPointer idtp;
|
||||
|
||||
/* Use this function to set an entry in the IDT. Alot simpler
|
||||
* than twiddling with the GDT ;) */
|
||||
void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
||||
{
|
||||
/* The interrupt routine's base address */
|
||||
idt[num].base_lo = (base & 0xFFFF);
|
||||
idt[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
/* The segment or 'selector' that this IDT entry will use
|
||||
* is set here, along with any access flags */
|
||||
idt[num].sel = sel;
|
||||
idt[num].always0 = 0;
|
||||
idt[num].flags = flags;
|
||||
}
|
||||
|
||||
struct IdtEntry* IdtGetGate(unsigned char num)
|
||||
{
|
||||
return &idt[num];
|
||||
}
|
||||
|
||||
/* Installs the IDT */
|
||||
void IdtInstall()
|
||||
{
|
||||
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
||||
idtp.limit = (sizeof (struct IdtEntry) * 256) - 1;
|
||||
idtp.base = (unsigned int)&idt;
|
||||
|
||||
/* Clear out the entire IDT, initializing it to zeros */
|
||||
memset (&idt, 0, sizeof(struct IdtEntry) * 256);
|
||||
|
||||
/* Points the processor's internal register to the new IDT */
|
||||
IdtLoad();
|
||||
}
|
||||
31
Kernel/hal/cpu/idt.h
Normal file
31
Kernel/hal/cpu/idt.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __IDT_H
|
||||
#define __IDT_H
|
||||
|
||||
/* Defines an IDT entry */
|
||||
struct IdtEntry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This exists in 'start.asm', and is used to load our IDT */
|
||||
extern void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
extern struct IdtEntry* IdtGetGate(unsigned char num);
|
||||
extern void IdtInstall();
|
||||
|
||||
#endif
|
||||
159
Kernel/hal/cpu/irq-asm.asm
Normal file
159
Kernel/hal/cpu/irq-asm.asm
Normal file
@@ -0,0 +1,159 @@
|
||||
bits 32
|
||||
|
||||
; !!! IRQ !!!
|
||||
global Irq_0
|
||||
global Irq_1
|
||||
global Irq_2
|
||||
global Irq_3
|
||||
global Irq_4
|
||||
global Irq_5
|
||||
global Irq_6
|
||||
global Irq_7
|
||||
global Irq_8
|
||||
global Irq_9
|
||||
global Irq_10
|
||||
global Irq_11
|
||||
global Irq_12
|
||||
global Irq_13
|
||||
global Irq_14
|
||||
global Irq_15
|
||||
|
||||
; 32: IRQ0
|
||||
Irq_0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32; Note that these don't push an error code on the stack:
|
||||
; We need to push a dummy error code
|
||||
jmp irq_common_stub
|
||||
|
||||
; 33: IRQ1
|
||||
Irq_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
; 34: IRQ2
|
||||
Irq_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
; 35: IRQ3
|
||||
Irq_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
; 36: IRQ4
|
||||
Irq_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
; 37: IRQ5
|
||||
Irq_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
; 38: IRQ6
|
||||
Irq_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
; 39: IRQ7
|
||||
Irq_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
; 40: IRQ8
|
||||
Irq_8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
; 41: IRQ9
|
||||
Irq_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
; 42: IRQ10
|
||||
Irq_10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
; 43: IRQ11
|
||||
Irq_11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
; 44: IRQ12
|
||||
Irq_12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
; 45: IRQ13
|
||||
Irq_13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
; 46: IRQ14
|
||||
Irq_14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
; 47: IRQ15
|
||||
Irq_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern IrqHandler
|
||||
|
||||
; This is a stub that we have created for IRQ based ISRs. This calls
|
||||
; 'Irq__handler' in our C code. We need to create this in an 'irq.c'
|
||||
irq_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push eax
|
||||
mov eax, IrqHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
91
Kernel/hal/cpu/irq.c
Normal file
91
Kernel/hal/cpu/irq.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
#include "irq.h"
|
||||
#include "idt.h"
|
||||
|
||||
/* These are own ISRs that point to our special IRQ handler
|
||||
* instead of the regular 'fault_handler' function */
|
||||
extern void Irq_0();
|
||||
extern void Irq_1();
|
||||
extern void Irq_2();
|
||||
extern void Irq_3();
|
||||
extern void Irq_4();
|
||||
extern void Irq_5();
|
||||
extern void Irq_6();
|
||||
extern void Irq_7();
|
||||
extern void Irq_8();
|
||||
extern void Irq_9();
|
||||
extern void Irq_10();
|
||||
extern void Irq_11();
|
||||
extern void Irq_12();
|
||||
extern void Irq_13();
|
||||
extern void Irq_14();
|
||||
extern void Irq_15();
|
||||
|
||||
/* This array is actually an array of function pointers. We use
|
||||
* this to handle custom IRQ handlers for a given IRQ */
|
||||
void *IrqRoutines[16] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* This installs a custom IRQ handler for the given IRQ */
|
||||
void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r))
|
||||
{
|
||||
IrqRoutines[irq] = handler;
|
||||
}
|
||||
|
||||
void IrqUninstallHandler (int irq)
|
||||
{
|
||||
IrqRoutines[irq] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We first remap the interrupt controllers, and then we install
|
||||
* the appropriate ISRs to the correct entries in the IDT. This
|
||||
* is just like installing the exception handlers */
|
||||
void IrqInstall()
|
||||
{
|
||||
PicRemap(32,40);
|
||||
|
||||
IdtSetGate(32, (unsigned)Irq_0, 0x08, 0x8E);
|
||||
IdtSetGate(33, (unsigned)Irq_1, 0x08, 0x8E);
|
||||
IdtSetGate(34, (unsigned)Irq_2, 0x08, 0x8E);
|
||||
IdtSetGate(35, (unsigned)Irq_3, 0x08, 0x8E);
|
||||
IdtSetGate(36, (unsigned)Irq_4, 0x08, 0x8E);
|
||||
IdtSetGate(37, (unsigned)Irq_5, 0x08, 0x8E);
|
||||
IdtSetGate(38, (unsigned)Irq_6, 0x08, 0x8E);
|
||||
IdtSetGate(39, (unsigned)Irq_7, 0x08, 0x8E);
|
||||
IdtSetGate(40, (unsigned)Irq_8, 0x08, 0x8E);
|
||||
IdtSetGate(41, (unsigned)Irq_9, 0x08, 0x8E);
|
||||
IdtSetGate(42, (unsigned)Irq_10, 0x08, 0x8E);
|
||||
IdtSetGate(43, (unsigned)Irq_11, 0x08, 0x8E);
|
||||
IdtSetGate(44, (unsigned)Irq_12, 0x08, 0x8E);
|
||||
IdtSetGate(45, (unsigned)Irq_13, 0x08, 0x8E);
|
||||
IdtSetGate(46, (unsigned)Irq_14, 0x08, 0x8E);
|
||||
IdtSetGate(47, (unsigned)Irq_15, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
// Default IRQ handler, launches other handler if installed.
|
||||
// Also sends end-of-interrupt messages to PIC
|
||||
void IrqHandler (_RegsStack32 *r)
|
||||
{
|
||||
/* This is a blank function pointer */
|
||||
void (*handler)(_RegsStack32 *r);
|
||||
|
||||
/* Find out if we have a custom handler to run for this
|
||||
* IRQ, and then finally, run it */
|
||||
handler = IrqRoutines[r->int_no - 32];
|
||||
if (handler) handler(r);
|
||||
|
||||
/* If the IDT entry that was invoked was greater than 40
|
||||
* (meaning IRQ8 - 15), then we need to send an EOI to
|
||||
* the slave controller */
|
||||
if (r->int_no >=40) outportb(0xA0, 0x20);
|
||||
|
||||
/* In either case, we need to send an EOI to the master
|
||||
* interrupt controller too */
|
||||
outportb(0x20, 0x20);
|
||||
}
|
||||
10
Kernel/hal/cpu/irq.h
Normal file
10
Kernel/hal/cpu/irq.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r));
|
||||
extern void IrqUninstallHandler (int irq);
|
||||
extern void IrqInstall();
|
||||
|
||||
#endif
|
||||
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
@@ -0,0 +1,217 @@
|
||||
bits 32
|
||||
|
||||
; !!! ISRs !!!
|
||||
global isr_exception_0
|
||||
global isr_exception_1
|
||||
global isr_exception_2
|
||||
global isr_exception_3
|
||||
global isr_exception_4
|
||||
global isr_exception_5
|
||||
global isr_exception_6
|
||||
global isr_exception_7
|
||||
global isr_exception_8
|
||||
global isr_exception_9
|
||||
global isr_exception_10
|
||||
global isr_exception_11
|
||||
global isr_exception_12
|
||||
global isr_exception_13
|
||||
global isr_exception_14
|
||||
global isr_exception_15
|
||||
global isr_exception_16
|
||||
global isr_exception_17
|
||||
global isr_exception_18
|
||||
global isr_exception_19
|
||||
global isr_exception_20
|
||||
global isr_exception_21
|
||||
global isr_exception_22
|
||||
global isr_exception_23
|
||||
global isr_exception_24
|
||||
global isr_exception_25
|
||||
global isr_exception_26
|
||||
global isr_exception_27
|
||||
global isr_exception_28
|
||||
global isr_exception_29
|
||||
global isr_exception_30
|
||||
global isr_exception_31
|
||||
|
||||
isr_exception_0:
|
||||
cli
|
||||
push byte 0; A normal ISR stub that pops a dummy error code to keep a
|
||||
; uniform stack frame
|
||||
push byte 0
|
||||
jmp isr_common_stub
|
||||
isr_exception_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
jmp isr_common_stub
|
||||
isr_exception_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
isr_exception_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
isr_exception_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
isr_exception_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
isr_exception_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
isr_exception_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
isr_exception_8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
isr_exception_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
isr_exception_10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
isr_exception_11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
isr_exception_12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
isr_exception_13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
isr_exception_14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
isr_exception_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
isr_exception_16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
isr_exception_17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
isr_exception_18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
isr_exception_19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
isr_exception_20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
isr_exception_21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
isr_exception_22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
isr_exception_23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
isr_exception_24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
isr_exception_25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
isr_exception_26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
isr_exception_27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
isr_exception_28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
isr_exception_29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
isr_exception_30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
isr_exception_31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern IsrsFaultHandler
|
||||
|
||||
isr_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10 ; Load the Kernel Data Segment descriptor!
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp ; Push us the stack
|
||||
push eax
|
||||
mov eax, IsrsFaultHandler
|
||||
call eax ; A special call, preserves the 'eip' register
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!
|
||||
114
Kernel/hal/cpu/isrs.c
Normal file
114
Kernel/hal/cpu/isrs.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <debugio.h>
|
||||
|
||||
#include "isrs.h"
|
||||
#include "idt.h"
|
||||
|
||||
// Assembly coded
|
||||
extern void isr_exception_0();
|
||||
extern void isr_exception_1();
|
||||
extern void isr_exception_2();
|
||||
extern void isr_exception_3();
|
||||
extern void isr_exception_4();
|
||||
extern void isr_exception_5();
|
||||
extern void isr_exception_6();
|
||||
extern void isr_exception_7();
|
||||
extern void isr_exception_8();
|
||||
extern void isr_exception_9();
|
||||
extern void isr_exception_10();
|
||||
extern void isr_exception_11();
|
||||
extern void isr_exception_12();
|
||||
extern void isr_exception_13();
|
||||
extern void isr_exception_14();
|
||||
extern void isr_exception_15();
|
||||
extern void isr_exception_16();
|
||||
extern void isr_exception_17();
|
||||
extern void isr_exception_18();
|
||||
extern void isr_exception_19();
|
||||
extern void isr_exception_20();
|
||||
extern void isr_exception_21();
|
||||
extern void isr_exception_22();
|
||||
extern void isr_exception_23();
|
||||
extern void isr_exception_24();
|
||||
extern void isr_exception_25();
|
||||
extern void isr_exception_26();
|
||||
extern void isr_exception_27();
|
||||
extern void isr_exception_28();
|
||||
extern void isr_exception_29();
|
||||
extern void isr_exception_30();
|
||||
extern void isr_exception_31();
|
||||
|
||||
|
||||
void* IdtFaultHandlers[32] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
void IsrsInstall()
|
||||
{
|
||||
IdtSetGate(0, (unsigned)isr_exception_0, 0x08, 0x8E);
|
||||
IdtSetGate(1, (unsigned)isr_exception_1, 0x08, 0x8E);
|
||||
IdtSetGate(2, (unsigned)isr_exception_2, 0x08, 0x8E);
|
||||
IdtSetGate(3, (unsigned)isr_exception_3, 0x08, 0x8E);
|
||||
IdtSetGate(4, (unsigned)isr_exception_4, 0x08, 0x8E);
|
||||
IdtSetGate(5, (unsigned)isr_exception_5, 0x08, 0x8E);
|
||||
IdtSetGate(6, (unsigned)isr_exception_6, 0x08, 0x8E);
|
||||
IdtSetGate(7, (unsigned)isr_exception_7, 0x08, 0x8E);
|
||||
IdtSetGate(8, (unsigned)isr_exception_8, 0x08, 0x8E);
|
||||
IdtSetGate(9, (unsigned)isr_exception_9, 0x08, 0x8E);
|
||||
IdtSetGate(10, (unsigned)isr_exception_10, 0x08, 0x8E);
|
||||
IdtSetGate(11, (unsigned)isr_exception_11, 0x08, 0x8E);
|
||||
IdtSetGate(12, (unsigned)isr_exception_12, 0x08, 0x8E);
|
||||
IdtSetGate(13, (unsigned)isr_exception_13, 0x08, 0x8E);
|
||||
IdtSetGate(14, (unsigned)isr_exception_14, 0x08, 0x8E);
|
||||
IdtSetGate(15, (unsigned)isr_exception_15, 0x08, 0x8E);
|
||||
IdtSetGate(16, (unsigned)isr_exception_16, 0x08, 0x8E);
|
||||
IdtSetGate(17, (unsigned)isr_exception_17, 0x08, 0x8E);
|
||||
IdtSetGate(18, (unsigned)isr_exception_18, 0x08, 0x8E);
|
||||
IdtSetGate(19, (unsigned)isr_exception_19, 0x08, 0x8E);
|
||||
IdtSetGate(20, (unsigned)isr_exception_20, 0x08, 0x8E);
|
||||
IdtSetGate(21, (unsigned)isr_exception_21, 0x08, 0x8E);
|
||||
IdtSetGate(22, (unsigned)isr_exception_22, 0x08, 0x8E);
|
||||
IdtSetGate(23, (unsigned)isr_exception_23, 0x08, 0x8E);
|
||||
IdtSetGate(24, (unsigned)isr_exception_24, 0x08, 0x8E);
|
||||
IdtSetGate(25, (unsigned)isr_exception_25, 0x08, 0x8E);
|
||||
IdtSetGate(26, (unsigned)isr_exception_26, 0x08, 0x8E);
|
||||
IdtSetGate(27, (unsigned)isr_exception_27, 0x08, 0x8E);
|
||||
IdtSetGate(28, (unsigned)isr_exception_28, 0x08, 0x8E);
|
||||
IdtSetGate(29, (unsigned)isr_exception_29, 0x08, 0x8E);
|
||||
IdtSetGate(30, (unsigned)isr_exception_30, 0x08, 0x8E);
|
||||
IdtSetGate(31, (unsigned)isr_exception_31, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
|
||||
void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r))
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = function;
|
||||
}
|
||||
|
||||
|
||||
void IsrsUninstallHandler(int interr)
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = 0;
|
||||
}
|
||||
|
||||
|
||||
extern void CrashMessage(_RegsStack32 *r);
|
||||
// Default fault handler; calls other handlers, or displays error message.
|
||||
void IsrsFaultHandler(_RegsStack32 *r)
|
||||
{
|
||||
/* Is this a fault whose number is from 0 to 31? */
|
||||
if (r->int_no < 32)
|
||||
{
|
||||
void (*func)(_RegsStack32 *r);
|
||||
func = IdtFaultHandlers[r->int_no];
|
||||
|
||||
// Halt system if unhandled
|
||||
if (!func) {
|
||||
CrashMessage(r);
|
||||
asm ("cli");
|
||||
asm ("hlt");
|
||||
}
|
||||
|
||||
else (*func)(r);
|
||||
}
|
||||
}
|
||||
10
Kernel/hal/cpu/isrs.h
Normal file
10
Kernel/hal/cpu/isrs.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __ISRS_H_
|
||||
#define __ISRS_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern void IsrsInstall();
|
||||
extern void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r));
|
||||
extern void IsrsUninstallHandler(int interr);
|
||||
|
||||
#endif
|
||||
23
Kernel/hal/cpu/pic.c
Normal file
23
Kernel/hal/cpu/pic.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
|
||||
void PicRemap(int pic1, int pic2)
|
||||
{
|
||||
// Send ICW1
|
||||
outportb(0x20, 0x11);
|
||||
outportb(0xA0, 0x11);
|
||||
|
||||
// send ICW2
|
||||
outportb(0x21, pic1); // remap pics
|
||||
outportb(0xA1, pic2);
|
||||
|
||||
// send ICW3
|
||||
outportb(0x21, 4);
|
||||
outportb(0xA1, 2);
|
||||
|
||||
// Send ICW4
|
||||
outportb(0x21, 0x01);
|
||||
outportb(0xA1, 0x01);
|
||||
|
||||
outportb(0x21, 0x00);
|
||||
}
|
||||
6
Kernel/hal/cpu/pic.h
Normal file
6
Kernel/hal/cpu/pic.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _PIC_H
|
||||
#define _PIC_H
|
||||
|
||||
extern void PicRemap(int pic1, int pic2);
|
||||
|
||||
#endif
|
||||
96
Kernel/hal/crash.c
Normal file
96
Kernel/hal/crash.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* crash.c
|
||||
*
|
||||
* Created on: Aug 19, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
string errorCodes[] =
|
||||
{
|
||||
"Division by zero", //0
|
||||
"Debugger", //1
|
||||
"Non maskable interrupt", //2
|
||||
"Breakpoint", //3
|
||||
"Overflow", //4
|
||||
"Bounds", //5
|
||||
"Invalid opcode", //6
|
||||
"Coprocessor not available", //7
|
||||
"Double fault", //8
|
||||
"Coprocessor segment overrun",//9
|
||||
"Invalid task state segment", //A
|
||||
"Segment not present", //B
|
||||
"Stack fault", //C
|
||||
"General protection fault", //D
|
||||
"Page fault", //E
|
||||
"", //F
|
||||
"Math fault", //10
|
||||
"Alignment check", //11
|
||||
"Machine check", //12
|
||||
"SIMD floating-point exception" //13
|
||||
};
|
||||
|
||||
void CrashMessage(_RegsStack32 *r)
|
||||
{
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n"); uint32 i;
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
|
||||
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
|
||||
ConsoleWrite("There was an unhandled exception: ");
|
||||
|
||||
if (r->int_no < 20)
|
||||
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
|
||||
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
|
||||
|
||||
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
|
||||
ConsoleWrite("Here, this might help find the problem:\n");
|
||||
|
||||
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
|
||||
|
||||
ConsoleSetDefaultColor(ColorWhite);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
|
||||
|
||||
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
|
||||
if (r->int_no == 0xE)
|
||||
{
|
||||
uint32 faulting_address;
|
||||
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
|
||||
|
||||
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
|
||||
|
||||
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
|
||||
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
|
||||
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
|
||||
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
|
||||
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
|
||||
}
|
||||
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n");
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
}
|
||||
97
Kernel/hal/crash.c~
Normal file
97
Kernel/hal/crash.c~
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* crash.c
|
||||
*
|
||||
* Created on: Aug 19, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
string errorCodes[] =
|
||||
{
|
||||
"Division by zero", //0
|
||||
"Debugger", //1
|
||||
"Non maskable interrupt", //2
|
||||
"Breakpoint", //3
|
||||
"Overflow", //4
|
||||
"Bounds", //5
|
||||
"Invalid opcode", //6
|
||||
"Coprocessor not available", //7
|
||||
"Double fault", //8
|
||||
"Coprocessor segment overrun",//9
|
||||
"Invalid task state segment", //A
|
||||
"Segment not present", //B
|
||||
"Stack fault", //C
|
||||
"General protection fault", //D
|
||||
"Page fault", //E
|
||||
"", //F
|
||||
"Math fault", //10
|
||||
"Alignment check", //11
|
||||
"Machine check", //12
|
||||
"SIMD floating-point exception" //13
|
||||
};
|
||||
|
||||
void CrashMessage(_RegsStack32 *r)
|
||||
{
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
|
||||
ConsoleWrite("\n"); uint32 i;
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
|
||||
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
|
||||
ConsoleWrite("There was an unhandled exception: ");
|
||||
|
||||
if (r->int_no < 20)
|
||||
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
|
||||
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
|
||||
|
||||
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
|
||||
ConsoleWrite("Here, this might help find the problem:\n");
|
||||
|
||||
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
|
||||
|
||||
ConsoleSetDefaultColor(ColorWhite);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
|
||||
|
||||
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
|
||||
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
|
||||
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
|
||||
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
|
||||
|
||||
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
|
||||
if (r->int_no == 0xE)
|
||||
{
|
||||
uint32 faulting_address;
|
||||
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
|
||||
|
||||
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
|
||||
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
|
||||
|
||||
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
|
||||
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
|
||||
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
|
||||
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
|
||||
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
|
||||
}
|
||||
|
||||
ConsoleSetDefaultColor(ColorLightRed);
|
||||
ConsoleWrite("\n");
|
||||
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
|
||||
}
|
||||
35
Kernel/hal/hal.c
Normal file
35
Kernel/hal/hal.c
Normal file
@@ -0,0 +1,35 @@
|
||||
// HARDWARE ABSTRACTION LAYER
|
||||
#include "cpu/gdt.h"
|
||||
#include "cpu/idt.h"
|
||||
#include "cpu/isrs.h"
|
||||
#include "cpu/irq.h"
|
||||
|
||||
#include "clock/clock.h"
|
||||
#include "keyboard/keyboard.h"
|
||||
#include "mouse/mouse.h"
|
||||
|
||||
#include <debugio.h>
|
||||
|
||||
void HalInitialize()
|
||||
{
|
||||
// Initialize cpu
|
||||
GdtInstall(); Log("%#[HAL] %#Installed GDT\n", ColorYellow, ColorLightGreen);
|
||||
IdtInstall(); Log("%#[HAL] %#Installed IDT\n", ColorYellow, ColorLightGreen);
|
||||
IsrsInstall(); Log("%#[HAL] %#Installed ISRs\n", ColorYellow, ColorLightGreen);
|
||||
IrqInstall(); Log("%#[HAL] %#Installed IRQs\n", ColorYellow, ColorLightGreen);
|
||||
|
||||
// Start interrupts
|
||||
asm volatile ("sti");
|
||||
Log("%#[HAL] %#Interrupts are started...\n", ColorYellow, ColorLightMagenta);
|
||||
|
||||
// Install keyboard
|
||||
IrqInstallHandler(0, TimeHandler);
|
||||
IrqInstallHandler(1, KeyboardHandler);
|
||||
IrqInstallHandler(12, MouseHandler);
|
||||
|
||||
KeyboardInstallA(); Log("%#[HAL] %#Installing keyboard... %#[1/2] ", ColorYellow, ColorLightGray, ColorLightGreen);
|
||||
KeyboardInstallB(); Log("%#[2/2]\n", ColorLightGreen);
|
||||
|
||||
// Install mouse driver
|
||||
MouseInstall(); Log("%#[HAL] %#Installed mouse driver\n", ColorYellow, ColorLightGreen);
|
||||
}
|
||||
6
Kernel/hal/hal.h
Normal file
6
Kernel/hal/hal.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __HAL__H
|
||||
#define __HAL__H
|
||||
|
||||
extern void HalInitialize();
|
||||
|
||||
#endif
|
||||
327
Kernel/hal/keyboard/keyboard.c
Normal file
327
Kernel/hal/keyboard/keyboard.c
Normal file
@@ -0,0 +1,327 @@
|
||||
#include <stdio.h>
|
||||
#include "keyboard.h"
|
||||
|
||||
#define KeybCmdWriteLED 0xed
|
||||
#define KeybCmdEcho 0xee
|
||||
#define KeybCmdSetScancodeSet 0xf0
|
||||
#define KeybCmdGetID 0xf2
|
||||
#define KeybCmdSetRepeatDelay 0xf3
|
||||
#define KeybCmdEnable 0xf4
|
||||
#define KeybCmdSetDefaultDisable 0xf5
|
||||
#define KeybCmdSetDefault 0xf6
|
||||
#define KeybCmdResend 0xfe
|
||||
#define KeybCmdReset 0xff
|
||||
|
||||
volatile uint8 KeyState[16];
|
||||
volatile uint8 KeyboardLastStatus;
|
||||
volatile uint8 KeyboardLastScancode;
|
||||
|
||||
uint8 KeyboardScancodeSet = 2;
|
||||
|
||||
// Byte map:
|
||||
// 0 If set, next code is break
|
||||
// 1 'Gray' key
|
||||
// 2 'Weird' key (Pause/Break)
|
||||
// 3 Scroll
|
||||
// 4 Num
|
||||
// 5 Caps
|
||||
// 6 If set, LEDs changed
|
||||
uint8 KeyboardModifiers;
|
||||
|
||||
const char KeyboardMap[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
|
||||
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
|
||||
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
|
||||
0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
|
||||
0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
|
||||
0, 0, '\'', 0, '[', '=', 0, 0, 0, 0, '\n', ']', 0, '\\', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
const char KeyboardMapShift[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
|
||||
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
|
||||
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
|
||||
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
|
||||
0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
|
||||
0, 0, '\"', 0, '{', '+', 0, 0, 0, 0, '\n', '}', 0, '|', 0, 0,
|
||||
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
|
||||
void KeyboardSetKeyStatus (uint8 scancode, uint8 status)
|
||||
{
|
||||
int32 index = scancode>>3, pos = scancode & 0x7;
|
||||
|
||||
if (status) KeyState[index] |= 1<<pos;
|
||||
else KeyState[index] &= ~(1<<pos);
|
||||
}
|
||||
|
||||
|
||||
uint8 KeyboardGetKeyStatus (uint8 scancode)
|
||||
{
|
||||
int32 index = scancode>>3, pos = scancode & 0x7;
|
||||
|
||||
return KeyState[index] & (1<<pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _process_scancode(uint8 scancode)
|
||||
{
|
||||
switch (scancode)
|
||||
{
|
||||
// Messages from keyboard controller
|
||||
case 0x00: // Error 0x00
|
||||
case 0xFC: // Diagnostics failed (MF kb)
|
||||
case 0xFD: // Diagnostics failed (AT kb)
|
||||
case 0xFF: KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdEnable);
|
||||
return; // Error 0xFF, reenable keyboard
|
||||
case 0xAA: // BAT test successful.
|
||||
case 0xFA: // ACKnowledge
|
||||
case 0xFE: // Last command invalid or parity error
|
||||
case 0xEE: return; // Echo response
|
||||
|
||||
// Break
|
||||
case 0xF0: KeyboardModifiers |= 1; return;
|
||||
|
||||
// Special character (gray, etc)
|
||||
case 0xE0: KeyboardModifiers |= 2; return;
|
||||
case 0xE1: KeyboardModifiers |= 4; return;
|
||||
|
||||
// Remap some characters:
|
||||
case 0x83: scancode = KeyboardKeyF7; break;
|
||||
|
||||
// LEDs
|
||||
case KeyboardKeyScrollLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<3;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
|
||||
case KeyboardKeyNumLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<4;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
case KeyboardKeyCapsLock:
|
||||
if ((KeyboardModifiers & 1) == 0) {
|
||||
KeyboardModifiers ^= 1<<5;
|
||||
KeyboardModifiers |= 1<<6;
|
||||
} break;
|
||||
}
|
||||
|
||||
// Remap most gray characters
|
||||
if (KeyboardModifiers & 2) switch (scancode)
|
||||
{
|
||||
case 0x10: scancode = KeyboardKeyMediaWebSearch; break;
|
||||
case 0x11: scancode = KeyboardKeyRightAlt; break;
|
||||
case 0x12: return; // Fake shift, ignore
|
||||
case 0x14: scancode = KeyboardKeyRightCtrl; break;
|
||||
case 0x15: scancode = KeyboardKeyMediaPrevious; break;
|
||||
case 0x18: scancode = KeyboardKeyMediaWebFavorites; break;
|
||||
case 0x1F: scancode = KeyboardKeyLeftWin; break;
|
||||
case 0x20: scancode = KeyboardKeyMediaWebRefresh; break;
|
||||
case 0x21: scancode = KeyboardKeyMediaVolDown; break;
|
||||
case 0x23: scancode = KeyboardKeyMediaMute; break;
|
||||
case 0x27: scancode = KeyboardKeyRightWin; break;
|
||||
case 0x28: scancode = KeyboardKeyMediaWebStop; break;
|
||||
case 0x2B: scancode = KeyboardKeyMediaCalculator; break;
|
||||
case 0x2F: scancode = KeyboardKeyMenu; break;
|
||||
case 0x30: scancode = KeyboardKeyMediaWebForward; break;
|
||||
case 0x32: scancode = KeyboardKeyMediaVolUp; break;
|
||||
case 0x34: scancode = KeyboardKeyMediaPause; break;
|
||||
case 0x37: scancode = KeyboardKeyPower; break;
|
||||
case 0x38: scancode = KeyboardKeyMediaWebBack; break;
|
||||
case 0x3A: scancode = KeyboardKeyMediaWebHome; break;
|
||||
case 0x3B: scancode = KeyboardKeyMediaStop; break;
|
||||
case 0x3F: scancode = KeyboardKeySleep; break;
|
||||
case 0x40: scancode = KeyboardKeyMediaComputer; break;
|
||||
case 0x48: scancode = KeyboardKeyMediaEmail; break;
|
||||
case 0x4A: scancode = KeyboardKeyNumpadSlash; break;
|
||||
case 0x4D: scancode = KeyboardKeyMediaNext; break;
|
||||
case 0x50: scancode = KeyboardKeyMediaSelect; break;
|
||||
case 0x5A: scancode = KeyboardKeyNumpadEnter; break;
|
||||
case 0x5E: scancode = KeyboardKeyWake; break;
|
||||
case 0x69: scancode = KeyboardKeyEnd; break;
|
||||
case 0x6B: scancode = KeyboardKeyLeft; break;
|
||||
case 0x6C: scancode = KeyboardKeyHome; break;
|
||||
case 0x70: scancode = KeyboardKeyInsert; break;
|
||||
case 0x71: scancode = KeyboardKeyDelete; break;
|
||||
case 0x72: scancode = KeyboardKeyDown; break;
|
||||
case 0x74: scancode = KeyboardKeyRight; break;
|
||||
case 0x75: scancode = KeyboardKeyUp; break;
|
||||
case 0x7A: scancode = KeyboardKeyPageDown; break;
|
||||
case 0x7C: scancode = KeyboardKeyPrintScreen; break;
|
||||
case 0x7D: scancode = KeyboardKeyPageUp; break;
|
||||
}
|
||||
|
||||
// Pause/break
|
||||
if (KeyboardModifiers & 4)
|
||||
{
|
||||
KeyboardSetKeyStatus(KeyboardKeyPause, 1 - (KeyboardModifiers & 1));
|
||||
|
||||
if (scancode == 0x77) KeyboardModifiers = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
KeyboardSetKeyStatus(scancode, 1 - (KeyboardModifiers & 1));
|
||||
|
||||
// Give functions something to wait for :P
|
||||
KeyboardLastScancode = scancode;
|
||||
KeyboardLastStatus = KeyboardModifiers;
|
||||
KeyboardModifiers &= ~7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void KeyboardHandler (_RegsStack32* UNUSED(r))
|
||||
{
|
||||
// Get scancode from keyboard
|
||||
uint8 scancode = inportb(0x60);
|
||||
|
||||
// Process scancode
|
||||
_process_scancode(scancode);
|
||||
|
||||
// LED update
|
||||
if (KeyboardModifiers & (1<<6))
|
||||
{
|
||||
KeyboardSetLEDs(KeyboardModifiers & (1<<3), KeyboardModifiers & (1<<4), KeyboardModifiers & (1<<5));
|
||||
KeyboardModifiers &= ~(1<<6);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps)
|
||||
{
|
||||
uint8 status = 0;
|
||||
status |= (scroll > 0);
|
||||
status |= (num > 0) << 1;
|
||||
status |= (caps > 0) << 2;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, KeybCmdWriteLED);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, status);
|
||||
}
|
||||
|
||||
|
||||
/***************************************
|
||||
* Set repeat rate/delay *
|
||||
***************************************
|
||||
Values for inter-character delay (bits 4-0)
|
||||
(characters per second; default is 10.9)
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||
----+----+----+----+----+----+----+----+----
|
||||
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
|
||||
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
|
||||
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
|
||||
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
|
||||
|
||||
Values for delay:
|
||||
(miliseconds; default is 500)
|
||||
0 | 1 | 2 | 3
|
||||
-----+-----+-----+-----
|
||||
250 | 500 | 750 | 1000
|
||||
|
||||
***************************************/
|
||||
void KeyboardSetRepeatRate(uint8 rate, uint8 delay)
|
||||
{
|
||||
if (rate>3 || delay>31) return;
|
||||
|
||||
uint8 out = rate<<5 | delay;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdSetRepeatDelay);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, out);
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Set scancode set *
|
||||
***************************************
|
||||
1 Set to scancode set 1
|
||||
2 Set to scancode set 2
|
||||
3 Set to scancode set 3
|
||||
***************************************/
|
||||
void KeyboardSetScancodeSet(uint8 set)
|
||||
{
|
||||
if (set>3 || set <= 0) return;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, KeybCmdSetScancodeSet);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x60, set);
|
||||
|
||||
KeyboardScancodeSet = set;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardWaitOutport()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
void KeyboardWaitInport()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallA()
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, KeybCmdReset); // Reset kb
|
||||
|
||||
// Initialize variables
|
||||
KeyboardLastStatus = 0;
|
||||
KeyboardModifiers = 0;
|
||||
|
||||
int32 i;
|
||||
for (i = 0; i < 16; i++)
|
||||
KeyState[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallB()
|
||||
{
|
||||
// Wait for BAT test results
|
||||
KeyboardWaitInport();
|
||||
|
||||
unsigned char temp;
|
||||
do temp = inportb(0x60);
|
||||
while (temp!=0xAA && temp!=0xFC);
|
||||
|
||||
// Error
|
||||
if (temp == 0xFC) return;
|
||||
|
||||
// Set new repeat rate
|
||||
KeyboardSetRepeatRate(1, 11);
|
||||
|
||||
// Set scancode set 2
|
||||
KeyboardSetScancodeSet(2); // Set new scancode set
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x20); // Get "Command unsigned char"
|
||||
|
||||
do { temp = inportb(0x60);
|
||||
} while (temp==0xFA || temp==0xAA);
|
||||
|
||||
temp &= ~(1<<6); // Unset bit6: disable conversion
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x60); // Function to write cmd unsigned char
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, temp); // Send it
|
||||
}
|
||||
52
Kernel/hal/keyboard/keyboard.h
Normal file
52
Kernel/hal/keyboard/keyboard.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __KEYBOARD__H
|
||||
#define __KEYBOARD__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern const char KeyboardMap[0x80];
|
||||
extern const char KeyboardMapShift[0x80];
|
||||
extern volatile uint8 KeyboardLastStatus;
|
||||
extern volatile uint8 KeyboardLastScancode;
|
||||
|
||||
extern void KeyboardSetKeyStatus (uint8 scancode, uint8 status);
|
||||
extern uint8 KeyboardGetKeyStatus (uint8 scancode);
|
||||
extern void KeyboardHandler (_RegsStack32 *r);
|
||||
extern void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps);
|
||||
/***************************************
|
||||
* Set repeat rate/delay *
|
||||
***************************************
|
||||
Values for inter-character delay (bits 4-0)
|
||||
(characters per second; default is 10.9)
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||
----+----+----+----+----+----+----+----+----
|
||||
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
|
||||
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
|
||||
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
|
||||
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
|
||||
|
||||
Values for delay:
|
||||
(miliseconds; default is 500)
|
||||
0 | 1 | 2 | 3
|
||||
-----+-----+-----+-----
|
||||
250 | 500 | 750 | 1000
|
||||
|
||||
***************************************/
|
||||
extern void KeyboardSetRepeatRate(uint8 rate, uint8 delay);
|
||||
|
||||
/***************************************
|
||||
* Set scancode set *
|
||||
***************************************
|
||||
1 Set to scancode set 1
|
||||
2 Set to scancode set 2
|
||||
3 Set to scancode set 3
|
||||
***************************************/
|
||||
extern void KeyboardSetScancodeSet(uint8 set);
|
||||
|
||||
extern void KeyboardWaitOutport();
|
||||
extern void KeyboardWaitInport();
|
||||
|
||||
extern void KeyboardInstallA();
|
||||
extern void KeyboardInstallB();
|
||||
|
||||
#endif
|
||||
|
||||
116
Kernel/hal/mouse/mouse.c
Normal file
116
Kernel/hal/mouse/mouse.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <stdio.h>
|
||||
#include <debugio.h>
|
||||
#include "mouse.h"
|
||||
#include "../keyboard/keyboard.h"
|
||||
|
||||
uint8 MouseCycle = 0;
|
||||
uint8 MouseCycleExpected = 3;
|
||||
uint8 Packets[4];
|
||||
|
||||
Point MousePosition = {0,0};
|
||||
Point MouseMinimumPosition = {0,0}, MouseMaximumPosition = {80, 25};
|
||||
Point Prev = {0,0};
|
||||
|
||||
#define SpeedLimit 0x8
|
||||
|
||||
// IRQ12
|
||||
void MouseHandler (_RegsStack32* UNUSED(r))
|
||||
{
|
||||
uint8 data = inportb(0x60);
|
||||
Point delta;
|
||||
|
||||
if (MouseCycle == 0 && (data == 0 || data == 0xFA || data == 0xFF || data == 0xAA)) return;
|
||||
Packets[MouseCycle++] = data;
|
||||
|
||||
// Cycle ended
|
||||
if (MouseCycle >= MouseCycleExpected)
|
||||
{
|
||||
MouseCycle = 0;
|
||||
if (Packets[0] & 0xC0) return; // Discard packet
|
||||
|
||||
// Update X position
|
||||
if (Packets[0] & 0x10) delta.X = (int32) (Packets[1] | 0xFFFFFF00);
|
||||
else delta.X = (int32) Packets[1];
|
||||
|
||||
// Update Y position
|
||||
if (Packets[0] & 0x20) delta.Y = -1 * (int32) (Packets[2] | 0xFFFFFF00);
|
||||
else delta.Y = -1 * (int32)Packets[2];
|
||||
|
||||
if (delta.X >= SpeedLimit) delta.X = SpeedLimit;
|
||||
if (delta.X <= -SpeedLimit) delta.X = -SpeedLimit;
|
||||
if (delta.Y >= SpeedLimit) delta.Y = SpeedLimit;
|
||||
if (delta.Y <= -SpeedLimit) delta.Y = -SpeedLimit;
|
||||
|
||||
MousePosition.X += delta.X;
|
||||
MousePosition.Y += delta.Y;
|
||||
|
||||
// Check limits
|
||||
if (MousePosition.X < MouseMinimumPosition.X) MousePosition.X = MouseMinimumPosition.X;
|
||||
if (MousePosition.Y < MouseMinimumPosition.Y) MousePosition.Y = MouseMinimumPosition.Y;
|
||||
if (MousePosition.X >= MouseMaximumPosition.X) MousePosition.X = MouseMaximumPosition.X - 1;
|
||||
if (MousePosition.Y >= MouseMaximumPosition.Y) MousePosition.Y = MouseMaximumPosition.Y - 1;
|
||||
|
||||
/* TESTING ONLY */
|
||||
ConsoleSetColor(Prev, 0xFF - ConsoleGetColor(Prev));
|
||||
ConsoleSetColor(MousePosition, 0xFF - ConsoleGetColor(MousePosition));
|
||||
Prev = MousePosition;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MouseSendCommand(uint8 command)
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0xD4);
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, command);
|
||||
}
|
||||
|
||||
uint8 MouseReadData ()
|
||||
{
|
||||
KeyboardWaitInport();
|
||||
return inportb(0x60);
|
||||
}
|
||||
|
||||
void MouseInstall()
|
||||
{
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0xA8);
|
||||
|
||||
// Enable interrupts
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x20);
|
||||
|
||||
KeyboardWaitInport();
|
||||
uint8 temp = inportb(0x60) | 2;
|
||||
temp &= ~0x20;
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x64, 0x60);
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb(0x60, temp);
|
||||
|
||||
// Reset mouse, and enable it
|
||||
MouseSendCommand(MouseCommandReset);
|
||||
MouseReadData(); MouseReadData();
|
||||
|
||||
MouseSendCommand(MouseCommandSetDefaults);
|
||||
MouseReadData(); // Read ack
|
||||
|
||||
MouseSendCommand(MouseCommandEnableDataReporting);
|
||||
MouseReadData(); // Read ack
|
||||
|
||||
}
|
||||
|
||||
void MouseSetLimits (Point min_pos, Point max_pos)
|
||||
{
|
||||
MouseMinimumPosition = min_pos;
|
||||
MouseMaximumPosition = max_pos;
|
||||
}
|
||||
|
||||
MouseState MouseGetState()
|
||||
{
|
||||
MouseState ret = { Packets[0] & 0x7, MousePosition};
|
||||
return ret;
|
||||
}
|
||||
36
Kernel/hal/mouse/mouse.h
Normal file
36
Kernel/hal/mouse/mouse.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef __MOUSE__H
|
||||
#define __MOUSE__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 Buttons;
|
||||
Point Position;
|
||||
} MouseState;
|
||||
|
||||
enum MouseCommands
|
||||
{
|
||||
MouseCommandReset = 0xFF,
|
||||
MouseCommandResend = 0xFE,
|
||||
MouseCommandSetDefaults = 0xF6,
|
||||
MouseCommandDisableDataReporting = 0xF5,
|
||||
MouseCommandEnableDataReporting = 0xF4,
|
||||
MouseCommandSetSampleRate = 0xF3,
|
||||
MouseCommandGetDeviceID = 0xF2,
|
||||
MouseCommandSetRemoteMode = 0xF0,
|
||||
MouseCommandSetWrapMode = 0xEE,
|
||||
MouseCommandReadData = 0xEB,
|
||||
MouseCommandSetStreamMode = 0xEA,
|
||||
MouseCommandStatusRequest = 0xE9,
|
||||
MouseCommandSetResolution = 0xE8,
|
||||
MouseCommandSetScaling_2_1 = 0xE7,
|
||||
MouseCommandSetScaling_1_1 = 0xE6
|
||||
};
|
||||
|
||||
extern void MouseInstall();
|
||||
extern void MouseHandler (_RegsStack32 *r);
|
||||
extern void MouseSetLimits (Point min_pos, Point max_pos);
|
||||
extern MouseState MouseGetState();
|
||||
|
||||
#endif
|
||||
27
Kernel/hal/sysinfo.c
Normal file
27
Kernel/hal/sysinfo.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* sysinfo.c
|
||||
*
|
||||
* Provides information about system, and useful utilities
|
||||
*
|
||||
* Created on: Aug 17, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <multiboot.h>
|
||||
#include <debugio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <../drivers/cmos/cmos.h>
|
||||
|
||||
#include "keyboard/keyboard.h"
|
||||
void SystemReboot()
|
||||
{
|
||||
Log("Rebooting system...\n");
|
||||
|
||||
KeyboardWaitOutport();
|
||||
outportb (0x64, 0xFE);
|
||||
|
||||
asm("cli");
|
||||
asm("hlt");
|
||||
}
|
||||
40
Kernel/hal/vfs.c
Normal file
40
Kernel/hal/vfs.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#include<fileio.h>
|
||||
#include<storage.h>
|
||||
|
||||
#define MAX_FS_COUNT 64
|
||||
|
||||
uint32 FsRead(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
|
||||
{
|
||||
if (node->Read != NULL) return node->Read(node, offset, size, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 FsWrite(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
|
||||
{
|
||||
if (node->Write != NULL) return node->Write(node, offset, size, buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FsOpen(FsNode *node, uint8 read, uint8 write)
|
||||
{
|
||||
if (node->Open != NULL) return node->Open(node, read, write);
|
||||
}
|
||||
|
||||
void FsClose(FsNode *node)
|
||||
{
|
||||
if (node->Close != NULL) return node->Close();
|
||||
}
|
||||
|
||||
DirectoryEntry *FsReadDir(FsNode *node, uint32 index)
|
||||
{
|
||||
if (node->ReadDir != NULL && (node->Flags&7) == FsDirectory)
|
||||
return node->ReadDir(node, index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FsNode *FsFindDir(FsNode *node, char *name)
|
||||
{
|
||||
if (node->FindDir != NULL && (node->Flags&7) == FsDirectory)
|
||||
return node->FindDir(node, name);
|
||||
return NULL;
|
||||
}
|
||||
31
Kernel/include/ctype.h
Normal file
31
Kernel/include/ctype.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __CTYPE_H
|
||||
#define __CTYPE_H
|
||||
|
||||
extern unsigned char _ctype[];
|
||||
|
||||
#define _CTYPE_ISCONTROL 0x01 // 0000 0001
|
||||
#define _CTYPE_ISSPACE 0x02 // 0000 0010
|
||||
#define _CTYPE_ISBLANK 0x04 // 0000 0100 etc.
|
||||
#define _CTYPE_ISPUNCT 0x08
|
||||
#define _CTYPE_ISDIGIT 0x10
|
||||
#define _CTYPE_ISHEX 0x20
|
||||
#define _CTYPE_ISUPPER 0x40
|
||||
#define _CTYPE_ISLOWER 0x80
|
||||
|
||||
#define isalnum(c) (_ctype[(int)c+1] & (_CTYPE_ISLOWER | _CTYPE_ISUPPER | _CTYPE_ISDIGIT))
|
||||
#define isalpha(c) (_ctype[(int)c+1] & (_CTYPE_ISLOWER | _CTYPE_ISUPPER))
|
||||
#define isblank(c) (_ctype[(int)c+1] & (_CTYPE_ISBLANK))
|
||||
#define iscntrl(c) (_ctype[(int)c+1] & (_CTYPE_ISCONTROL))
|
||||
#define isdigit(c) (_ctype[(int)c+1] & (_CTYPE_ISDIGIT))
|
||||
#define isgraph(c) (_ctype[(int)c+1] & (_CTYPE_ISLOWER | _CTYPE_ISUPPER | _CTYPE_ISDIGIT | _CTYPE_ISPUNCT))
|
||||
#define islower(c) (_ctype[(int)c+1] & (_CTYPE_ISLOWER))
|
||||
#define isprint(c) (_ctype[(int)c+1] & (_CTYPE_ISLOWER | _CTYPE_ISUPPER | _CTYPE_ISDIGIT | _CTYPE_ISPUNCT | _CTYPE_ISBLANK))
|
||||
#define ispunct(c) (_ctype[(int)c+1] & (_CTYPE_ISPUNCT))
|
||||
#define isspace(c) (_ctype[(int)c+1] & (_CTYPE_ISSPACE))
|
||||
#define isupper(c) (_ctype[(int)c+1] & (_CTYPE_ISUPPER))
|
||||
#define isxdigit(c) (_ctype[(int)c+1] & (_CTYPE_ISHEX))
|
||||
|
||||
extern int toupper(int c);
|
||||
extern int tolower(int c);
|
||||
|
||||
#endif
|
||||
88
Kernel/include/debugio.h
Normal file
88
Kernel/include/debugio.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef __DEBUGIO__H
|
||||
#define __DEBUGIO__H
|
||||
|
||||
#include <types.h>
|
||||
#include <settings.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
enum Colors
|
||||
{
|
||||
ColorBlack = 0x0,
|
||||
ColorBlue = 0x1,
|
||||
ColorGreen = 0x2,
|
||||
ColorCyan = 0x3,
|
||||
ColorRed = 0x4,
|
||||
ColorMagenta = 0x5,
|
||||
ColorBrown = 0x6,
|
||||
ColorLightGray = 0x7,
|
||||
ColorDarkGray = 0x8,
|
||||
ColorLightBlue = 0x9,
|
||||
ColorLightGreen = 0xA,
|
||||
ColorLightCyan = 0xB,
|
||||
ColorLightRed = 0xC,
|
||||
ColorLightMagenta = 0xD,
|
||||
ColorYellow = 0xE,
|
||||
ColorWhite = 0xF
|
||||
};
|
||||
|
||||
extern uint8 Color (uint8 back, uint8 fore);
|
||||
|
||||
// Cursor position
|
||||
extern Point ConsoleGetCursor();
|
||||
extern void ConsoleSetCursor(Point p);
|
||||
extern void ConsoleCursorGoto(Point p);
|
||||
|
||||
extern void ConsoleCursorIncreasePos (int32 delta);
|
||||
extern void ConsoleCursorNewline();
|
||||
extern void ConsoleCursorUpdateHardware();
|
||||
|
||||
// Get/set properties
|
||||
extern void ConsoleSetDefaultColor(uint8 color);
|
||||
extern uint8 ConsoleGetDefaultColor ();
|
||||
extern UPoint ConsoleGetSize();
|
||||
|
||||
extern void ConsoleSetChar(Point pos, char c);
|
||||
extern void ConsoleSetColor(Point pos, uint8 color);
|
||||
extern char ConsoleGetChar(Point pos);
|
||||
extern uint8 ConsoleGetColor (Point pos);
|
||||
|
||||
|
||||
// Basic console operations
|
||||
extern void ConsoleClear();
|
||||
extern void ConsoleScroll (uint32 lines);
|
||||
|
||||
// Console write operations
|
||||
extern void ConsoleWriteChar (char c);
|
||||
extern void ConsoleWriteString (string s);
|
||||
extern int32 ConsoleWrite (string format, ...);
|
||||
|
||||
// Console read operations
|
||||
extern void ConsoleReadString (string s, int32 buffer_size, char end_char);
|
||||
|
||||
// Console main loop
|
||||
extern void ConsoleMain();
|
||||
|
||||
// Debug print
|
||||
#if VERBOSE_MODE==1
|
||||
#define Log(...) ConsoleWrite(__VA_ARGS__)
|
||||
#else
|
||||
#define Log(...)
|
||||
#endif
|
||||
|
||||
// Error print
|
||||
#if VERBOSE_ERROR==1
|
||||
#define Error(...) ConsoleWrite(__VA_ARGS__)
|
||||
#else
|
||||
#define Error(...)
|
||||
#endif
|
||||
|
||||
// Panic
|
||||
#if VERBOSE_PANIC==1
|
||||
#define Panic(...) { ConsoleWrite("%#[PANIC] KERNEL PANIC: ", ColorLightRed); \
|
||||
ConsoleWrite(__VA_ARGS__); \
|
||||
asm volatile ("cli\nhlt"); }
|
||||
#else
|
||||
#define Panic(...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
70
Kernel/include/fileio.h
Normal file
70
Kernel/include/fileio.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* fileio.h
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef FILEIO_H_
|
||||
#define FILEIO_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
enum FsFlags
|
||||
{
|
||||
FsFile = 0x1,
|
||||
FsDirectory = 0x2,
|
||||
FsCharDevice = 0x3,
|
||||
FsBlockDevice = 0x4,
|
||||
FsPipe = 0x5,
|
||||
FsSymbolLink = 0x6,
|
||||
FsMountPoint = 0x8
|
||||
};
|
||||
|
||||
typedef uint32 (*ReadRoutine)(struct _FsNode*, uint32, uint32, uint8*);
|
||||
typedef uint32 (*WriteRoutine)(struct _FsNode*, uint32, uint32, uint8*);
|
||||
typedef void (*OpenRoutine)(struct _FsNode*);
|
||||
typedef void (*CloseRoutine)(struct _FsNode*);
|
||||
typedef struct _DirectoryEntry (*ReadDirRoutine)(struct _FsNode*,uint32);
|
||||
typedef struct _FsNode* (*FindDirRoutine)(struct _FsNode*,char *name);
|
||||
|
||||
typedef struct _FsNode
|
||||
{
|
||||
char Name[128]; // The filename.
|
||||
uint32 Permissions; // The permissions mask.
|
||||
uint32 UserId; // The owning user.
|
||||
uint32 GroupId; // The owning group.
|
||||
uint32 Flags; // Includes the node type. See enum above.
|
||||
uint32 INode; // This is device-specific - provides a way for a filesystem to identify files.
|
||||
uint32 Length; // Size of the file, in bytes.
|
||||
uint32 Implementation; // An implementation-defined number.
|
||||
ReadRoutine Read;
|
||||
WriteRoutine Write;
|
||||
OpenRoutine Open;
|
||||
CloseRoutine Close;
|
||||
ReadDirRoutine ReadDir;
|
||||
FindDirRoutine FindDir;
|
||||
struct _FsNode *Ptr; // Used by mountpoints and symlinks.
|
||||
} FsNode;
|
||||
|
||||
|
||||
typedef struct _DirectoryEntry
|
||||
{
|
||||
char Name[128];
|
||||
uint32 INode;
|
||||
} DirectoryEntry;
|
||||
|
||||
|
||||
extern uint32 FsRead(FsNode *node, uint32 offset, uint32 size, uint8 *buffer);
|
||||
extern uint32 FsWrite(FsNode *node, uint32 offset, uint32 size, uint8 *buffer);
|
||||
extern void FsOpen(FsNode *node, uint8 read, uint8 write);
|
||||
extern void FsClose(FsNode *node);
|
||||
extern DirectoryEntry *FsReadDir(FsNode *node, uint32 index);
|
||||
extern FsNode *FsFindDir(FsNode *node, char *name);
|
||||
|
||||
#ifdef NEVER
|
||||
void VfsRegisterFilesys();
|
||||
void VfsMount();
|
||||
#endif
|
||||
|
||||
#endif /* FILEIO_H_ */
|
||||
97
Kernel/include/memory-add.h
Normal file
97
Kernel/include/memory-add.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* memory-add.h
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_ADD_H_
|
||||
#define MEMORY_ADD_H_
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <debugio.h>
|
||||
|
||||
/***************************************************
|
||||
* Paging *
|
||||
***************************************************/
|
||||
typedef uint32 Page;
|
||||
|
||||
enum PageFlags
|
||||
{
|
||||
PagePresent = 0x1,
|
||||
PageWriteable = 0x2,
|
||||
PageUser = 0x4,
|
||||
PageWriteThough = 0x8,
|
||||
PageNotCacheable = 0x10,
|
||||
PageAccessed = 0x20,
|
||||
PageDirty = 0x40,
|
||||
PagePAT = 0x80,
|
||||
PageCpuGlobal = 0x100,
|
||||
PageLvl4Global = 0x200,
|
||||
PageFrame = 0xFFFFF000
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
Page Pages[1024];
|
||||
} PageTable;
|
||||
|
||||
typedef struct {
|
||||
PageTable* Tables[1024];
|
||||
uint32 TablesPhysical[1024];
|
||||
uint32 PhysicalAddr;
|
||||
} PageDirectory;
|
||||
|
||||
extern PageDirectory* CurrentDirectory;
|
||||
extern PageDirectory* KernelDirectory;
|
||||
|
||||
extern void PagingInitialize(uint32 SystemMemory);
|
||||
extern void PagingSwitchPageDirectory (PageDirectory* dir);
|
||||
extern Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir);
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Physical memory manager *
|
||||
***************************************************/
|
||||
extern uint32 TotalFrames;
|
||||
extern uint32 TotalMemory;
|
||||
extern uint32 UsedFrames;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Memory heap *
|
||||
***************************************************/
|
||||
typedef struct
|
||||
{
|
||||
OrderedArray Index;
|
||||
uint32 StartAddress, EndAddress, MaxAddress;
|
||||
// bit 0: supervisor-only bit 1: read-only
|
||||
uint8 Flags;
|
||||
} MemHeap;
|
||||
|
||||
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 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);
|
||||
|
||||
|
||||
#define LogMem(...) { Log("%#[Mem] ", ColorLightCyan); Log(__VA_ARGS__); }
|
||||
#define ErrorMem(...) { Error("%#[Mem] ", ColorLightCyan); Error(__VA_ARGS__); }
|
||||
|
||||
|
||||
#endif /* MEMORY_ADD_H_ */
|
||||
96
Kernel/include/memory-add.h~
Normal file
96
Kernel/include/memory-add.h~
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* memory-add.h
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_ADD_H_
|
||||
#define MEMORY_ADD_H_
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include <debugio.h>
|
||||
|
||||
/***************************************************
|
||||
* Paging *
|
||||
***************************************************/
|
||||
typedef uint32 Page;
|
||||
|
||||
enum PageFlags
|
||||
{
|
||||
PagePresent = 0x1,
|
||||
PageWriteable = 0x2,
|
||||
PageUser = 0x4,
|
||||
PageWriteThough = 0x8,
|
||||
PageNotCacheable = 0x10,
|
||||
PageAccessed = 0x20,
|
||||
PageDirty = 0x40,
|
||||
PagePAT = 0x80,
|
||||
PageCpuGlobal = 0x100,
|
||||
PageLvl4Global = 0x200,
|
||||
PageFrame = 0xFFFFF000
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
Page Pages[1024];
|
||||
} PageTable;
|
||||
|
||||
typedef struct {
|
||||
PageTable* Tables[1024];
|
||||
uint32 TablesPhysical[1024];
|
||||
uint32 PhysicalAddr;
|
||||
} PageDirectory;
|
||||
|
||||
extern PageDirectory* CurrentDirectory;
|
||||
extern PageDirectory* KernelDirectory;
|
||||
|
||||
extern void PagingInitialize(uint32 SystemMemory);
|
||||
extern void PagingSwitchPageDirectory (PageDirectory* dir);
|
||||
extern Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir);
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Physical memory manager *
|
||||
***************************************************/
|
||||
extern uint32 TotalFrames;
|
||||
extern uint32 TotalMemory;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Memory heap *
|
||||
***************************************************/
|
||||
typedef struct
|
||||
{
|
||||
OrderedArray Index;
|
||||
uint32 StartAddress, EndAddress, MaxAddress;
|
||||
// bit 0: supervisor-only bit 1: read-only
|
||||
uint8 Flags;
|
||||
} MemHeap;
|
||||
|
||||
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 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);
|
||||
|
||||
|
||||
#define LogMem(...) { Log("%#[Mem] ", ColorLightCyan); Log(__VA_ARGS__); }
|
||||
#define ErrorMem(...) { Error("%#[Mem] ", ColorLightCyan); Error(__VA_ARGS__); }
|
||||
|
||||
|
||||
#endif /* MEMORY_ADD_H_ */
|
||||
29
Kernel/include/memory.h
Normal file
29
Kernel/include/memory.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __MEMORY__H
|
||||
#define __MEMORY__H
|
||||
|
||||
#include <types.h>
|
||||
#include <settings.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
/***************************************************
|
||||
* Basic memory operations: alloc, free *
|
||||
***************************************************/
|
||||
extern void* kmalloc (uint32 size);
|
||||
extern void* kmalloc_a (uint32 size);
|
||||
extern void* kmalloc_p (uint32 size, uint32* phys);
|
||||
extern void* kmalloc_ap (uint32 size, uint32* phys);
|
||||
extern void kfree (void* addr);
|
||||
|
||||
extern void MemoryTempInitialize (uint32 kernel_end);
|
||||
extern void MemoryInitialize (MultibootInfo* info);
|
||||
|
||||
extern uint32 MemoryGetTotal();
|
||||
extern uint32 MemoryGetFree(); // Returns total free physical memory in kilobytes
|
||||
extern uint32 MemoryGetUsed(); // Total used physical memory in kbytes
|
||||
extern uint32 MemoryGetFrameSize(); // Same as above functions, but in frames
|
||||
extern uint32 MemoryGetFramesTotal();
|
||||
extern uint32 MemoryGetFramesUsed();
|
||||
extern uint32 MemoryGetFramesFree();
|
||||
|
||||
|
||||
#endif
|
||||
29
Kernel/include/memory.h~
Normal file
29
Kernel/include/memory.h~
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __MEMORY__H
|
||||
#define __MEMORY__H
|
||||
|
||||
#include <types.h>
|
||||
#include <settings.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
/***************************************************
|
||||
* Basic memory operations: alloc, free *
|
||||
***************************************************/
|
||||
extern void* kmalloc (uint32 size);
|
||||
extern void* kmalloc_a (uint32 size);
|
||||
extern void* kmalloc_p (uint32 size, uint32* phys);
|
||||
extern void* kmalloc_ap (uint32 size, uint32* phys);
|
||||
extern void kfree (void* addr);
|
||||
|
||||
extern void MemoryTempInitialize (uint32 kernel_end);
|
||||
extern void MemoryInitialize (MultibootInfo* info);
|
||||
|
||||
extern uint32 MemoryGetTotal();
|
||||
extern uint32 MemoryGetFree(); // Returns total free physical memory in bytes
|
||||
extern uint32 MemoryGetUsed(); // Total used physical memory in bytes
|
||||
extern uint32 MemoryGetFrameSize(); // Same as above functions, but in frames
|
||||
extern uint32 MemoryGetFramesTotal();
|
||||
extern uint32 MemoryGetFramesUsed();
|
||||
extern uint32 MemoryGetFramesFree();
|
||||
|
||||
|
||||
#endif
|
||||
119
Kernel/include/multiboot.h
Normal file
119
Kernel/include/multiboot.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* multiboot.h
|
||||
*
|
||||
* Created on: Aug 17, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_H_
|
||||
#define MULTIBOOT_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// Flags to be set in the 'flags' member of the multiboot info structure.
|
||||
#define MultibootInfo_MEMORY 0x00000001 // is there basic lower/upper memory information?
|
||||
#define MultibootInfo_BOOTDEV 0x00000002 // is there a boot device set?
|
||||
#define MultibootInfo_CMDLINE 0x00000004 // is the command-line defined?
|
||||
#define MultibootInfo_MODS 0x00000008 // are there modules to do something with?
|
||||
|
||||
// These next two are mutually exclusive
|
||||
#define MultibootInfo_AOUT_SYMS 0x00000010 // is there a symbol table loaded?
|
||||
#define MultibootInfo_ELF_SHDR 0X00000020 // is there an ELF section header table?
|
||||
|
||||
|
||||
#define MultibootInfo_MEM_MAP 0x00000040 // is there a full memory map?
|
||||
#define MultibootInfo_DRIVE_INFO 0x00000080 // Is there drive info?
|
||||
#define MultibootInfo_CONFIG_TABLE 0x00000100 // Is there a config table?
|
||||
#define MultibootInfo_BOOT_LOADER_NAME 0x00000200 // Is there a boot loader name?
|
||||
#define MultibootInfo_APM_TABLE 0x00000400 // Is there a APM table?
|
||||
#define MultibootInfo_VIDEO_INFO 0x00000800 // Is there video information?
|
||||
|
||||
|
||||
// The symbol table for a.out.
|
||||
typedef struct
|
||||
{
|
||||
uint32 TableSize;
|
||||
uint32 StrSize;
|
||||
uint32 Address;
|
||||
uint32 Reserved;
|
||||
} MultibootAoutSymbolTable;
|
||||
|
||||
|
||||
// The section header table for ELF.
|
||||
typedef struct
|
||||
{
|
||||
uint32 Number;
|
||||
uint32 Size;
|
||||
uint32 Address;
|
||||
uint32 Shndx;
|
||||
} MultibootElfSectionHeaderTable;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Flags; // Multiboot info version number
|
||||
|
||||
uint32 MemoryLower; // Available memory from BIOS
|
||||
uint32 MemoryUpper;
|
||||
|
||||
uint32 BootDevice; // "root" partition
|
||||
|
||||
uint32 CommandLine; // Kernel command line
|
||||
|
||||
uint32 ModulesCount; // Boot-Module list
|
||||
uint32 ModulesAddress;
|
||||
|
||||
union
|
||||
{
|
||||
MultibootAoutSymbolTable AoutSymbols;
|
||||
MultibootElfSectionHeaderTable ElfSectionHeaderTable;
|
||||
} Symbols;
|
||||
|
||||
uint32 MemoryMapLength; // Memory Mapping buffer
|
||||
uint32 MemoryMapAddress;
|
||||
|
||||
uint32 DrivesLength; // Drive Info buffer
|
||||
uint32 DrivesAddress;
|
||||
|
||||
uint32 ConfigurationTable; // ROM configuration table
|
||||
|
||||
uint32 BootLoaderName; // Boot Loader Name
|
||||
|
||||
uint32 ApmTable; // APM table
|
||||
|
||||
uint32 VbeControlInfo; // Video
|
||||
uint32 VbeModeInfo;
|
||||
uint16 VbeMode;
|
||||
uint16 VbeInterfaceSegment;
|
||||
uint16 VbeInterfaceOffset;
|
||||
uint16 VbeInterfaceLength;
|
||||
} MultibootInfo;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Size;
|
||||
uint64 Address;
|
||||
uint64 Length;
|
||||
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
|
||||
uint32 Type;
|
||||
} __attribute__((packed)) MultibootMemoryMapEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive
|
||||
uint32 ModuleStart;
|
||||
uint32 ModuleEnd;
|
||||
|
||||
// Module command line
|
||||
uint32 CommandLine;
|
||||
|
||||
// padding to take it to 16 bytes (must be zero)
|
||||
uint32 _Padding;
|
||||
} MultibootModule;
|
||||
|
||||
|
||||
#endif
|
||||
38
Kernel/include/settings.h
Normal file
38
Kernel/include/settings.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* settings.h
|
||||
*
|
||||
* Created on: Aug 16, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef SETTINGS_H_
|
||||
#define SETTINGS_H_
|
||||
|
||||
// OS info
|
||||
#define OS_STRING "lux"
|
||||
#define OS_VERSION "0.1 [pre-Alpha]"
|
||||
#define OS_BUILD_DATE __DATE__
|
||||
#define OS_BUILD_TIME __TIME__
|
||||
|
||||
#include <version.h>
|
||||
|
||||
// Logger
|
||||
#define VERBOSE_MODE 1
|
||||
#define VERBOSE_ERROR 1
|
||||
#define VERBOSE_PANIC 1
|
||||
|
||||
|
||||
// Clock
|
||||
#define PIT_FREQUENCY 100
|
||||
|
||||
// Console
|
||||
#define CONSOLE_MAX_PARAMS 32
|
||||
#define CONSOLE_DEFAULT_COLOR 0x7
|
||||
|
||||
// Memory manager
|
||||
#define KERNEL_HEAP_START 0xC0000000
|
||||
#define KERNEL_HEAP_INITIAL_SIZE 0x100000
|
||||
#define KERNEL_HEAP_END (KERNEL_HEAP_START + KERNEL_HEAP_INITIAL_SIZE)
|
||||
|
||||
|
||||
#endif /* SETTINGS_H_ */
|
||||
37
Kernel/include/settings.h~
Normal file
37
Kernel/include/settings.h~
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* settings.h
|
||||
*
|
||||
* Created on: Aug 16, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef SETTINGS_H_
|
||||
#define SETTINGS_H_
|
||||
|
||||
// OS info
|
||||
#define OS_STRING "lux"
|
||||
#define OS_VERSION "0.1 [pre-Alpha]"
|
||||
#define OS_BUILD_DATE __DATE__
|
||||
#define OS_BUILD_TIME __TIME__
|
||||
|
||||
#include <version.h>
|
||||
|
||||
// Logger
|
||||
#define VERBOSE_MODE 1
|
||||
#define VERBOSE_ERROR 1
|
||||
#define VERBOSE_PANIC 1
|
||||
|
||||
|
||||
// Clock
|
||||
#define PIT_FREQUENCY 100
|
||||
|
||||
// Console
|
||||
#define CONSOLE_MAX_PARAMS 32
|
||||
#define CONSOLE_DEFAULT_COLOR 0x7
|
||||
|
||||
// Memory manager
|
||||
#define KERNEL_HEAP_START 0xC0000000
|
||||
#define KERNEL_HEAP_END 0xCFFFF000
|
||||
#define KERNEL_HEAP_INITIAL_SIZE 0x100000
|
||||
|
||||
#endif /* SETTINGS_H_ */
|
||||
38
Kernel/include/stdarg.h
Normal file
38
Kernel/include/stdarg.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef __STDARG__H
|
||||
#define __STDARG__H
|
||||
|
||||
#include <va_list.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* width of stack == width of int */
|
||||
#define STACKITEM int
|
||||
|
||||
/* round up width of objects pushed on stack. The expression before the
|
||||
& ensures that we get 0 for objects of size 0. */
|
||||
#define VA_SIZE(TYPE) \
|
||||
((sizeof(TYPE) + sizeof(STACKITEM) - 1) \
|
||||
& ~(sizeof(STACKITEM) - 1))
|
||||
|
||||
/* &(LASTARG) points to the LEFTMOST argument of the function call
|
||||
(before the ...) */
|
||||
#define va_start(AP, LASTARG) \
|
||||
(AP=((va_list)&(LASTARG) + VA_SIZE(LASTARG)))
|
||||
|
||||
/* nothing for va_end */
|
||||
#define va_end(AP)
|
||||
|
||||
#define va_arg(AP, TYPE) \
|
||||
(AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
29
Kernel/include/stdio.h
Normal file
29
Kernel/include/stdio.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __STDIO__H
|
||||
#define __STDIO__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define inb(port) inportb(port)
|
||||
#define outb(port) outportb(port)
|
||||
|
||||
extern uint8 inportb (uint16 _port);
|
||||
|
||||
static inline void outportb (uint16 _port, uint8 _data) {
|
||||
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
||||
}
|
||||
|
||||
static inline void iowait() {
|
||||
asm volatile ("outb %al, $0x80");
|
||||
}
|
||||
|
||||
static inline void MagicBreakpoint()
|
||||
{
|
||||
asm volatile ("xchg %bx, %bx");
|
||||
}
|
||||
|
||||
extern void SystemReboot();
|
||||
|
||||
extern Key ReadKey();
|
||||
extern KeyEvent ReadKeyEvent();
|
||||
|
||||
#endif
|
||||
69
Kernel/include/stdlib.h
Normal file
69
Kernel/include/stdlib.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef __STDLIB__H
|
||||
#define __STDLIB__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define IsDigit(c) (c >= '0' && c <= '9')
|
||||
#define IsHexDigit(c) ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
|
||||
#define IsUpper(c) (c >= 'A' && c <= 'Z')
|
||||
#define IsLower(c) (c >= 'a' && c <= 'z')
|
||||
|
||||
#define IsAlpha(c) (IsLower(c) || IsUpper(c))
|
||||
#define IsAlphaNum(c) (IsAlpha(c) || IsDigit(c))
|
||||
|
||||
#define ToLower(c) ((IsUpper(c)) ? (c - 'A' + 'a') : c)
|
||||
#define ToUpper(c) ((IsLower(c)) ? (c - 'a' + 'A') : c)
|
||||
|
||||
#define Max(a,b) ((a > b) ? (a) : (b))
|
||||
#define Min(a,b) ((a < b) ? (a) : (b))
|
||||
#define Abs(a) ((a < 0) ? (a * -1) : (a))
|
||||
|
||||
/***************************************************
|
||||
* String operations: len, cmp, cpy *
|
||||
***************************************************/
|
||||
extern uint32 strlen (string s);
|
||||
extern int32 strcmp (string a, string b);
|
||||
extern string strcpy (string s1, const string s2);
|
||||
|
||||
/***************************************************
|
||||
* Number operations: len *
|
||||
***************************************************/
|
||||
extern uint32 numlen (int32 number, int32 base);
|
||||
extern uint32 unumlen (uint32 number, int32 base);
|
||||
|
||||
/***************************************************
|
||||
* Memory operations: cpy, cmp, set *
|
||||
***************************************************/
|
||||
void* memcpy (void *dest, const void *src, uint32 count);
|
||||
int32 memcmp (const void *s1, const void *s2, uint32 count);
|
||||
void* memset (void *dest, uint8 val, uint32 count);
|
||||
|
||||
/***************************************************
|
||||
* Conversion operations: num-str/str-num *
|
||||
***************************************************/
|
||||
extern int32 ConvertIntToString (string buffer, int32 number, int32 base);
|
||||
extern uint32 ConvertUIntToString (string buffer, uint32 number, int32 base);
|
||||
extern int32 ConvertStringToInt (string buffer);
|
||||
extern uint32 ConvertStringToUInt (string buffer);
|
||||
extern uint32 ConvertStringToIntHex (string buffer);
|
||||
|
||||
/***************************************************
|
||||
* Ordered array implementation *
|
||||
***************************************************/
|
||||
typedef int (*ComparePredicate) (uint32, uint32);
|
||||
typedef struct {
|
||||
uint32* Data;
|
||||
uint32 Size;
|
||||
uint32 SizeLimit;
|
||||
ComparePredicate Compare;
|
||||
} OrderedArray;
|
||||
|
||||
extern OrderedArray OrderedArrayCreate (uint32 maxSize, ComparePredicate p);
|
||||
extern OrderedArray OrderedArrayPlace (uint32 addr, uint32 maxSize, ComparePredicate p);
|
||||
extern void OrderedArrayDispose (OrderedArray* arr);
|
||||
extern uint32 OrderedArraySearch (uint32 key, OrderedArray* arr, ComparePredicate predicate);
|
||||
extern void OrderedArrayInsert (uint32 item, OrderedArray* arr);
|
||||
extern uint32 OrderedArrayLookup (uint32 index, OrderedArray* arr);
|
||||
extern void OrderedArrayDeleteIndex (uint32 index, OrderedArray* arr);
|
||||
|
||||
#endif
|
||||
69
Kernel/include/stdlib.h~
Normal file
69
Kernel/include/stdlib.h~
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef __STDLIB__H
|
||||
#define __STDLIB__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define IsDigit(c) (c >= '0' && c <= '9')
|
||||
#define IsHexDigit(c) ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
|
||||
#define IsUpper(c) (c >= 'A' && c <= 'Z')
|
||||
#define IsLower(c) (c >= 'a' && c <= 'z')
|
||||
|
||||
#define IsAlpha(c) (IsLower(c) || IsUpper(c))
|
||||
#define IsAlphaNum(c) (IsAlpha(c) || IsDigit(c))
|
||||
|
||||
#define ToLower(c) ((IsUpper(c)) ? (c - 'A' + 'a') : c)
|
||||
#define ToUpper(c) ((IsLower(c)) ? (c - 'a' + 'A') : c)
|
||||
|
||||
#define Max(a,b) ((a > b) ? (a) : (b))
|
||||
#define Min(a,b) ((a < b) ? (a) : (b))
|
||||
#define Abs(a) ((a < 0) ? (a * -1) : (a))
|
||||
|
||||
/***************************************************
|
||||
* String operations: len, cmp, cpy *
|
||||
***************************************************/
|
||||
extern uint32 strlen (string s);
|
||||
extern int32 strcmp (string a, string b);
|
||||
extern string strcpy (string s1, const string s2);
|
||||
|
||||
/***************************************************
|
||||
* Number operations: len *
|
||||
***************************************************/
|
||||
extern uint32 numlen (int32 number, int32 base);
|
||||
extern uint32 unumlen (uint32 number, int32 base);
|
||||
|
||||
/***************************************************
|
||||
* Memory operations: cpy, cmp, set *
|
||||
***************************************************/
|
||||
void* memcpy (void *dest, const void *src, uint32 count);
|
||||
int32 memcmp (const void *s1, const void *s2, uint32 count);
|
||||
void* memset (void *dest, uint8 val, uint32 count);
|
||||
|
||||
/***************************************************
|
||||
* Conversion operations: num-str/str-num *
|
||||
***************************************************/
|
||||
extern int32 ConvertIntToString (string buffer, int32 number, int32 base);
|
||||
extern uint32 ConvertUIntToString (string buffer, uint32 number, int32 base);
|
||||
extern int32 ConvertStringToInt (string buffer);
|
||||
extern uint32 ConvertStringToUInt (string buffer);
|
||||
extern uint32 ConvertStringToIntHex (string buffer);
|
||||
|
||||
/***************************************************
|
||||
* Ordered array implementation *
|
||||
***************************************************/
|
||||
typedef int (*ComparePredicate) (uint32, uint32);
|
||||
typedef struct {
|
||||
uint32* Data;
|
||||
uint32 Size;
|
||||
uint32 SizeLimit;
|
||||
ComparePredicate Compare;
|
||||
} OrderedArray;
|
||||
|
||||
extern OrderedArray OrderedArrayCreate (uint32 maxSize, ComparePredicate p);
|
||||
extern OrderedArray OrderedArrayPlace (uint32 addr, uint32 maxSize, ComparePredicate p);
|
||||
extern void OrderedArrayDispose (OrderedArray* arr);
|
||||
extern uint32 OrderedArraySearch (uint32 key, OrderedArray* arr, ComparePredicate predicate);
|
||||
extern void OrderedArrayInsert (uint32 item, OrderedArray* arr);
|
||||
extern uint32 OrderedArrayLookup (uint32 index, OrderedArray* arr);
|
||||
extern void OrderedArrayDeleteIndex (uint32 index, OrderedArray* arr);
|
||||
|
||||
#endif
|
||||
65
Kernel/include/storage.h
Normal file
65
Kernel/include/storage.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* storage.h
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#ifndef STORAGE_H_
|
||||
#define STORAGE_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// Storage device
|
||||
typedef struct {
|
||||
|
||||
char MountPointName[32];// E.g. "fd0"; you should avoid spaces, or special chars, or otherwise get weird paths like "Mom's floppy\virus.exe"
|
||||
uint32 DeviceID; // Autocompleted by VFS
|
||||
|
||||
uint32 BlockSize; // E.g. sector size
|
||||
uint32 BlockCount; // How many blocks are loaded in memory per read
|
||||
|
||||
/********************************************************
|
||||
* READ DATA *
|
||||
* Params: *
|
||||
* > offset: read starting from block ~ *
|
||||
* Returns: address to data, NULL for error *
|
||||
********************************************************/
|
||||
uint32 (*ReadData) (uint32 offset);
|
||||
|
||||
/********************************************************
|
||||
* WRITE DATA *
|
||||
* Params: *
|
||||
* > offset: write starting from block ~ *
|
||||
* > address: where to write from *
|
||||
* Returns: NULL for error *
|
||||
********************************************************/
|
||||
uint32 (*WriteData) (uint32 offset, uint32 address);
|
||||
|
||||
uint32 FileSystemID; // Autocompleted by 'mount'... at least should be
|
||||
|
||||
} StorageDevice;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 FileSystemID; // Autocompleted by VFS
|
||||
|
||||
/********************************************************
|
||||
* DETECT IF THIS IS THE FS ON STORAGE DEVICE *
|
||||
* Params: *
|
||||
* > *s: Pointer to device info & routines *
|
||||
* Returns: positive if match, NULL otherwise *
|
||||
********************************************************/
|
||||
uint32 (*Detect) (StorageDevice *s);
|
||||
|
||||
uint32 (*Open) (StorageDevice *s, string path);
|
||||
uint32 (*CreateNode) (StorageDevice *s, string path);
|
||||
uint32 (*DeleteNode) (StorageDevice *s, string path);
|
||||
|
||||
} FileSystem;
|
||||
|
||||
|
||||
|
||||
extern void ConvertLbaToChs(uint32 SectorsPerTrack, uint32 lba, uint32 *cyl, uint32 *head, uint32 *sector);
|
||||
|
||||
#endif /* STORAGE_H_ */
|
||||
37
Kernel/include/time.h
Normal file
37
Kernel/include/time.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef __TIME__H
|
||||
#define __TIME__H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// User friendly time structure
|
||||
struct _Time
|
||||
{
|
||||
int32 Year;
|
||||
uint8 Month, WeekDay, Day; // Day starts monday
|
||||
uint8 Hour, Minute, Second;
|
||||
uint16 Milisecond;
|
||||
} __attribute__((packed));
|
||||
|
||||
// System time structure
|
||||
struct _TimeSystem {
|
||||
uint32 Date, Time;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _Time Time;
|
||||
typedef struct _TimeSystem TimeSystem;
|
||||
|
||||
|
||||
extern TimeSystem TimeConvertToTimeSystem (Time t);
|
||||
extern Time TimeConvertToTime (TimeSystem InternalTime);
|
||||
extern uint16 TimeCalculateWeekday (Time t);
|
||||
|
||||
extern TimeSystem TimeGetInternalTime();
|
||||
extern uint32 TimeGetInternalFrequency ();
|
||||
|
||||
extern void TimeSetInternalTime(TimeSystem t);
|
||||
extern void TimeSetInternalFrequency (uint32 f);
|
||||
|
||||
extern void TimerStart (uint32 ms);
|
||||
extern uint8 TimerIsDone ();
|
||||
|
||||
#endif
|
||||
267
Kernel/include/types.h
Normal file
267
Kernel/include/types.h
Normal file
@@ -0,0 +1,267 @@
|
||||
#ifndef __TYPES__H
|
||||
#define __TYPES__H
|
||||
|
||||
// Get rid of annoying unused params warnings
|
||||
#ifdef UNUSED
|
||||
#elif defined(__GNUC__)
|
||||
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
||||
#elif defined(__LCLINT__)
|
||||
# define UNUSED(x) /*@unused@*/ x
|
||||
#else
|
||||
# define UNUSED(x) x
|
||||
#endif
|
||||
|
||||
/****************************************
|
||||
* NULL constant *
|
||||
****************************************/
|
||||
#define null 0
|
||||
#define NULL 0
|
||||
|
||||
/****************************************
|
||||
* Int definitions *
|
||||
****************************************/
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
typedef int int32;
|
||||
typedef unsigned uint32;
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
|
||||
/****************************************
|
||||
* Limits definitions *
|
||||
****************************************/
|
||||
#define INT8_MIN (-128)
|
||||
#define INT16_MIN (-32768)
|
||||
#define INT32_MIN (-2147483647 - 1)
|
||||
#define INT64_MIN (-9223372036854775807LL - 1)
|
||||
|
||||
#define INT8_MAX 127
|
||||
#define INT16_MAX 32767
|
||||
#define INT32_MAX 2147483647
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
|
||||
#define UINT8_MAX 0xff /* 255U */
|
||||
#define UINT16_MAX 0xffff /* 65535U */
|
||||
#define UINT32_MAX 0xffffffff /* 4294967295U */
|
||||
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
|
||||
|
||||
|
||||
/****************************************
|
||||
* Registers *
|
||||
****************************************/
|
||||
// 32 bit registers
|
||||
typedef struct {
|
||||
uint32 eax, ebx, ecx, edx, esi, edi, ebp, esp, eflags;
|
||||
uint8 cflag;
|
||||
} _R32BIT;
|
||||
|
||||
// 16 bit registers
|
||||
typedef struct {
|
||||
uint16 ax, bx, cx, dx, si, di, bp, sp, es, cs, ss, ds, flags;
|
||||
uint8 cflag;
|
||||
} _R16BIT ;
|
||||
|
||||
// 16 bit registers expressed in 32 bit registers
|
||||
typedef struct {
|
||||
uint16 ax, axh, bx, bxh, cx, cxh, dx, dxh;
|
||||
uint16 si, di, bp, sp, es, cs, ss, ds, flags;
|
||||
uint8 cflags;
|
||||
} _R16BIT32 ;
|
||||
|
||||
// 8 bit registers
|
||||
typedef struct {
|
||||
uint8 al, ah, bl, bh, cl, ch, dl, dh;
|
||||
} _R8BIT;
|
||||
|
||||
// 8 bit registers expressed in 32 bit registers
|
||||
typedef struct {
|
||||
uint8 al, ah; uint16 axh;
|
||||
uint8 bl, bh; uint16 bxh;
|
||||
uint8 cl, ch; uint16 cxh;
|
||||
uint8 dl, dh; uint16 dxh;
|
||||
} _R8BIT32;
|
||||
|
||||
// 8 and 16 bit registers union
|
||||
typedef union {
|
||||
_R16BIT x;
|
||||
_R8BIT h;
|
||||
}_INTR16;
|
||||
|
||||
// 32 bit, 16 bit and 8 bit registers union
|
||||
typedef union {
|
||||
_R32BIT x;
|
||||
_R16BIT32 l;
|
||||
_R8BIT32 h;
|
||||
} _INTR32;
|
||||
|
||||
/* This defines what the stack looks like after an ISR was running */
|
||||
typedef struct
|
||||
{
|
||||
uint32 gs, fs, es, ds; /* pushed the segs last */
|
||||
uint32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */
|
||||
uint32 int_no, err_code; /* our 'push byte #' and ecodes do this */
|
||||
uint32 eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */
|
||||
} _RegsStack32;
|
||||
|
||||
|
||||
/****************************************
|
||||
* Keyboard data types *
|
||||
****************************************/
|
||||
enum KeyboardKeys {
|
||||
|
||||
KeyboardKeyF9 = 0x01,
|
||||
KeyboardKeyF7 = 0x02,
|
||||
KeyboardKeyF5 = 0x03,
|
||||
KeyboardKeyF3 = 0x04,
|
||||
KeyboardKeyF1 = 0x05,
|
||||
KeyboardKeyF2 = 0x06,
|
||||
KeyboardKeyF12 = 0x07,
|
||||
KeyboardKeyMediaNext = 0x08,
|
||||
KeyboardKeyF10 = 0x09,
|
||||
KeyboardKeyF8 = 0x0A,
|
||||
KeyboardKeyF6 = 0x0B,
|
||||
KeyboardKeyF4 = 0x0C,
|
||||
KeyboardKeyTab = 0x0D,
|
||||
KeyboardKeyTilda = 0x0E,
|
||||
KeyboardKeyMediaPrevious = 0x0F,
|
||||
KeyboardKeyMediaStop = 0x10,
|
||||
KeyboardKeyLeftAlt = 0x11,
|
||||
KeyboardKeyLeftShift = 0x12,
|
||||
KeyboardKeyMediaPause = 0x13,
|
||||
KeyboardKeyLeftCtrl = 0x14,
|
||||
KeyboardKeyQ = 0x15,
|
||||
KeyboardKey1 = 0x16,
|
||||
KeyboardKeyMediaVolUp = 0x17,
|
||||
KeyboardKeyMediaVolDown = 0x18,
|
||||
KeyboardKeyMediaSelect = 0x19,
|
||||
KeyboardKeyZ = 0x1A,
|
||||
KeyboardKeyS = 0x1B,
|
||||
KeyboardKeyA = 0x1C,
|
||||
KeyboardKeyW = 0x1D,
|
||||
KeyboardKey2 = 0x1E,
|
||||
KeyboardKeyLeftWin = 0x1F,
|
||||
KeyboardKeyMediaEmail = 0x20,
|
||||
KeyboardKeyC = 0x21,
|
||||
KeyboardKeyX = 0x22,
|
||||
KeyboardKeyD = 0x23,
|
||||
KeyboardKeyE = 0x24,
|
||||
KeyboardKey4 = 0x25,
|
||||
KeyboardKey3 = 0x26,
|
||||
KeyboardKeyRightWin = 0x27,
|
||||
KeyboardKeyMediaCalculator = 0x28,
|
||||
KeyboardKeySpace = 0x29,
|
||||
KeyboardKeyV = 0x2A,
|
||||
KeyboardKeyF = 0x2B,
|
||||
KeyboardKeyT = 0x2C,
|
||||
KeyboardKeyR = 0x2D,
|
||||
KeyboardKey5 = 0x2E,
|
||||
KeyboardKeyMenu = 0x2F,
|
||||
KeyboardKeyMediaComputer = 0x30,
|
||||
KeyboardKeyN = 0x31,
|
||||
KeyboardKeyB = 0x32,
|
||||
KeyboardKeyH = 0x33,
|
||||
KeyboardKeyG = 0x34,
|
||||
KeyboardKeyY = 0x35,
|
||||
KeyboardKey6 = 0x36,
|
||||
KeyboardKeyPower = 0x37,
|
||||
KeyboardKeyMediaWebSearch = 0x38,
|
||||
KeyboardKeyMediaWebHome = 0x39,
|
||||
KeyboardKeyM = 0x3A,
|
||||
KeyboardKeyJ = 0x3B,
|
||||
KeyboardKeyU = 0x3C,
|
||||
KeyboardKey7 = 0x3D,
|
||||
KeyboardKey8 = 0x3E,
|
||||
KeyboardKeySleep = 0x3F,
|
||||
KeyboardKeyWake = 0x40,
|
||||
KeyboardKeyComma = 0x41,
|
||||
KeyboardKeyK = 0x42,
|
||||
KeyboardKeyI = 0x43,
|
||||
KeyboardKeyO = 0x44,
|
||||
KeyboardKey0 = 0x45,
|
||||
KeyboardKey9 = 0x46,
|
||||
KeyboardKeyMediaWebBack = 0x47,
|
||||
KeyboardKeyMediaWebForward = 0x48,
|
||||
KeyboardKeyPeriod = 0x49,
|
||||
KeyboardKeySlash = 0x4A,
|
||||
KeyboardKeyL = 0x4B,
|
||||
KeyboardKeySemicolon = 0x4C,
|
||||
KeyboardKeyP = 0x4D,
|
||||
KeyboardKeyDash = 0x4E,
|
||||
KeyboardKeyMediaWebStop = 0x4F,
|
||||
KeyboardKeyMediaWebRefresh = 0x50,
|
||||
KeyboardKeyMediaWebFavorites = 0x51,
|
||||
KeyboardKeyApostrophe = 0x52,
|
||||
KeyboardKeyRightAlt = 0x53,
|
||||
KeyboardKeyLeftBracket = 0x54,
|
||||
KeyboardKeyEqual = 0x55,
|
||||
KeyboardKeyPrintScreen = 0x56,
|
||||
KeyboardKeyPause = 0x57,
|
||||
KeyboardKeyCapsLock = 0x58,
|
||||
KeyboardKeyRightShift = 0x59,
|
||||
KeyboardKeyReturn = 0x5A,
|
||||
KeyboardKeyRightBracket = 0x5B,
|
||||
KeyboardKeyRightCtrl = 0x5C,
|
||||
KeyboardKeyBackSlash = 0x5D,
|
||||
KeyboardKeyInsert = 0x5E,
|
||||
KeyboardKeyDelete = 0x5F,
|
||||
KeyboardKeyHome = 0x60,
|
||||
KeyboardKeyEnd = 0x61,
|
||||
KeyboardKeyPageUp = 0x62,
|
||||
KeyboardKeyPageDown = 0x63,
|
||||
KeyboardKeyLeft = 0x64,
|
||||
KeyboardKeyDown = 0x65,
|
||||
KeyboardKeyBackspace = 0x66,
|
||||
KeyboardKeyRight = 0x67,
|
||||
KeyboardKeyUp = 0x68,
|
||||
KeyboardKeyNumpad1 = 0x69,
|
||||
KeyboardKeyNumpadSlash = 0x6A,
|
||||
KeyboardKeyNumpad4 = 0x6B,
|
||||
KeyboardKeyNumpad7 = 0x6C,
|
||||
KeyboardKeyNumpadEnter = 0x6D,
|
||||
KeyboardKeyMediaMute = 0x6E,
|
||||
KeyboardKeyNumpad0 = 0x70,
|
||||
KeyboardKeyNumpadColon = 0x71,
|
||||
KeyboardKeyNumpad2 = 0x72,
|
||||
KeyboardKeyNumpad5 = 0x73,
|
||||
KeyboardKeyNumpad6 = 0x74,
|
||||
KeyboardKeyNumpad8 = 0x75,
|
||||
KeyboardKeyEscape = 0x76,
|
||||
KeyboardKeyNumLock = 0x77,
|
||||
KeyboardKeyF11 = 0x78,
|
||||
KeyboardKeyNumpadPlus = 0x79,
|
||||
KeyboardKeyNumpad3 = 0x7A,
|
||||
KeyboardKeyNumpadMinus = 0x7B,
|
||||
KeyboardKeyNumpadAsterisk = 0x7C,
|
||||
KeyboardKeyNumpad9 = 0x7D,
|
||||
KeyboardKeyScrollLock = 0x7E
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char Character;
|
||||
uint8 Scancode;
|
||||
} Key;
|
||||
|
||||
typedef struct {
|
||||
uint8 Pressed;
|
||||
char Character;
|
||||
uint8 Scancode;
|
||||
} KeyEvent;
|
||||
|
||||
/****************************************
|
||||
* Other data types *
|
||||
****************************************/
|
||||
typedef struct {
|
||||
int32 X, Y;
|
||||
} Point;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 X, Y;
|
||||
} UPoint;
|
||||
|
||||
typedef char* string;
|
||||
|
||||
#endif
|
||||
17
Kernel/include/va_list.h
Normal file
17
Kernel/include/va_list.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __VA_LIST__H
|
||||
#define __VA_LIST__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* va list parameter list */
|
||||
typedef unsigned char *va_list;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
1
Kernel/include/version.h
Normal file
1
Kernel/include/version.h
Normal file
@@ -0,0 +1 @@
|
||||
#define OS_BUILD "0.1.0.450"
|
||||
1
Kernel/include/version.h~
Normal file
1
Kernel/include/version.h~
Normal file
@@ -0,0 +1 @@
|
||||
-e #define OS_BUILD "0.1.0.418"
|
||||
146
Kernel/library/ctype.c
Normal file
146
Kernel/library/ctype.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include<ctype.h>
|
||||
|
||||
unsigned char _ctype[256] =
|
||||
{
|
||||
0, // -1 EOF
|
||||
_CTYPE_ISCONTROL, // 00 (NUL)
|
||||
_CTYPE_ISCONTROL, // 01 (SOH)
|
||||
_CTYPE_ISCONTROL, // 02 (STX)
|
||||
_CTYPE_ISCONTROL, // 03 (ETX)
|
||||
_CTYPE_ISCONTROL, // 04 (EOT)
|
||||
_CTYPE_ISCONTROL, // 05 (ENQ)
|
||||
_CTYPE_ISCONTROL, // 06 (ACK)
|
||||
_CTYPE_ISCONTROL, // 07 (BEL)
|
||||
_CTYPE_ISCONTROL, // 08 (BS)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISCONTROL, // 09 (HT)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISCONTROL, // 0A (LF)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISCONTROL, // 0B (VT)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISCONTROL, // 0C (FF)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISCONTROL, // 0D (CR)
|
||||
_CTYPE_ISCONTROL, // 0E (SI)
|
||||
_CTYPE_ISCONTROL, // 0F (SO)
|
||||
_CTYPE_ISCONTROL, // 10 (DLE)
|
||||
_CTYPE_ISCONTROL, // 11 (DC1)
|
||||
_CTYPE_ISCONTROL, // 12 (DC2)
|
||||
_CTYPE_ISCONTROL, // 13 (DC3)
|
||||
_CTYPE_ISCONTROL, // 14 (DC4)
|
||||
_CTYPE_ISCONTROL, // 15 (NAK)
|
||||
_CTYPE_ISCONTROL, // 16 (SYN)
|
||||
_CTYPE_ISCONTROL, // 17 (ETB)
|
||||
_CTYPE_ISCONTROL, // 18 (CAN)
|
||||
_CTYPE_ISCONTROL, // 19 (EM)
|
||||
_CTYPE_ISCONTROL, // 1A (SUB)
|
||||
_CTYPE_ISCONTROL, // 1B (ESC)
|
||||
_CTYPE_ISCONTROL, // 1C (FS)
|
||||
_CTYPE_ISCONTROL, // 1D (GS)
|
||||
_CTYPE_ISCONTROL, // 1E (RS)
|
||||
_CTYPE_ISCONTROL, // 1F (US)
|
||||
_CTYPE_ISSPACE+_CTYPE_ISBLANK, // 20 SPACE
|
||||
_CTYPE_ISPUNCT, // 21 !
|
||||
_CTYPE_ISPUNCT, // 22 "
|
||||
_CTYPE_ISPUNCT, // 23 #
|
||||
_CTYPE_ISPUNCT, // 24 $
|
||||
_CTYPE_ISPUNCT, // 25 %
|
||||
_CTYPE_ISPUNCT, // 26 &
|
||||
_CTYPE_ISPUNCT, // 27 '
|
||||
_CTYPE_ISPUNCT, // 28 (
|
||||
_CTYPE_ISPUNCT, // 29 )
|
||||
_CTYPE_ISPUNCT, // 2A *
|
||||
_CTYPE_ISPUNCT, // 2B +
|
||||
_CTYPE_ISPUNCT, // 2C ,
|
||||
_CTYPE_ISPUNCT, // 2D -
|
||||
_CTYPE_ISPUNCT, // 2E .
|
||||
_CTYPE_ISPUNCT, // 2F /
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 30 0
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 31 1
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 32 2
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 33 3
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 34 4
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 35 5
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 36 6
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 37 7
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 38 8
|
||||
_CTYPE_ISDIGIT+_CTYPE_ISHEX, // 39 9
|
||||
_CTYPE_ISPUNCT, // 3A :
|
||||
_CTYPE_ISPUNCT, // 3B ;
|
||||
_CTYPE_ISPUNCT, // 3C <
|
||||
_CTYPE_ISPUNCT, // 3D =
|
||||
_CTYPE_ISPUNCT, // 3E >
|
||||
_CTYPE_ISPUNCT, // 3F ?
|
||||
_CTYPE_ISPUNCT, // 40 @
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 41 A
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 42 B
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 43 C
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 44 D
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 45 E
|
||||
_CTYPE_ISUPPER+_CTYPE_ISHEX, // 46 F
|
||||
_CTYPE_ISUPPER, // 47 G
|
||||
_CTYPE_ISUPPER, // 48 H
|
||||
_CTYPE_ISUPPER, // 49 I
|
||||
_CTYPE_ISUPPER, // 4A J
|
||||
_CTYPE_ISUPPER, // 4B K
|
||||
_CTYPE_ISUPPER, // 4C L
|
||||
_CTYPE_ISUPPER, // 4D M
|
||||
_CTYPE_ISUPPER, // 4E N
|
||||
_CTYPE_ISUPPER, // 4F O
|
||||
_CTYPE_ISUPPER, // 50 P
|
||||
_CTYPE_ISUPPER, // 51 Q
|
||||
_CTYPE_ISUPPER, // 52 R
|
||||
_CTYPE_ISUPPER, // 53 S
|
||||
_CTYPE_ISUPPER, // 54 T
|
||||
_CTYPE_ISUPPER, // 55 U
|
||||
_CTYPE_ISUPPER, // 56 V
|
||||
_CTYPE_ISUPPER, // 57 W
|
||||
_CTYPE_ISUPPER, // 58 X
|
||||
_CTYPE_ISUPPER, // 59 Y
|
||||
_CTYPE_ISUPPER, // 5A Z
|
||||
_CTYPE_ISPUNCT, // 5B [
|
||||
_CTYPE_ISPUNCT, // 5C backslash
|
||||
_CTYPE_ISPUNCT, // 5D ]
|
||||
_CTYPE_ISPUNCT, // 5E ^
|
||||
_CTYPE_ISPUNCT, // 5F _
|
||||
_CTYPE_ISPUNCT, // 60 `
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 61 a
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 62 b
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 63 c
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 64 d
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 65 e
|
||||
_CTYPE_ISLOWER+_CTYPE_ISHEX, // 66 f
|
||||
_CTYPE_ISLOWER, // 67 g
|
||||
_CTYPE_ISLOWER, // 68 h
|
||||
_CTYPE_ISLOWER, // 69 i
|
||||
_CTYPE_ISLOWER, // 6A j
|
||||
_CTYPE_ISLOWER, // 6B k
|
||||
_CTYPE_ISLOWER, // 6C l
|
||||
_CTYPE_ISLOWER, // 6D m
|
||||
_CTYPE_ISLOWER, // 6E n
|
||||
_CTYPE_ISLOWER, // 6F o
|
||||
_CTYPE_ISLOWER, // 70 p
|
||||
_CTYPE_ISLOWER, // 71 q
|
||||
_CTYPE_ISLOWER, // 72 r
|
||||
_CTYPE_ISLOWER, // 73 s
|
||||
_CTYPE_ISLOWER, // 74 t
|
||||
_CTYPE_ISLOWER, // 75 u
|
||||
_CTYPE_ISLOWER, // 76 v
|
||||
_CTYPE_ISLOWER, // 77 w
|
||||
_CTYPE_ISLOWER, // 78 x
|
||||
_CTYPE_ISLOWER, // 79 y
|
||||
_CTYPE_ISLOWER, // 7A z
|
||||
_CTYPE_ISPUNCT, // 7B {
|
||||
_CTYPE_ISPUNCT, // 7C +
|
||||
_CTYPE_ISPUNCT, // 7D }
|
||||
_CTYPE_ISPUNCT, // 7E ~
|
||||
_CTYPE_ISCONTROL, // 7F (DEL)
|
||||
// and the rest are 0...
|
||||
};
|
||||
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
return ((islower(c)) ? (c-'a'+'A') : c);
|
||||
}
|
||||
|
||||
int tolower(int c)
|
||||
{
|
||||
return((isupper(c)) ? (c-'A'+'a') : c);
|
||||
}
|
||||
84
Kernel/library/memory/memory_alloc.c
Normal file
84
Kernel/library/memory/memory_alloc.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* memory_alloc.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
|
||||
extern uint32 mem_kernel_end;
|
||||
extern uint8 mem_initialized;
|
||||
|
||||
// Used prior to proper initialization
|
||||
uint32 _malloc_init1 (uint32 size, uint8 page_aligned)
|
||||
{
|
||||
uint32 ret = mem_kernel_end;
|
||||
|
||||
if (page_aligned && (ret & 0xfff)) ret = (ret & 0xfffff000) + 0x1000;
|
||||
mem_kernel_end = size + ret;
|
||||
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at end of kernel (0x%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint32 _malloc_init2 (uint32 size, uint8 page_aligned, uint32* phys)
|
||||
{
|
||||
uint32 ret = MemHeapAlloc(size, page_aligned, KernelHeap, KernelDirectory);
|
||||
|
||||
if (phys)
|
||||
{
|
||||
Page *pg = PagingGetPage(ret, 0, KernelDirectory);
|
||||
*phys = (*pg & PageFrame) + (ret & 0xFFF);
|
||||
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at address 0x%x (phys=%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret, *phys);
|
||||
}
|
||||
|
||||
else {
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at address 0x%x.\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Allocate 'size' bytes
|
||||
void* kmalloc (uint32 size)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) return (void*)_malloc_init1(size, 0);
|
||||
|
||||
return (void*)_malloc_init2(size,0,0);
|
||||
}
|
||||
|
||||
// Allocate 'size' bytes, page aligned
|
||||
void* kmalloc_a(uint32 size)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) return (void*)_malloc_init1(size, 1);
|
||||
|
||||
return (void*)_malloc_init2(size,1,0);
|
||||
}
|
||||
|
||||
void* kmalloc_p(uint32 size, uint32* phys)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) {
|
||||
*phys = _malloc_init1(size,0);
|
||||
return (void*)(*phys);
|
||||
}
|
||||
|
||||
return (void*)_malloc_init2(size,0,phys);
|
||||
}
|
||||
|
||||
void* kmalloc_ap(uint32 size, uint32* phys)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
|
||||
uint32 ret;
|
||||
if (mem_initialized == 1) {
|
||||
*phys = ret = _malloc_init1(size,1);
|
||||
}
|
||||
|
||||
else ret = _malloc_init2(size,1,phys);
|
||||
return (void*)ret;
|
||||
}
|
||||
87
Kernel/library/memory/memory_alloc.c~
Normal file
87
Kernel/library/memory/memory_alloc.c~
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* memory_alloc.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
|
||||
extern uint32 mem_kernel_end;
|
||||
extern uint8 mem_initialized;
|
||||
|
||||
// Used prior to proper initialization
|
||||
uint32 _malloc_init1 (uint32 size, uint8 page_aligned)
|
||||
{
|
||||
uint32 ret = mem_kernel_end;
|
||||
|
||||
if (page_aligned && (ret & 0xfff)) ret = (ret & 0xfffff000) + 0x1000;
|
||||
mem_kernel_end = size + ret;
|
||||
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at end of kernel (0x%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint32 _malloc_init2 (uint32 size, uint8 page_aligned, uint32* phys)
|
||||
{
|
||||
uint32 ret = MemHeapAlloc(size, page_aligned, KernelHeap, KernelDirectory);
|
||||
|
||||
if (phys)
|
||||
{
|
||||
Page *pg = PagingGetPage(ret, 0, KernelDirectory);
|
||||
*phys = (*pg & PageFrame) + (ret & 0xFFF);
|
||||
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at address 0x%x (phys=%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret, *phys);
|
||||
}
|
||||
|
||||
else {
|
||||
LogMem("%#Allocated %u bytes (%spage aligned) at address 0x%x.\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Allocate 'size' bytes
|
||||
void* kmalloc (uint32 size)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) return (void*)_malloc_init1(size, 0);
|
||||
|
||||
return (void*)_malloc_init2(size,0,0);
|
||||
}
|
||||
|
||||
// Allocate 'size' bytes, page aligned
|
||||
void* kmalloc_a(uint32 size)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) return (void*)_malloc_init1(size, 1);
|
||||
|
||||
return (void*)_malloc_init2(size,1,0);
|
||||
}
|
||||
|
||||
void* kmalloc_p(uint32 size, uint32* phys)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
if (mem_initialized == 1) {
|
||||
*phys = _malloc_init1(size,0);
|
||||
return (void*)(*phys);
|
||||
}
|
||||
|
||||
return (void*)_malloc_init2(size,0,phys);
|
||||
}
|
||||
|
||||
void* kmalloc_ap(uint32 size, uint32* phys)
|
||||
{
|
||||
if (!mem_initialized) return 0;
|
||||
|
||||
uint32 ret;
|
||||
if (mem_initialized == 1) {
|
||||
*phys = ret = _malloc_init1(size,1);
|
||||
}
|
||||
|
||||
else ret = _malloc_init2(size,1,phys);
|
||||
|
||||
LogMem("%#kmalloc_ap requested, returned 0x%x, phys = 0x%x.\n", ColorMagenta, ret, *phys);
|
||||
|
||||
return (void*)ret;
|
||||
}
|
||||
20
Kernel/library/memory/memory_free.c
Normal file
20
Kernel/library/memory/memory_free.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* memory_free.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
|
||||
extern uint8 mem_initialized;
|
||||
|
||||
void kfree(void* addr)
|
||||
{
|
||||
if (mem_initialized < 2) {
|
||||
ErrorMem("%#Tried to free at address 0x%x when memory manager is uninitialized.\n", ColorLightRed, (uint32)addr);
|
||||
return;
|
||||
}
|
||||
|
||||
MemHeapFree((uint32)addr, KernelHeap, KernelDirectory);
|
||||
}
|
||||
48
Kernel/library/memory/memory_info.c
Normal file
48
Kernel/library/memory/memory_info.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* memory_info.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
// MemoryGetFree(), MemoryGetTotal(), MemoryGet blah blah...
|
||||
|
||||
// Returns total physical memory in bytes
|
||||
uint32 MemoryGetTotal()
|
||||
{
|
||||
return (TotalMemory);
|
||||
}
|
||||
|
||||
// Returns total free physical memory in bytes
|
||||
uint32 MemoryGetFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames) * 0x4;
|
||||
}
|
||||
|
||||
// Total used physical memory in bytes
|
||||
uint32 MemoryGetUsed()
|
||||
{
|
||||
return UsedFrames * 0x4;
|
||||
}
|
||||
|
||||
// Same as above functions, but in frames
|
||||
uint32 MemoryGetFrameSize()
|
||||
{
|
||||
return 0x4;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesTotal()
|
||||
{
|
||||
return TotalFrames;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesUsed()
|
||||
{
|
||||
return UsedFrames;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames);
|
||||
}
|
||||
48
Kernel/library/memory/memory_info.c~
Normal file
48
Kernel/library/memory/memory_info.c~
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* memory_info.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
// MemoryGetFree(), MemoryGetTotal(), MemoryGet blah blah...
|
||||
|
||||
// Returns total physical memory in bytes
|
||||
uint32 MemoryGetTotal()
|
||||
{
|
||||
return (TotalMemory);
|
||||
}
|
||||
|
||||
// Returns total free physical memory in bytes
|
||||
uint32 MemoryGetFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames) * 0x4;
|
||||
}
|
||||
|
||||
// Total used physical memory in bytes
|
||||
uint32 MemoryGetUsed()
|
||||
{
|
||||
return UsedFrames * 0x4;
|
||||
}
|
||||
|
||||
// Same as above functions, but in frames
|
||||
uint32 MemoryGetFrameSize()
|
||||
{
|
||||
return 0x1000;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesTotal()
|
||||
{
|
||||
return TotalFrames;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesUsed()
|
||||
{
|
||||
return UsedFrames;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames);
|
||||
}
|
||||
88
Kernel/library/memory/memory_init.c
Normal file
88
Kernel/library/memory/memory_init.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* memory-init.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <multiboot.h>
|
||||
#include <debugio.h>
|
||||
#include "../../drivers/cmos/cmos.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
uint32 mem_kernel_end = 0;
|
||||
uint8 mem_initialized = 0;
|
||||
|
||||
uint32 _memory_get_total_mem(MultibootInfo* info)
|
||||
{
|
||||
// Grub was nice enough to give us info
|
||||
if (info->Flags & MultibootInfo_MEMORY) return (1024 + info->MemoryUpper);
|
||||
|
||||
// No? Get info from CMOS
|
||||
uint8 low, high;
|
||||
uint32 total;
|
||||
|
||||
low = CmosRead(0x30);
|
||||
high = CmosRead(0x31);
|
||||
total = (uint32)(low | high<<8) + 1024;
|
||||
|
||||
ErrorMem("%#Missing memory info from bootloader. Reading from CMOS: %ukb\n", ColorLightRed, total);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void _memory_reserve_system(MultibootInfo* info)
|
||||
{
|
||||
MagicBreakpoint();
|
||||
if ((info->Flags & MultibootInfo_MEM_MAP) != 0)
|
||||
{
|
||||
MultibootMemoryMapEntry* location = (MultibootMemoryMapEntry*)info->MemoryMapAddress;
|
||||
|
||||
while ((uint32)location < (info->MemoryMapAddress + info->MemoryMapLength))
|
||||
{
|
||||
if (location->Type > 1)
|
||||
MemPhReserveFrames((uint32)location->Address, (uint32)location->Length);
|
||||
|
||||
location = (MultibootMemoryMapEntry*) ((uint32)location + location->Size + sizeof(uint32));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ErrorMem("%#Missing %#memory map%# info from bootloader.\n", ColorLightRed, ColorWhite, ColorLightRed);
|
||||
|
||||
// Standard memory hole at 15mb
|
||||
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)
|
||||
{
|
||||
uint32 totalSystemMemory = _memory_get_total_mem(info);
|
||||
|
||||
MemPhInitialize(totalSystemMemory);
|
||||
PagingInitialize(0x200000);
|
||||
|
||||
_memory_reserve_system(info);
|
||||
|
||||
KernelHeap = MemHeapCreate(KERNEL_HEAP_START, KERNEL_HEAP_START
|
||||
+ KERNEL_HEAP_INITIAL_SIZE, 0xCFFFF000, 3); // is kernel, writeable
|
||||
|
||||
LogMem("Done initializing memory!");
|
||||
|
||||
mem_initialized = 2;
|
||||
}
|
||||
|
||||
void MemoryTempInitialize (uint32 kernel_end)
|
||||
{
|
||||
mem_initialized = 1;
|
||||
mem_kernel_end = kernel_end;
|
||||
LogMem("Initialized temporary memory manager, allocating from %#0x%x.\n", kernel_end);
|
||||
}
|
||||
92
Kernel/library/memory/memory_init.c~
Normal file
92
Kernel/library/memory/memory_init.c~
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* memory-init.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <multiboot.h>
|
||||
#include <debugio.h>
|
||||
#include "../../drivers/cmos/cmos.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
uint32 mem_kernel_end = 0;
|
||||
uint8 mem_initialized = 0;
|
||||
|
||||
uint32 _memory_get_total_mem(MultibootInfo* info)
|
||||
{
|
||||
// Grub was nice enough to give us info
|
||||
if (info->Flags & MultibootInfo_MEMORY) return (1024 + info->MemoryUpper);
|
||||
|
||||
// No? Get info from CMOS
|
||||
uint8 low, high;
|
||||
uint32 total;
|
||||
|
||||
low = CmosRead(0x30);
|
||||
high = CmosRead(0x31);
|
||||
total = (uint32)(low | high<<8) + 1024;
|
||||
|
||||
ErrorMem("%#Missing memory info from bootloader. Reading from CMOS: %ukb\n", ColorLightRed, total);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void _memory_reserve_system(MultibootInfo* info)
|
||||
{
|
||||
MagicBreakpoint();
|
||||
if ((info->Flags & MultibootInfo_MEM_MAP) != 0)
|
||||
{
|
||||
MultibootMemoryMapEntry* location = (MultibootMemoryMapEntry*)info->MemoryMapAddress;
|
||||
|
||||
while ((uint32)location < (info->MemoryMapAddress + info->MemoryMapLength))
|
||||
{
|
||||
if (location->Type > 1)
|
||||
MemPhReserveFrames((uint32)location->Address, (uint32)location->Length);
|
||||
|
||||
location = (MultibootMemoryMapEntry*) ((uint32)location + location->Size + sizeof(uint32));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ErrorMem("%#Missing %#memory map%# info from bootloader.\n", ColorLightRed, ColorWhite, ColorLightRed);
|
||||
|
||||
// Standard memory hole at 15mb
|
||||
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)
|
||||
{
|
||||
uint32 totalSystemMemory = _memory_get_total_mem(info);
|
||||
|
||||
MemPhInitialize(totalSystemMemory);
|
||||
PagingInitialize(0x200000);
|
||||
|
||||
LogMem("Reserving important areas...\n");
|
||||
|
||||
_memory_reserve_system(info);
|
||||
|
||||
LogMem("Allocating kernel heap...\n");
|
||||
|
||||
KernelHeap = MemHeapCreate(KERNEL_HEAP_START, KERNEL_HEAP_START
|
||||
+ KERNEL_HEAP_INITIAL_SIZE, 0xCFFFF000, 3); // is kernel, writeable
|
||||
|
||||
LogMem("Done initializing memory!");
|
||||
|
||||
mem_initialized = 2;
|
||||
}
|
||||
|
||||
void MemoryTempInitialize (uint32 kernel_end)
|
||||
{
|
||||
mem_initialized = 1;
|
||||
mem_kernel_end = kernel_end;
|
||||
LogMem("Initialized temporary memory manager, allocating from %#0x%x.\n", kernel_end);
|
||||
}
|
||||
44
Kernel/library/stdio.c
Normal file
44
Kernel/library/stdio.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "../hal/keyboard/keyboard.h"
|
||||
|
||||
uint8 inportb (uint16 _port) {
|
||||
uint8 rv;
|
||||
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
|
||||
return rv;
|
||||
}
|
||||
|
||||
Key ReadKey()
|
||||
{
|
||||
Key key;
|
||||
|
||||
do {
|
||||
KeyboardLastScancode = 0xFF ;
|
||||
while (KeyboardLastScancode == 0xFF) ;
|
||||
|
||||
key.Scancode = KeyboardLastScancode;
|
||||
|
||||
} while (KeyboardLastStatus & 1);
|
||||
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyLeftShift) || KeyboardGetKeyStatus(KeyboardKeyRightShift))
|
||||
key.Character = KeyboardMapShift[key.Scancode];
|
||||
else key.Character = KeyboardMap[key.Scancode];
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
KeyEvent ReadKeyEvent()
|
||||
{
|
||||
KeyEvent key;
|
||||
|
||||
KeyboardLastScancode = 0xFF ;
|
||||
while (KeyboardLastScancode == 0xFF) ;
|
||||
|
||||
key.Scancode = KeyboardLastScancode;
|
||||
key.Pressed = 1 - (KeyboardLastStatus & 1);
|
||||
|
||||
if (KeyboardGetKeyStatus(KeyboardKeyLeftShift) || KeyboardGetKeyStatus(KeyboardKeyRightShift))
|
||||
key.Character = KeyboardMapShift[key.Scancode];
|
||||
else key.Character = KeyboardMap[key.Scancode];
|
||||
|
||||
return key;
|
||||
}
|
||||
100
Kernel/library/stdlib/convert_ops.c
Normal file
100
Kernel/library/stdlib/convert_ops.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* convert_ops.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
const string _Numbers = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
int32 ConvertIntToString (string buffer, int32 number, int32 base)
|
||||
{
|
||||
if (base > 36 || base < 2) return 0;
|
||||
|
||||
int32 len = numlen (number, base), beg = 0, i;
|
||||
uint32 n = (uint32) number;
|
||||
|
||||
// If number is negative and in base 10, we put a '-' in front
|
||||
if (number < 0 && base == 10) buffer[beg++] = '-';
|
||||
|
||||
// Put every digit in string
|
||||
for (i = len-1; i>=beg; i--)
|
||||
{
|
||||
buffer[i] = _Numbers[n % base];
|
||||
n /= base;
|
||||
}
|
||||
|
||||
buffer[len] = 0;
|
||||
return number;
|
||||
}
|
||||
|
||||
uint32 ConvertUIntToString (string buffer, uint32 number, int32 base)
|
||||
{
|
||||
if (base > 36 || base < 2) return 0;
|
||||
|
||||
int32 len = unumlen (number, base), i;
|
||||
|
||||
// Put every digit in string
|
||||
for (i = len-1; i >= 0; i--)
|
||||
{
|
||||
buffer[i] = _Numbers[number % base];
|
||||
number /= base;
|
||||
}
|
||||
|
||||
buffer[len] = 0;
|
||||
return number;
|
||||
}
|
||||
|
||||
int32 ConvertStringToInt (string buffer)
|
||||
{
|
||||
int8 negative = (buffer[0] == '-');
|
||||
int32 pos = (buffer[0] == '-' );
|
||||
|
||||
int32 number = 0;
|
||||
|
||||
while (IsDigit(buffer[pos]))
|
||||
{
|
||||
number = number*10 + (buffer[pos] - '0');
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (negative) return -number;
|
||||
return number;
|
||||
}
|
||||
|
||||
uint32 ConvertStringToUInt (string buffer)
|
||||
{
|
||||
int32 pos = 0;
|
||||
int32 number = 0;
|
||||
|
||||
while (IsDigit(buffer[pos]))
|
||||
{
|
||||
number = number*10 + (buffer[pos] - '0');
|
||||
pos++;
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
uint32 ConvertStringToIntHex (string buffer)
|
||||
{
|
||||
int32 pos = 0;
|
||||
uint32 number = 0;
|
||||
|
||||
// Skip first 2 digits if it is in format 0xXXXX...
|
||||
if (buffer[1] == 'x' || buffer[1] == 'X') pos = 2;
|
||||
|
||||
while (IsHexDigit(buffer[pos]))
|
||||
{
|
||||
number = number*0x10;
|
||||
|
||||
if (IsDigit(buffer[pos])) number += buffer[pos] - '0';
|
||||
else if (buffer[pos] >= 'a' && buffer[pos] <= 'f') number += 10 + buffer[pos] - 'a';
|
||||
else if (buffer[pos] >= 'A' && buffer[pos] <= 'F') number += 10 + buffer[pos] - 'A';
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
42
Kernel/library/stdlib/mem_ops.c
Normal file
42
Kernel/library/stdlib/mem_ops.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* mem_ops.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <types.h>
|
||||
|
||||
void *memcpy(void *dest, const void *src, uint32 count)
|
||||
{
|
||||
uint8* d = (uint8*) dest;
|
||||
const uint8* s = (const uint8*) src;
|
||||
|
||||
while (count-- != 0)
|
||||
*d++ = *s++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int32 memcmp(const void *s1, const void *s2, uint32 count)
|
||||
{
|
||||
const uint8 *us1 = (const uint8*) s1;
|
||||
const uint8 *us2 = (const uint8*) s2;
|
||||
|
||||
while (count-- != 0)
|
||||
{
|
||||
if (*us1 != *us2) return (*us1 < *us2) ? -1 : 1;
|
||||
us1++; us2++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *memset(void *dest, uint8 val, uint32 count)
|
||||
{
|
||||
uint8 *temp = (uint8 *)dest;
|
||||
while (count-- != 0)
|
||||
*temp++ = val;
|
||||
|
||||
return dest;
|
||||
}
|
||||
39
Kernel/library/stdlib/num_ops.c
Normal file
39
Kernel/library/stdlib/num_ops.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* num_ops.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <types.h>
|
||||
|
||||
uint32 numlen (int32 number, int32 base)
|
||||
{
|
||||
// Sanity check
|
||||
if (base < 2) return 0;
|
||||
|
||||
uint32 len = (number < 0 && base == 10); // add minus sign
|
||||
if (number == 0) return 1;
|
||||
|
||||
while (number) {
|
||||
number /= base;
|
||||
++len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32 unumlen (uint32 number, int32 base)
|
||||
{
|
||||
// Sanity check
|
||||
if (base < 2) return 0;
|
||||
|
||||
uint32 len = 0;
|
||||
if (number == 0) return 1;
|
||||
|
||||
while (number) {
|
||||
number /= base;
|
||||
++len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
112
Kernel/library/stdlib/ord_arr.c
Normal file
112
Kernel/library/stdlib/ord_arr.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* ord-arr.c
|
||||
*
|
||||
* Created on: Aug 25, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* memory.c
|
||||
*
|
||||
* Created on: Aug 24, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
int StandardComparePredicate (uint32 a, uint32 b)
|
||||
{
|
||||
if (a > b) return 1;
|
||||
else if (a == b) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
OrderedArray OrderedArrayCreate (uint32 maxSize, ComparePredicate p)
|
||||
{
|
||||
OrderedArray ret;
|
||||
ret.Data = (unsigned*) kmalloc(maxSize);
|
||||
memset(ret.Data, 0, maxSize);
|
||||
ret.Size = 0;
|
||||
ret.SizeLimit = maxSize;
|
||||
ret.Compare = (p == 0) ? StandardComparePredicate : p;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OrderedArray OrderedArrayPlace (uint32 addr, uint32 maxSize, ComparePredicate p)
|
||||
{
|
||||
OrderedArray ret;
|
||||
ret.Data = (unsigned*)addr;
|
||||
memset(ret.Data, 0, maxSize);
|
||||
ret.Size = 0;
|
||||
ret.SizeLimit = maxSize;
|
||||
ret.Compare = (p == 0) ? StandardComparePredicate : p;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void OrderedArrayDispose (OrderedArray* arr)
|
||||
{
|
||||
kfree(arr->Data);
|
||||
}
|
||||
|
||||
uint32 OrderedArrayBinarySearch (uint32 key, uint32* array, uint32 length, ComparePredicate predicate)
|
||||
{
|
||||
if (!predicate) return 0;
|
||||
|
||||
uint32 left = 0, right = length, mid;
|
||||
|
||||
while (left < right)
|
||||
{
|
||||
mid = left + (right-left) / 2;
|
||||
|
||||
int r = (*predicate)(key, array[mid]);
|
||||
|
||||
if (r > 0) left = mid + 1;
|
||||
else if (r < 0) right = mid;
|
||||
else return mid;
|
||||
}
|
||||
mid = left + (right-left) / 2;
|
||||
|
||||
return mid;
|
||||
}
|
||||
|
||||
uint32 OrderedArraySearch (uint32 key, OrderedArray* arr, ComparePredicate predicate)
|
||||
{
|
||||
uint32 r = OrderedArrayBinarySearch(key,arr->Data,arr->Size,predicate);
|
||||
|
||||
if (arr->Data[r] != key) return 0xffffffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
void OrderedArrayInsert (uint32 item, OrderedArray* arr)
|
||||
{
|
||||
if (arr->Size >= arr->SizeLimit) return;
|
||||
|
||||
uint32 location = OrderedArrayBinarySearch(item, arr->Data, arr->Size, arr->Compare);
|
||||
|
||||
uint32 i;
|
||||
for (i = arr->Size; i > location && arr->Size > 0; i--)
|
||||
arr->Data[i] = arr->Data[i-1];
|
||||
|
||||
arr->Data[location] = item;
|
||||
arr->Size++;
|
||||
}
|
||||
|
||||
uint32 OrderedArrayLookup (uint32 index, OrderedArray* arr)
|
||||
{
|
||||
if (index >= arr->Size) return 0;
|
||||
return arr->Data[index];
|
||||
}
|
||||
|
||||
void OrderedArrayDeleteIndex (uint32 index, OrderedArray* arr)
|
||||
{
|
||||
if (index >= arr->Size) return;
|
||||
|
||||
uint32 i;
|
||||
for (i = index + 1; i < arr->Size; i++)
|
||||
arr->Data[i - 1] = arr->Data[i];
|
||||
arr->Size--;
|
||||
}
|
||||
39
Kernel/library/stdlib/str_ops.c
Normal file
39
Kernel/library/stdlib/str_ops.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* str_ops.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <types.h>
|
||||
|
||||
uint32 strlen (string s)
|
||||
{
|
||||
string end = s;
|
||||
while (*end != '\0')
|
||||
end++;
|
||||
|
||||
return (uint32)(end - s);
|
||||
}
|
||||
|
||||
int32 strcmp (string a, string b)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
|
||||
while (*a != '\0' && *b != '\0' && *a == *b) {
|
||||
a++; b++;
|
||||
}
|
||||
|
||||
c1 = (*(unsigned char*) a);
|
||||
c2 = (*(unsigned char*) b);
|
||||
return ((c1 < c2) ? -1 : (c1 > c2));
|
||||
}
|
||||
|
||||
string strcpy (string s1, const string s2)
|
||||
{
|
||||
char *dst = s1;
|
||||
const char *src = s2;
|
||||
|
||||
while ((*dst++ = *src++) != '\0') ;
|
||||
|
||||
return s1;
|
||||
}
|
||||
18
Kernel/library/storage.c
Normal file
18
Kernel/library/storage.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* storage.c
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <storage.h>
|
||||
|
||||
void ConvertLbaToChs(uint32 SectorsPerTrack, uint32 lba, uint32 *cyl, uint32 *head, uint32 *sector)
|
||||
{
|
||||
// Avoid division by 0
|
||||
if (SectorsPerTrack == 0) return;
|
||||
|
||||
*head = (lba % (SectorsPerTrack * 2)) / SectorsPerTrack;
|
||||
*cyl = lba / (SectorsPerTrack * 2);
|
||||
*sector = lba % SectorsPerTrack + 1;
|
||||
}
|
||||
98
Kernel/library/time.c
Normal file
98
Kernel/library/time.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <time.h>
|
||||
extern volatile TimeSystem _internal_time;
|
||||
extern uint32 _internal_frequency_hz;
|
||||
|
||||
// Length of months (summed)
|
||||
const int16 MonthLen[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
|
||||
|
||||
|
||||
TimeSystem TimeConvertToTimeSystem (Time t)
|
||||
{
|
||||
TimeSystem sys = {0,0};
|
||||
|
||||
t.Year--; t.Month--; t.Day--; t.WeekDay--;
|
||||
|
||||
sys.Time = (uint32)(t.Hour * 3600000) + (uint32)(t.Minute * 60000) + (uint32)(t.Second * 1000) + (uint32)t.Milisecond;
|
||||
|
||||
if (t.Year < 0) return sys;
|
||||
|
||||
sys.Date = (uint32)(t.Day) + (uint32)(MonthLen[t.Month])
|
||||
+ (uint32)((t.Year/4) * (365*4 + 1)) + (uint32)(t.Year%4 * 365);
|
||||
|
||||
return sys;
|
||||
}
|
||||
|
||||
Time TimeConvertToTime (TimeSystem InternalTime)
|
||||
{
|
||||
Time t;
|
||||
t.Milisecond = InternalTime.Time % 1000;
|
||||
t.Second = (InternalTime.Time / 1000) % 60;
|
||||
t.Minute = (InternalTime.Time / 60000) % 60;
|
||||
t.Hour = (InternalTime.Time / 3600000);
|
||||
|
||||
|
||||
uint32 DayOfYear = (InternalTime.Date % 1461) % 365;
|
||||
t.Year = (InternalTime.Date / 1461)*4 + (InternalTime.Date % 1461)/365 + 1;
|
||||
t.Month = 11;
|
||||
while ((int32)DayOfYear < (MonthLen[t.Month] + (t.Year % 4 == 0 && t.Month>1))) t.Month--;
|
||||
t.WeekDay = InternalTime.Date % 7;
|
||||
t.Day = DayOfYear - MonthLen[t.Month] - (t.Year % 4 == 0 && t.Month>1);
|
||||
|
||||
t.Month++; t.WeekDay++; t.Day++;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
uint16 TimeCalculateWeekday (Time t)
|
||||
{
|
||||
t.Year--;
|
||||
uint32 d = (uint32)(t.Day-1) + (uint32)(MonthLen[t.Month-1]) +
|
||||
+ (uint32)((t.Year/4) * (365*4 + 1)) + (uint32)(t.Year%4 * 365);
|
||||
|
||||
return 1 + (d%7);
|
||||
}
|
||||
|
||||
|
||||
TimeSystem TimeGetInternalTime()
|
||||
{
|
||||
return _internal_time;
|
||||
}
|
||||
|
||||
void TimeSetInternalTime(TimeSystem t)
|
||||
{
|
||||
_internal_time = t;
|
||||
}
|
||||
|
||||
uint32 TimeGetInternalFrequency ()
|
||||
{
|
||||
return _internal_frequency_hz;
|
||||
}
|
||||
|
||||
void TimeSetInternalFrequency (uint32 f)
|
||||
{
|
||||
_internal_frequency_hz = f;
|
||||
}
|
||||
|
||||
|
||||
TimeSystem _timer;
|
||||
#define MILISECONDS_IN_DAY 86400000
|
||||
|
||||
void TimerStart (uint32 ms)
|
||||
{
|
||||
_timer = TimeGetInternalTime();
|
||||
_timer.Time += ms;
|
||||
|
||||
if (_timer.Time >= MILISECONDS_IN_DAY)
|
||||
{
|
||||
_timer.Date++;
|
||||
_timer.Time-=MILISECONDS_IN_DAY;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 TimerIsDone ()
|
||||
{
|
||||
TimeSystem now = TimeGetInternalTime();
|
||||
if (_timer.Date >= now.Date && _timer.Time > now.Time) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
98
Kernel/loader.asm
Normal file
98
Kernel/loader.asm
Normal file
@@ -0,0 +1,98 @@
|
||||
bits 32
|
||||
|
||||
global start
|
||||
|
||||
; multiboot header
|
||||
MODULEALIGN equ 1<<0
|
||||
MEMINFO equ 1<<1
|
||||
VIDEOINFO equ 1<<2
|
||||
FLAGS equ MODULEALIGN | MEMINFO | VIDEOINFO
|
||||
MAGIC equ 0x1BADB002
|
||||
CHECKSUM equ -(MAGIC + FLAGS)
|
||||
|
||||
align 4
|
||||
section .__mbHeader
|
||||
MultiBootHeader:
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
section .text
|
||||
|
||||
STACKSIZE equ 0x4000 ; that's 16k.
|
||||
|
||||
start:
|
||||
XCHG BX, BX ; magic breakpoint
|
||||
|
||||
mov ecx, eax
|
||||
|
||||
; lgdt [trickgdt]
|
||||
; mov ax, 0x10;
|
||||
; mov ds, ax
|
||||
; mov es, ax
|
||||
; mov fs, ax
|
||||
; mov gs, ax
|
||||
; mov ss, ax
|
||||
|
||||
; jmp 0x08:HigherHalf ; NOTE: Must be absolute jump!
|
||||
|
||||
HigherHalf:
|
||||
|
||||
; Verify booted with multiboot compliant bootloader
|
||||
mov esp, stack+STACKSIZE
|
||||
|
||||
cmp ecx, 0x2BADB002
|
||||
jne .bad
|
||||
|
||||
push ebx
|
||||
|
||||
extern k_main
|
||||
call k_main
|
||||
|
||||
; Show error message, and halt system
|
||||
.bad:
|
||||
|
||||
extern ConsoleClear
|
||||
extern ConsoleWrite
|
||||
extern CommandOsver
|
||||
|
||||
call ConsoleClear
|
||||
call CommandOsver
|
||||
|
||||
mov eax, [ErrorColor]
|
||||
push eax
|
||||
push ErrorString
|
||||
call ConsoleWrite
|
||||
|
||||
cli
|
||||
hlt
|
||||
|
||||
|
||||
; some variables
|
||||
ErrorString db 0xA, "%#! Fatal error: Not booted with multiboot compliant bootloader (e.g. GRUB).", 0x0
|
||||
ErrorColor db 0x0C
|
||||
|
||||
|
||||
|
||||
; tells the assembler to include this data in the '.setup' section
|
||||
section .setup
|
||||
|
||||
trickgdt:
|
||||
dw gdt_end - gdt - 1 ; size of the GDT
|
||||
dd gdt ; linear address of GDT
|
||||
|
||||
gdt:
|
||||
dd 0, 0 ; null gate
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 ; code selector 0x08: base 0x40000000, limit 0xFFFFFFFF, type 0x9A, granularity 0xCF
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 ; data selector 0x10: base 0x40000000, limit 0xFFFFFFFF, type 0x92, granularity 0xCF
|
||||
|
||||
gdt_end:
|
||||
|
||||
|
||||
|
||||
|
||||
; stack
|
||||
section .bss
|
||||
align 32
|
||||
stack:
|
||||
resb STACKSIZE ; This reserves 64KBytes of memory here
|
||||
99
Kernel/loader.asm~
Normal file
99
Kernel/loader.asm~
Normal file
@@ -0,0 +1,99 @@
|
||||
bits 32
|
||||
|
||||
global start
|
||||
|
||||
; multiboot header
|
||||
MODULEALIGN equ 1<<0
|
||||
MEMINFO equ 1<<1
|
||||
VIDEOINFO equ 1<<2
|
||||
FLAGS equ MODULEALIGN | MEMINFO | VIDEOINFO
|
||||
MAGIC equ 0x1BADB002
|
||||
CHECKSUM equ -(MAGIC + FLAGS)
|
||||
|
||||
|
||||
section .__mbHeader
|
||||
align 4
|
||||
MultiBootHeader:
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
section .text
|
||||
|
||||
STACKSIZE equ 0x4000 ; that's 16k.
|
||||
|
||||
start:
|
||||
XCHG BX, BX ; magic breakpoint
|
||||
|
||||
mov ecx, eax
|
||||
|
||||
; lgdt [trickgdt]
|
||||
; mov ax, 0x10;
|
||||
; mov ds, ax
|
||||
; mov es, ax
|
||||
; mov fs, ax
|
||||
; mov gs, ax
|
||||
; mov ss, ax
|
||||
|
||||
; jmp 0x08:HigherHalf ; NOTE: Must be absolute jump!
|
||||
|
||||
HigherHalf:
|
||||
|
||||
; Verify booted with multiboot compliant bootloader
|
||||
mov esp, stack+STACKSIZE
|
||||
|
||||
cmp ecx, 0x2BADB002
|
||||
jne .bad
|
||||
|
||||
push ebx
|
||||
|
||||
extern k_main
|
||||
call k_main
|
||||
|
||||
; Show error message, and halt system
|
||||
.bad:
|
||||
|
||||
extern ConsoleClear
|
||||
extern ConsoleWrite
|
||||
extern CommandOsver
|
||||
|
||||
call ConsoleClear
|
||||
call CommandOsver
|
||||
|
||||
mov eax, [ErrorColor]
|
||||
push eax
|
||||
push ErrorString
|
||||
call ConsoleWrite
|
||||
|
||||
cli
|
||||
hlt
|
||||
|
||||
|
||||
; some variables
|
||||
ErrorString db 0xA, "%#! Fatal error: Not booted with multiboot compliant bootloader (e.g. GRUB).", 0x0
|
||||
ErrorColor db 0x0C
|
||||
|
||||
|
||||
|
||||
; tells the assembler to include this data in the '.setup' section
|
||||
section .setup
|
||||
|
||||
trickgdt:
|
||||
dw gdt_end - gdt - 1 ; size of the GDT
|
||||
dd gdt ; linear address of GDT
|
||||
|
||||
gdt:
|
||||
dd 0, 0 ; null gate
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 ; code selector 0x08: base 0x40000000, limit 0xFFFFFFFF, type 0x9A, granularity 0xCF
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 ; data selector 0x10: base 0x40000000, limit 0xFFFFFFFF, type 0x92, granularity 0xCF
|
||||
|
||||
gdt_end:
|
||||
|
||||
|
||||
|
||||
|
||||
; stack
|
||||
section .bss
|
||||
align 32
|
||||
stack:
|
||||
resb STACKSIZE ; This reserves 64KBytes of memory here
|
||||
27
Kernel/main.c
Normal file
27
Kernel/main.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "hal/hal.h"
|
||||
#include "drivers/drivers.h"
|
||||
#include <debugio.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
extern uint32 _end;
|
||||
|
||||
void k_main(MultibootInfo* info)
|
||||
{
|
||||
uint32 KernelEnd = (uint32)&_end;
|
||||
MemoryTempInitialize(KernelEnd);
|
||||
|
||||
ConsoleClear();
|
||||
HalInitialize();
|
||||
DriversInstall();
|
||||
|
||||
// Set up memory manager
|
||||
MemoryInitialize(info);
|
||||
|
||||
Log("All ready. Starting console...\n\n");
|
||||
|
||||
ConsoleMain();
|
||||
}
|
||||
27
Kernel/main.c~
Normal file
27
Kernel/main.c~
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "hal/hal.h"
|
||||
#include "drivers/drivers.h"
|
||||
#include <debugio.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
extern uint32 _end;
|
||||
|
||||
void k_main(MultibootInfo* info)
|
||||
{
|
||||
uint32 KernelEnd = (uint32)&_end;
|
||||
MemoryTempInitialize(KernelEnd);
|
||||
|
||||
ConsoleClear();
|
||||
HalInitialize();
|
||||
DriversInstall();
|
||||
|
||||
// Set up memory manager
|
||||
MemoryInitialize(&info_new);
|
||||
|
||||
Log("All ready. Starting console...\n\n");
|
||||
|
||||
ConsoleMain();
|
||||
}
|
||||
304
Kernel/memory/mem-heap.c
Normal file
304
Kernel/memory/mem-heap.c
Normal file
@@ -0,0 +1,304 @@
|
||||
#include <memory-add.h>
|
||||
#include <debugio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MEMHEAP_MAGIC 0x50DBE514
|
||||
#define MEMHEAP_INDEX_SIZE 0x20000
|
||||
#define MEMHEAP_MINIM_SIZE 0x70000
|
||||
|
||||
#define FlagsKernel 1
|
||||
#define FlagsWriteable 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Magic;
|
||||
// bit 0: used bit 1: reserved
|
||||
uint8 Used;
|
||||
uint32 Size;
|
||||
} MemHeapHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Magic;
|
||||
MemHeapHeader* Header;
|
||||
} MemHeapFooter;
|
||||
|
||||
MemHeap* KernelHeap;
|
||||
|
||||
uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < heap->Index.Size; i++)
|
||||
{
|
||||
MemHeapHeader* head = (MemHeapHeader*) OrderedArrayLookup(i, &heap->Index);
|
||||
|
||||
if (page_align)
|
||||
{
|
||||
uint32 location = (uint32)(head) + sizeof(MemHeapHeader);
|
||||
|
||||
// page align it
|
||||
uint32 offset = 0x1000 - (location & 0xfff);
|
||||
offset &= 0xfff;
|
||||
|
||||
if (head->Size - offset >= size) return i;
|
||||
}
|
||||
|
||||
else if (head->Size >= size) return i;
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
int32 MemHeapCompare (uint32 a, uint32 b)
|
||||
{
|
||||
MemHeapHeader *ha = (MemHeapHeader*)a, *hb = (MemHeapHeader*)b;
|
||||
|
||||
if (ha->Size > hb->Size) return 1;
|
||||
else if (ha->Size == hb->Size) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
inline void MemHeapHeaderSetup (uint32 size, uint8 used, MemHeapHeader* head)
|
||||
{
|
||||
head->Magic = MEMHEAP_MAGIC;
|
||||
head->Used = used;
|
||||
head->Size = size;
|
||||
}
|
||||
|
||||
inline void MemHeapFooterSetup (MemHeapHeader* head, MemHeapFooter* foot)
|
||||
{
|
||||
foot->Magic = MEMHEAP_MAGIC;
|
||||
foot->Header = head;
|
||||
}
|
||||
|
||||
|
||||
MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags)
|
||||
{
|
||||
if ((start & 0xfff) || (end & 0xfff)) return NULL;
|
||||
|
||||
MemHeap* heap = (MemHeap*) kmalloc(sizeof(MemHeap));
|
||||
heap->Index = OrderedArrayPlace(start, MEMHEAP_INDEX_SIZE, MemHeapCompare);
|
||||
|
||||
start += sizeof(uint32) * MEMHEAP_INDEX_SIZE;
|
||||
|
||||
if (start & 0xfff) start = (start & 0xFFFFF000) + 0x1000;
|
||||
|
||||
heap->StartAddress = start;
|
||||
heap->EndAddress = end;
|
||||
heap->Flags = flags;
|
||||
heap->MaxAddress = max;
|
||||
|
||||
// One large hole
|
||||
MemHeapHeader* hole = (MemHeapHeader*)start;
|
||||
MemHeapHeaderSetup(end-start, 0, hole);
|
||||
OrderedArrayInsert(start, &heap->Index);
|
||||
|
||||
return heap;
|
||||
}
|
||||
|
||||
|
||||
void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
if (newsz <= heap->EndAddress - heap->StartAddress) return;
|
||||
|
||||
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000;
|
||||
if (newsz + heap->StartAddress >= heap->MaxAddress) return;
|
||||
|
||||
uint32 i;
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
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 - heap->StartAddress - 0x1000; i > newsz; i-=0x1000)
|
||||
MemPhFreeFrame(PagingGetPage(i, 0, pd));
|
||||
|
||||
heap->EndAddress = heap->StartAddress + newsz;
|
||||
return newsz;
|
||||
}
|
||||
|
||||
|
||||
uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
// Sanity check
|
||||
if (!size || !heap) return 0;
|
||||
|
||||
// Find a good hole
|
||||
uint32 newsize = size + sizeof(MemHeapHeader) + sizeof(MemHeapFooter);
|
||||
uint32 i = MemHeapFindSmallestHole(newsize, isPageAligned, heap);
|
||||
|
||||
// Didn't find? Expand heap
|
||||
if (i == 0xffffffff)
|
||||
{
|
||||
uint32 oldLen = heap->EndAddress - heap->StartAddress;
|
||||
uint32 oldEnd = heap->EndAddress;
|
||||
MemHeapExpand(oldLen + newsize, heap, pd);
|
||||
|
||||
uint32 newLen = heap->EndAddress - heap->StartAddress;
|
||||
|
||||
// Find the last header
|
||||
uint32 i = 0, index = 0, addr = 0;
|
||||
for (; i < heap->Index.Size; i++)
|
||||
{
|
||||
uint32 tmp = OrderedArrayLookup(i, &heap->Index);
|
||||
if (tmp > addr) {
|
||||
addr = tmp; index = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemHeapHeader* head; MemHeapFooter* foot;
|
||||
|
||||
if (heap->Index.Size == 0) // No headers? Add one
|
||||
{
|
||||
head = (MemHeapHeader*)oldEnd;
|
||||
MemHeapHeaderSetup(newLen - oldLen, 0, head);
|
||||
OrderedArrayInsert(oldEnd, &heap->Index);
|
||||
}
|
||||
|
||||
else { // Modify last header
|
||||
head = (MemHeapHeader*) OrderedArrayLookup(index, &heap->Index);
|
||||
head->Size = newLen - oldLen;
|
||||
}
|
||||
|
||||
foot = (MemHeapFooter*)((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(head, foot);
|
||||
|
||||
// Try again
|
||||
return MemHeapAlloc(size, isPageAligned, heap, pd);
|
||||
}
|
||||
|
||||
// Get info about hole
|
||||
uint32 origAddr = OrderedArrayLookup(i, &heap->Index);
|
||||
MemHeapHeader* origHead =(MemHeapHeader*) origAddr;
|
||||
uint32 origSize = origHead->Size;
|
||||
|
||||
// Should split in two?
|
||||
if (origSize - newsize <= sizeof(MemHeapHeader) + sizeof(MemHeapFooter))
|
||||
{
|
||||
size += origSize - newsize;
|
||||
newsize = origSize;
|
||||
}
|
||||
|
||||
// Should be page aligned
|
||||
if (isPageAligned && (origAddr&0xfffff000))
|
||||
{
|
||||
uint32 newAddr = origAddr + 0x1000 - (origAddr&0xfff) - sizeof(MemHeapHeader);
|
||||
MemHeapHeaderSetup(0x1000 - (origAddr&0xfff) - sizeof(MemHeapHeader), 0, origHead);
|
||||
|
||||
MemHeapFooter* holeFooter = (MemHeapFooter*)(newAddr - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(origHead, holeFooter);
|
||||
|
||||
origAddr = newAddr;
|
||||
origSize -= origHead->Size;
|
||||
}
|
||||
|
||||
else OrderedArrayDeleteIndex(i, &heap->Index);
|
||||
|
||||
// Create the new block
|
||||
MemHeapHeader* bHead = (MemHeapHeader*)origAddr;
|
||||
MemHeapFooter* bFoot = (MemHeapFooter*)(origAddr + sizeof(MemHeapHeader) + size);
|
||||
MemHeapHeaderSetup(newsize, 1, bHead);
|
||||
MemHeapFooterSetup(bHead, bFoot);
|
||||
|
||||
// Create a new hole at the end of current block if necessary
|
||||
if (origSize - newsize > 0)
|
||||
{
|
||||
// header
|
||||
MemHeapHeader* hHead = (MemHeapHeader*)(origAddr + sizeof(MemHeapHeader) +
|
||||
sizeof(MemHeapFooter) + size);
|
||||
MemHeapHeaderSetup(origSize - newsize, 0, hHead);
|
||||
|
||||
// footer
|
||||
MemHeapFooter* hFoot = (MemHeapFooter*)((uint32)hHead + hHead->Size - sizeof(MemHeapFooter));
|
||||
if ((uint32)hFoot < heap->EndAddress) MemHeapFooterSetup(hHead, hFoot);
|
||||
|
||||
// add it to index
|
||||
OrderedArrayInsert((uint32)hHead, &heap->Index);
|
||||
}
|
||||
|
||||
return (uint32)bHead + sizeof(MemHeapHeader);
|
||||
}
|
||||
|
||||
void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
// Sanity check
|
||||
if (!address || !heap) return;
|
||||
|
||||
MemHeapHeader* head = (MemHeapHeader*) (address - sizeof(MemHeapHeader));
|
||||
MemHeapFooter* foot = (MemHeapFooter*) ((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
|
||||
if (head->Magic != MEMHEAP_MAGIC) return;
|
||||
if (foot->Magic != MEMHEAP_MAGIC) return;
|
||||
|
||||
// Clear used flag
|
||||
head->Used = 0;
|
||||
|
||||
uint8 AddToIndex = 1;
|
||||
|
||||
// Unify left (if possible)
|
||||
MemHeapFooter* testFoot = (MemHeapFooter*) ((uint32)head - sizeof(MemHeapFooter));
|
||||
if (testFoot->Magic == MEMHEAP_MAGIC && testFoot->Header->Used == 0)
|
||||
{
|
||||
uint32 temp = head->Size;
|
||||
head = testFoot->Header;
|
||||
foot->Header = head;
|
||||
head->Size += temp;
|
||||
|
||||
AddToIndex = 0;
|
||||
}
|
||||
|
||||
// Unify right (if possible)
|
||||
MemHeapHeader* testHead = (MemHeapHeader*) ((uint32)foot + sizeof(MemHeapFooter));
|
||||
if ((uint32)testHead < heap->EndAddress && testHead->Magic == MEMHEAP_MAGIC && testHead->Used == 0)
|
||||
{
|
||||
head->Size += testHead->Size;
|
||||
testFoot = (MemHeapFooter*) ((uint32)testHead + testHead->Size - sizeof(MemHeapFooter));
|
||||
foot = testFoot;
|
||||
|
||||
uint32 i;
|
||||
for (i = 0; i < heap->Index.Size &&
|
||||
(uint32)testHead != OrderedArrayLookup(i, &heap->Index); i++) ;
|
||||
|
||||
if (i < heap->Index.Size) OrderedArrayDeleteIndex(i, &heap->Index);
|
||||
}
|
||||
|
||||
// Contract heap (if possible)
|
||||
if ((uint32)foot + sizeof(MemHeapFooter) == heap->EndAddress)
|
||||
{
|
||||
uint32 old = heap->EndAddress - heap->StartAddress;
|
||||
uint32 new = MemHeapContract((uint32)head + head->Size - sizeof(MemHeapFooter), heap,pd);
|
||||
|
||||
// Last block still existent
|
||||
if (head->Size > (old - new))
|
||||
{
|
||||
head->Size -= old - new;
|
||||
foot = (MemHeapFooter*) ((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(head, foot);
|
||||
}
|
||||
|
||||
// Nope, not existent
|
||||
else
|
||||
{
|
||||
uint32 i;
|
||||
for (i=0; i<heap->Index.Size && (uint32)testHead != OrderedArrayLookup(i,&heap->Index); i++) ;
|
||||
|
||||
if (i < heap->Index.Size) OrderedArrayDeleteIndex(i,&heap->Index);
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, insert hole in array
|
||||
if (AddToIndex) OrderedArrayInsert((uint32)head, &heap->Index);
|
||||
}
|
||||
|
||||
|
||||
74
Kernel/memory/mem-paging.c
Normal file
74
Kernel/memory/mem-paging.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* memory-vi.c
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <stdio.h>
|
||||
/*******************************
|
||||
* Data *
|
||||
*******************************/
|
||||
PageDirectory* CurrentDirectory;
|
||||
PageDirectory* KernelDirectory;
|
||||
|
||||
/*******************************
|
||||
* Useful routines *
|
||||
*******************************/
|
||||
void PagingInitialize(uint32 kernel_used)
|
||||
{
|
||||
LogMem("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));
|
||||
|
||||
CurrentDirectory = kernelPd;
|
||||
KernelDirectory = kernelPd;
|
||||
|
||||
uint32 i;
|
||||
for (i = 0; i < kernel_used; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0);
|
||||
|
||||
LogMem("Identity mapped first 0x%x bytes.\n", kernel_used);
|
||||
|
||||
for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 1, 1);
|
||||
|
||||
LogMem("Mapped kernel space.\n");
|
||||
|
||||
PagingSwitchPageDirectory (kernelPd);
|
||||
}
|
||||
|
||||
void PagingSwitchPageDirectory (PageDirectory* dir)
|
||||
{
|
||||
CurrentDirectory = dir;
|
||||
asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical));
|
||||
|
||||
uint32 cr0;
|
||||
asm volatile ("mov %%cr0, %0": "=r"(cr0));
|
||||
cr0 |= 0x80000000;
|
||||
asm volatile ("mov %0, %%cr0":: "r"(cr0));
|
||||
|
||||
LogMem("Enabled paging.\n");
|
||||
}
|
||||
|
||||
Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir)
|
||||
{
|
||||
addr >>= 12;
|
||||
|
||||
uint32 tableIndex = addr >> 10;
|
||||
|
||||
if (dir->Tables[tableIndex])
|
||||
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
|
||||
|
||||
else if (make)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
else return 0;
|
||||
}
|
||||
|
||||
75
Kernel/memory/mem-paging.c~
Normal file
75
Kernel/memory/mem-paging.c~
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* memory-vi.c
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <stdio.h>
|
||||
/*******************************
|
||||
* Data *
|
||||
*******************************/
|
||||
PageDirectory* CurrentDirectory;
|
||||
PageDirectory* KernelDirectory;
|
||||
|
||||
/*******************************
|
||||
* Useful routines *
|
||||
*******************************/
|
||||
void PagingInitialize(uint32 kernel_used)
|
||||
{
|
||||
LogMem("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));
|
||||
|
||||
CurrentDirectory = kernelPd;
|
||||
KernelDirectory = kernelPd;
|
||||
|
||||
uint32 i;
|
||||
for (i = 0; i < kernel_used; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0);
|
||||
|
||||
LogMem("Identity mapped first 0x%x bytes.\n", kernel_used);
|
||||
|
||||
for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 1, 1);
|
||||
|
||||
LogMem("Mapped kernel space.\n");
|
||||
|
||||
PagingSwitchPageDirectory (kernelPd);
|
||||
}
|
||||
|
||||
void PagingSwitchPageDirectory (PageDirectory* dir)
|
||||
{
|
||||
CurrentDirectory = dir;
|
||||
asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical));
|
||||
LogMem("Switched page directory to 0x%x.\n", (uint32)(&dir->TablesPhysical));
|
||||
|
||||
uint32 cr0;
|
||||
asm volatile ("mov %%cr0, %0": "=r"(cr0));
|
||||
cr0 |= 0x80000000;
|
||||
asm volatile ("mov %0, %%cr0":: "r"(cr0));
|
||||
|
||||
LogMem("Enabled paging.\n");
|
||||
}
|
||||
|
||||
Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir)
|
||||
{
|
||||
addr >>= 12;
|
||||
|
||||
uint32 tableIndex = addr >> 10;
|
||||
|
||||
if (dir->Tables[tableIndex])
|
||||
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
|
||||
|
||||
else if (make)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
else return 0;
|
||||
}
|
||||
|
||||
108
Kernel/memory/mem-phys.c
Normal file
108
Kernel/memory/mem-phys.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* mem-phys.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
|
||||
uint32* FrameMap;
|
||||
uint32 TotalFrames;
|
||||
uint32 TotalMemory;
|
||||
uint32 UsedFrames;
|
||||
|
||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
|
||||
{
|
||||
*address = (index >> 5);
|
||||
*offset = index & 0x1f;
|
||||
}
|
||||
|
||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
|
||||
{
|
||||
return (address<<5) | offset;
|
||||
}
|
||||
|
||||
void MemPhSetFrame (uint32 frame, uint8 value)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
if (value) {
|
||||
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
|
||||
FrameMap[addr] |= 1<<off;
|
||||
}
|
||||
|
||||
else {
|
||||
if (FrameMap[addr] & (1<<off)) UsedFrames--;
|
||||
FrameMap[addr] &= ~(1<<off);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MemPhGetFrame (uint32 frame)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
return FrameMap[addr] & (1<<off);
|
||||
}
|
||||
|
||||
uint32 MemPhFindFreeFrame()
|
||||
{
|
||||
uint32 addr, pos;
|
||||
|
||||
for (addr = 0; addr < TotalFrames >> 5; addr++)
|
||||
if (FrameMap[addr] != 0xffffffff)
|
||||
{
|
||||
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
|
||||
return ConvertFrameToIndex(addr, pos);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
|
||||
{
|
||||
if ((*page & PageFrame) != 0) return;
|
||||
|
||||
uint32 free = MemPhFindFreeFrame();
|
||||
if (free == 0xffffffff) {
|
||||
Panic("%#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)
|
||||
{
|
||||
TotalFrames = SystemMemoryKb >> 2;
|
||||
TotalMemory = SystemMemoryKb;
|
||||
|
||||
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
LogMem("%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
|
||||
}
|
||||
|
||||
void MemPhReserveFrames (uint32 address, uint32 length)
|
||||
{
|
||||
address >>= 12;
|
||||
length = (length>>12) + ((length & 0xfff) > 0);
|
||||
uint32 end = address + length;
|
||||
|
||||
for (; address < end ; address++)
|
||||
MemPhSetFrame(address, 1);
|
||||
}
|
||||
109
Kernel/memory/mem-phys.c~
Normal file
109
Kernel/memory/mem-phys.c~
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* mem-phys.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
|
||||
uint32* FrameMap;
|
||||
uint32 TotalFrames;
|
||||
uint32 TotalMemory;
|
||||
uint32 UsedFrames;
|
||||
|
||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
|
||||
{
|
||||
*address = (index >> 5);
|
||||
*offset = index & 0x1f;
|
||||
}
|
||||
|
||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
|
||||
{
|
||||
return (address<<5) | offset;
|
||||
}
|
||||
|
||||
void MemPhSetFrame (uint32 frame, uint8 value)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
if (value) {
|
||||
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
|
||||
FrameMap[addr] |= 1<<off;
|
||||
}
|
||||
|
||||
else {
|
||||
if (FrameMap[addr] & (1<<off)) UsedFrames--;
|
||||
FrameMap[addr] &= ~(1<<off);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MemPhGetFrame (uint32 frame)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
return FrameMap[addr] & (1<<off);
|
||||
}
|
||||
|
||||
uint32 MemPhFindFreeFrame()
|
||||
{
|
||||
uint32 addr, pos;
|
||||
|
||||
for (addr = 0; addr < TotalFrames >> 5; addr++)
|
||||
if (FrameMap[addr] != 0xffffffff)
|
||||
{
|
||||
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
|
||||
return ConvertFrameToIndex(addr, pos);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
|
||||
{
|
||||
if ((*page & PageFrame) != 0) return;
|
||||
|
||||
uint32 free = MemPhFindFreeFrame();
|
||||
if (free == 0xffffffff) {
|
||||
Panic("%#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)
|
||||
{
|
||||
LogMem("Starting physical memory manager...\n");
|
||||
TotalFrames = SystemMemoryKb >> 2;
|
||||
TotalMemory = SystemMemoryKb;
|
||||
|
||||
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
LogMem("%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
|
||||
}
|
||||
|
||||
void MemPhReserveFrames (uint32 address, uint32 length)
|
||||
{
|
||||
address >>= 12;
|
||||
length = (length>>12) + ((length & 0xfff) > 0);
|
||||
uint32 end = address + length;
|
||||
|
||||
for (; address < end ; address++)
|
||||
MemPhSetFrame(address, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user