Compare commits
	
		
			32 Commits
		
	
	
		
			7993a2d172
			...
			DebugLoggi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6086b04054 | |||
| 9c5667c454 | |||
| 2522492835 | |||
| e82392e9d9 | |||
| 64c87a2a58 | |||
| 04470edcc6 | |||
| 2970806705 | |||
| e8df6ec628 | |||
| 5781f730d9 | |||
| 2d0bb16fad | |||
| e6901f0526 | |||
| 61f1852420 | |||
| 32b0d990df | |||
| 745656eb2d | |||
| 644ff5b1f5 | |||
| a77621faf5 | |||
| 50bf952a49 | |||
| ef2bba5c1c | |||
| 81f7351fe6 | |||
| dea8ab7d71 | |||
| 2bcc79216e | |||
| b07b4f0d38 | |||
| 94a2de3847 | |||
| dbb147e110 | |||
| 37542b736f | |||
| 490529099b | |||
| 133c16cae7 | |||
| ecab248cd6 | |||
| 4ce7cc093b | |||
| c9a036bfbb | |||
| 1f90a5d862 | |||
| 520104a43a | 
							
								
								
									
										7
									
								
								.gdbinit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.gdbinit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
target remote localhost:1234
 | 
			
		||||
 | 
			
		||||
file root/boot/myos.bin
 | 
			
		||||
symbol-file kernel.sym
 | 
			
		||||
 | 
			
		||||
break prekernel/prekernel.cpp:18
 | 
			
		||||
continue
 | 
			
		||||
							
								
								
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,10 +1,15 @@
 | 
			
		||||
build
 | 
			
		||||
CON
 | 
			
		||||
.vscode
 | 
			
		||||
build/
 | 
			
		||||
bin/
 | 
			
		||||
.vscode/
 | 
			
		||||
.idea/
 | 
			
		||||
isodir/
 | 
			
		||||
root/
 | 
			
		||||
*.iso
 | 
			
		||||
*.img
 | 
			
		||||
*.sym
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/CoreLib/warnings.log
 | 
			
		||||
/kernel/warnings.log
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								CoreLib/List.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								CoreLib/List.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 25/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class List {
 | 
			
		||||
public:
 | 
			
		||||
    List* next;
 | 
			
		||||
    void* data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								CoreLib/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								CoreLib/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
CPP = /opt/cross/bin/i686-elf-g++
 | 
			
		||||
CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
BUILD_DIR = ../build/CoreLib
 | 
			
		||||
OBJ_FOLDER = ../bin/CoreLib
 | 
			
		||||
OUTPUTFILE = $(BUILD_DIR)/libCoreLib.a
 | 
			
		||||
 | 
			
		||||
OFILES = $(OBJ_FOLDER)/ctype.o $(OBJ_FOLDER)/memory.o $(OBJ_FOLDER)/path.o $(OBJ_FOLDER)/stack.o $(OBJ_FOLDER)/string.o $(OBJ_FOLDER)/stringview.o
 | 
			
		||||
 | 
			
		||||
.phony: all
 | 
			
		||||
all: $(OUTPUTFILE)
 | 
			
		||||
	cp *.h $(BUILD_DIR)/include/CoreLib
 | 
			
		||||
 | 
			
		||||
$(OUTPUTFILE): $(OFILES)
 | 
			
		||||
	pwd
 | 
			
		||||
	ar -rc $(OUTPUTFILE) $(OFILES)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/ctype.o: ctype.cpp
 | 
			
		||||
	$(CPP) -c ctype.cpp -o $(OBJ_FOLDER)/ctype.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/memory.o: Memory.cpp
 | 
			
		||||
	$(CPP) -c Memory.cpp -o $(OBJ_FOLDER)/memory.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/path.o: Path.cpp
 | 
			
		||||
	$(CPP) -c Path.cpp  -o $(OBJ_FOLDER)/path.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/stack.o: Stack.cpp
 | 
			
		||||
	$(CPP) -c Stack.cpp  -o $(OBJ_FOLDER)/stack.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/string.o: String.cpp
 | 
			
		||||
	$(CPP) -c String.cpp -o $(OBJ_FOLDER)/string.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
$(OBJ_FOLDER)/stringview.o: StringView.cpp
 | 
			
		||||
	$(CPP) -c StringView.cpp  -o $(OBJ_FOLDER)/stringview.o $(CFLAGS)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								CoreLib/Memory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								CoreLib/Memory.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
#include "Memory.h"
 | 
			
		||||
 | 
			
		||||
void* memset (void* ptr, int value, size_t num)
 | 
			
		||||
{
 | 
			
		||||
    for( int i = 0; i < num; i++ )
 | 
			
		||||
    {
 | 
			
		||||
        unsigned char* data  = (unsigned char*)ptr+ i;
 | 
			
		||||
        *data = (unsigned char)value;
 | 
			
		||||
    }
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int memcmp( const void* ptr1, const void* ptr2, size_t num)
 | 
			
		||||
{
 | 
			
		||||
    auto* cs = (const unsigned char*) ptr1;
 | 
			
		||||
    auto* ct = (const unsigned char*) ptr2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    for (int i = 0 ; i < num ; i++, cs++, ct++ ){
 | 
			
		||||
        if( *cs != *ct)
 | 
			
		||||
            return *cs - *ct;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[[maybe_unused]] void memcpy (void* dest, const void* src, size_t count ){
 | 
			
		||||
    for( int i = 0; i < count; i++){
 | 
			
		||||
        ((char *)dest)[i] = ((const char*)src)[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char* str) {
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
    while(str[len]){
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num ){
 | 
			
		||||
    for( int i = 0; i < num ; i++){
 | 
			
		||||
 | 
			
		||||
        if( str1[i] < str2[i]){
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( str1[i] > str2[i] ){
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* strchr(const char* s , int c){
 | 
			
		||||
    while(*s) {
 | 
			
		||||
        if(*s == c) return const_cast<char*>(s);
 | 
			
		||||
        s++;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
char* strtok(char* str, const char* delim , char**saveptr){
 | 
			
		||||
    char *begin;
 | 
			
		||||
    if(str) {
 | 
			
		||||
        begin = str;
 | 
			
		||||
    }
 | 
			
		||||
    else if (*saveptr) {
 | 
			
		||||
        begin = *saveptr;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while(strchr(delim, begin[0])) {
 | 
			
		||||
        begin++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    char *next = NULL;
 | 
			
		||||
    for(int i = 0; i < strlen(delim); i++) {
 | 
			
		||||
        char *temp = strchr(begin, delim[i]);
 | 
			
		||||
        if(temp < next || next == NULL) {
 | 
			
		||||
            next = temp;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if(!next) {
 | 
			
		||||
        *saveptr = NULL;
 | 
			
		||||
        return begin;
 | 
			
		||||
    }
 | 
			
		||||
    *next = 0;
 | 
			
		||||
    *saveptr=next+1;
 | 
			
		||||
    return begin;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								CoreLib/Memory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								CoreLib/Memory.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
void* memset (void* ptr, int value, size_t num);
 | 
			
		||||
 | 
			
		||||
int memcmp( const void* ptr1, const void* ptr2, size_t num);
 | 
			
		||||
 | 
			
		||||
[[maybe_unused]] void memcpy (void* dest, const void* src, size_t count );
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char* str);
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num );
 | 
			
		||||
 | 
			
		||||
char* strtok(char* str, const char* delim , char**saveptr);
 | 
			
		||||
							
								
								
									
										24
									
								
								CoreLib/Path.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								CoreLib/Path.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
#include "Path.h"
 | 
			
		||||
 | 
			
		||||
Path::Path(String path)
 | 
			
		||||
: path(path)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StringView Path::getbasename()
 | 
			
		||||
{
 | 
			
		||||
    unsigned int path_length = path.length();
 | 
			
		||||
    int i = path_length;
 | 
			
		||||
    while (path[i] != '/')
 | 
			
		||||
        i--;
 | 
			
		||||
 | 
			
		||||
    return {path,static_cast<unsigned int>(i +1), path_length};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* Path::str() {
 | 
			
		||||
    return path.str();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								CoreLib/Path.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								CoreLib/Path.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "StringView.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Path{
 | 
			
		||||
public:
 | 
			
		||||
    explicit Path(String path);
 | 
			
		||||
 | 
			
		||||
    StringView getbasename();
 | 
			
		||||
 | 
			
		||||
    char* str();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    String path;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								CoreLib/Stack.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								CoreLib/Stack.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
							
								
								
									
										73
									
								
								CoreLib/Stack.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								CoreLib/Stack.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../kernel/memory/KernelHeap.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class Stack {
 | 
			
		||||
    public:
 | 
			
		||||
        inline Stack() {
 | 
			
		||||
                elements = (T[MAX_STACK_SIZE]) malloc(MAX_STACK_SIZE * sizeof(T));
 | 
			
		||||
                num = 0;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void  Push(T element){
 | 
			
		||||
            num++;
 | 
			
		||||
            if(num > MAX_STACK_SIZE)
 | 
			
		||||
                grow();
 | 
			
		||||
 | 
			
		||||
            element[num] = element;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
     
 | 
			
		||||
        inline T Pop()
 | 
			
		||||
        {
 | 
			
		||||
            T temp = elements[num];
 | 
			
		||||
            num --;
 | 
			
		||||
 | 
			
		||||
            return temp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline bool isEmpty()
 | 
			
		||||
        {
 | 
			
		||||
            return num == 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline bool isFull()
 | 
			
		||||
        {
 | 
			
		||||
                return num == MAX_STACK_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
        inline int count()
 | 
			
		||||
        {
 | 
			
		||||
                return num;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline ~Stack()
 | 
			
		||||
        {
 | 
			
		||||
            free(elements);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        unsigned int MAX_STACK_SIZE;
 | 
			
		||||
        T[MAX_STACK_SIZE] elements;
 | 
			
		||||
        unsigned int num;
 | 
			
		||||
 | 
			
		||||
        inline void grow (){
 | 
			
		||||
            MAX_STACK_SIZE = MAX_STACK_SIZE + (int)(MAX_STACK_SIZE / 4);
 | 
			
		||||
            T[] new_elements =(T[MAX_STACK_SIZE]) malloc(MAX_STACK_SIZE * sizeof(T));
 | 
			
		||||
 | 
			
		||||
            for ( int i = 0; i < num ; i++){
 | 
			
		||||
                new_elements[i] = elements[i];
 | 
			
		||||
            }
 | 
			
		||||
            free(elements);
 | 
			
		||||
            elements = new_elements;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								CoreLib/String.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								CoreLib/String.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
#include "String.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
String::String(char* characters)
 | 
			
		||||
: chars(characters)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
char* String::str(){
 | 
			
		||||
    return chars;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int String::length ()
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
 | 
			
		||||
    while (  chars[i] != '\0'){
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns a null character if size exceeds limits
 | 
			
		||||
char String::operator[] (size_t idx)
 | 
			
		||||
{
 | 
			
		||||
    if( idx  > this->length())
 | 
			
		||||
        return '\0';
 | 
			
		||||
 | 
			
		||||
    return chars[idx];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char String::operator[](size_t idx) const {
 | 
			
		||||
return (const char) chars[idx];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								CoreLib/String.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								CoreLib/String.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
class  String {
 | 
			
		||||
public:
 | 
			
		||||
    String(char* characters);
 | 
			
		||||
    String(String&) = default;
 | 
			
		||||
    unsigned int length();
 | 
			
		||||
 | 
			
		||||
    char* str ();
 | 
			
		||||
    char operator[](size_t index) ;
 | 
			
		||||
    const char operator[](size_t idx) const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    char* chars;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										14
									
								
								CoreLib/StringView.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								CoreLib/StringView.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
#include "StringView.h"
 | 
			
		||||
 | 
			
		||||
StringView::StringView(String string, unsigned int start, unsigned int end)
 | 
			
		||||
        : String(string), begin(start), end(end)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* StringView::str(){
 | 
			
		||||
   //TODO: Not implemented
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								CoreLib/StringView.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								CoreLib/StringView.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 19/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "String.h"
 | 
			
		||||
 | 
			
		||||
class StringView : String {
 | 
			
		||||
public:
 | 
			
		||||
    StringView(String string, unsigned int start, unsigned  int end );
 | 
			
		||||
    char* str ();
 | 
			
		||||
private:
 | 
			
		||||
    unsigned int begin;
 | 
			
		||||
    unsigned int end;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										141
									
								
								CoreLib/ctype.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								CoreLib/ctype.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 25/02/23.
 | 
			
		||||
//
 | 
			
		||||
#include "ctype.h"
 | 
			
		||||
 | 
			
		||||
int isupper (int ch){
 | 
			
		||||
    if( ch >= 'A' && ch <= 'Z'){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int islower (int ch){
 | 
			
		||||
    if(ch >= 'a' && ch <= 'z'){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isalpha (int ch) {
 | 
			
		||||
    if(isupper(ch)){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    if(islower(ch)){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int isdigit (int ch){
 | 
			
		||||
    if(ch >= '0' && ch <= '9'){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isxdigit (int ch){
 | 
			
		||||
    if(isdigit(ch)){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( ch >= 'a' && ch <= 'f'){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( ch >= 'A' && ch <= 'F'){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int iscntrl (int ch){
 | 
			
		||||
    if(ch >= 0x00 && ch <= 0x1f )
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x7f)
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int isgraph (int ch){
 | 
			
		||||
    if(isdigit(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(isupper(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(islower(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ispunct(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isspace(int ch){
 | 
			
		||||
    if (ch == 0x20)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x0c)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x0a)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x0d)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x09)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ch == 0x0b)
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isblank (int ch){
 | 
			
		||||
    if( ch == 0x20 || ch == 0x09)
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ispunct(int ch){
 | 
			
		||||
    if(ch >= '!' && ch <= '~')
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isprint (int ch){
 | 
			
		||||
    if (isdigit(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(isupper(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(islower(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(ispunct(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    if(isspace(ch))
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int tolower(int ch){
 | 
			
		||||
 | 
			
		||||
    if(islower(ch)) return ch;
 | 
			
		||||
    int diff = 'a' - 'A';
 | 
			
		||||
    return ch + diff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int toupper(int ch){
 | 
			
		||||
    if(isupper(ch)) return ch;
 | 
			
		||||
    int diff = 'a' - 'A';
 | 
			
		||||
    return ch - diff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int isalnum (int ch){
 | 
			
		||||
    if(isdigit(ch)){
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   if(isalpha(ch)){
 | 
			
		||||
       return 1;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								CoreLib/ctype.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								CoreLib/ctype.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 25/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
//NOTE: Uses default locale
 | 
			
		||||
int isupper (int ch);
 | 
			
		||||
int islower (int ch);
 | 
			
		||||
int isalpha (int ch);
 | 
			
		||||
int isdigit (int ch);
 | 
			
		||||
int isxdigit (int ch);
 | 
			
		||||
int iscntrl (int ch);
 | 
			
		||||
int isgraph(int ch);
 | 
			
		||||
int isspace(int ch);
 | 
			
		||||
int isblank(int ch);
 | 
			
		||||
int ispunct(int ch);
 | 
			
		||||
int isprint(int ch);
 | 
			
		||||
int isalnum (int ch);
 | 
			
		||||
int tolower(int ch);
 | 
			
		||||
int toupper(int ch);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										137
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								Makefile
									
									
									
									
									
								
							@ -1,137 +0,0 @@
 | 
			
		||||
 | 
			
		||||
EMULATOR = qemu-system-i386
 | 
			
		||||
AS = ${HOME}/opt/cross/bin/i686-elf-as
 | 
			
		||||
CC = ${HOME}/opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++ 
 | 
			
		||||
CFLAGS =  -ffreestanding -Og -ggdb  -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o  $(BUILD_DIR)/paging.o	$(BUILD_DIR)/pit.o 	$(BUILD_DIR)/time.o	$(BUILD_DIR)/keyboard.o	 $(BUILD_DIR)/io.o 	$(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o  $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pcidevice.o $(BUILD_DIR)/atapiDevice.o $(BUILD_DIR)/ataDevice.o $(BUILD_DIR)/rsdp.o 
 | 
			
		||||
 | 
			
		||||
SRC_DIR = source
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
 | 
			
		||||
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
 | 
			
		||||
CRTEND_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
 | 
			
		||||
 | 
			
		||||
CRTI_OBJ = $(BUILD_DIR)/crti.o
 | 
			
		||||
CRTN_OBJ = $(BUILD_DIR)/crtn.o
 | 
			
		||||
OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ)  
 | 
			
		||||
INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
all: clean build 
 | 
			
		||||
 | 
			
		||||
build: build_kernel iso
 | 
			
		||||
 | 
			
		||||
clean_iso: 
 | 
			
		||||
	if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi
 | 
			
		||||
	if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi
 | 
			
		||||
	
 | 
			
		||||
iso: clean_iso clean build
 | 
			
		||||
	mkdir -p root/boot/grub
 | 
			
		||||
	cp build/myos.bin root/boot/myos.bin
 | 
			
		||||
	cp source/grub.cfg root/boot/grub/grub.cfg
 | 
			
		||||
	grub-mkrescue -o build/barinkOS.iso root
 | 
			
		||||
run: all
 | 
			
		||||
	virtualboxvm --startvm "BarinkOS_test"
 | 
			
		||||
debug: all
 | 
			
		||||
	objcopy --only-keep-debug build/myos.bin kernel.sym
 | 
			
		||||
	$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int
 | 
			
		||||
test:
 | 
			
		||||
	$(EMULATOR)  -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo 
 | 
			
		||||
 | 
			
		||||
test_iso: 
 | 
			
		||||
	$(EMULATOR)  -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo 
 | 
			
		||||
test_disk:
 | 
			
		||||
	$(EMULATOR) -boot d -drive format=raw,file=build/disk.img -serial stdio -vga std -display gtk -m 2G -cpu core2duo 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
build_kernel: $(OBJ_LINK_LIST)
 | 
			
		||||
	$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
 | 
			
		||||
	 -ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc
 | 
			
		||||
 | 
			
		||||
build_x86_64: 
 | 
			
		||||
	$(AS) $(SRC_DIR)/cgc/x86_64/crti.s -o $(BUILD_DIR)/crti_64.o
 | 
			
		||||
	$(AS) $(SRC_DIR)/cgc/x86_64/crtn.s -o $(BUILD_DIR)/crtn.o
 | 
			
		||||
 | 
			
		||||
clean: 
 | 
			
		||||
	rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
 | 
			
		||||
 | 
			
		||||
# C++ definition -> Object files
 | 
			
		||||
$(BUILD_DIR)/kernel.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/kterm.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/terminal/kterm.cpp  -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/io.o:
 | 
			
		||||
		$(CPP) -c $(SRC_DIR)/kernel/drivers/io/io.cpp  -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/interrupts/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/gdtc.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/string.o:
 | 
			
		||||
	$(CC) -c $(SRC_DIR)/lib/include/string.c  -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/PhysicalMemoryManager.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp  -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pci.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pci/pci.cpp  -o $(BUILD_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pcidevice.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pci/pciDevice.cpp  -o $(BUILD_DIR)/pcidevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/atapiDevice.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/atapi/atapiDevice.cpp  -o $(BUILD_DIR)/atapiDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/ataDevice.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/ata/ataDevice.cpp  -o $(BUILD_DIR)/ataDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/rsdp.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/acpi/rsdp.cpp  -o $(BUILD_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pit.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp  -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/keyboard.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/drivers/ps-2/keyboard.cpp  -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/time.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/time.cpp  -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/sv-terminal.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/supervisorterminal/superVisorTerminal.cpp  -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/memory.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp  -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/paging.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/KHeap.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/KernelHeap.cpp -o $(BUILD_DIR)/KHeap.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/prekernel.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/prekernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/cpu.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Assembly -> Object files
 | 
			
		||||
$(BUILD_DIR)/boot.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/crti.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/crtn.o:
 | 
			
		||||
	$(AS) $(SRC_DIR)/kernel/crtn.s -o $(BUILD_DIR)/crtn.o
 | 
			
		||||
@ -27,7 +27,7 @@ Enumerating the PCI bus
 | 
			
		||||
Correctly identified our ATAPI device 🎉
 | 
			
		||||
 | 
			
		||||
 \
 | 
			
		||||
Reading a file from a FAT-16 Formatted drive 
 | 
			
		||||
Reading a FILE from a FAT-16 Formatted drive 
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								features.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								features.md
									
									
									
									
									
								
							@ -1,14 +1,17 @@
 | 
			
		||||
# TODO list 
 | 
			
		||||
## Basics
 | 
			
		||||
<input type="checkbox" checked/> Setup Cross-Compiler \
 | 
			
		||||
<input type="checkbox" checked/> Multiboot to kernel \
 | 
			
		||||
<input type="checkbox" checked/> Printing string to the screen \
 | 
			
		||||
 | 
			
		||||
<label>
 | 
			
		||||
<input type="checkbox"  checked/>
 | 
			
		||||
</label> Setup Cross-Compiler
 | 
			
		||||
<input type="checkbox" checked> Multiboot to kernel  \
 | 
			
		||||
<input type="checkbox" checked/> Printing string to the screen  \
 | 
			
		||||
<input type="checkbox" checked/> Printing values/numbers to the screen \
 | 
			
		||||
<input type="checkbox" checked/> Basic Terminal \
 | 
			
		||||
<input type="checkbox" checked/> Extend Multiboot implementation \
 | 
			
		||||
<input type="checkbox" checked/> Output to serial port \
 | 
			
		||||
<input type="checkbox" checked/> Move to protected mode \
 | 
			
		||||
<input type="checkbox" checked/> Enabel CMOS clock \
 | 
			
		||||
<input type="checkbox" checked/> Enable CMOS clock \
 | 
			
		||||
<input type="checkbox" checked/> Time measurement (PIC &| PIT) \
 | 
			
		||||
<input type="checkbox" /> Detect CPU speed \
 | 
			
		||||
<input type="checkbox" checked/> Interrupt / exception system (API) \
 | 
			
		||||
@ -22,17 +25,13 @@
 | 
			
		||||
<input type="checkbox" checked/> Virtual memory management \
 | 
			
		||||
<input type="checkbox" checked/> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
 | 
			
		||||
<input type="checkbox" /> Enable SIMD Extensions (SSE)
 | 
			
		||||
 | 
			
		||||
## Other features I am thinking of:
 | 
			
		||||
<input type="checkbox" checked/> PCI support \
 | 
			
		||||
<input type="checkbox" /> ATA PIO Mode support \
 | 
			
		||||
<input type="checkbox" checked/> ATA PIO Mode support \
 | 
			
		||||
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
 | 
			
		||||
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
 | 
			
		||||
<input type="checkbox" /> ATAPI support \
 | 
			
		||||
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
 | 
			
		||||
<input type="checkbox" checked/> Memory Management (MMU)   
 | 
			
		||||
<input type="checkbox" /> Hardware Management system
 | 
			
		||||
 | 
			
		||||
<input type="checkbox" /> Preemptive multi tasking \
 | 
			
		||||
<input type="checkbox" /> Processes  \
 | 
			
		||||
<input type="checkbox" /> Threads  
 | 
			
		||||
@ -45,7 +44,7 @@
 | 
			
		||||
<input type="checkbox" /> ACPI support  \
 | 
			
		||||
<input type="checkbox" /> ATAPI support \
 | 
			
		||||
 | 
			
		||||
## Optional 
 | 
			
		||||
<input type="checkbox" /> Basic Window server/client \
 | 
			
		||||
<input type="checkbox" /> EXT2 Filesystem 
 | 
			
		||||
<input type="checkbox" /> USTAR Filesystem \
 | 
			
		||||
<input type="checkbox" /> FAT16 Filesystem \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										140
									
								
								kernel/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								kernel/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,140 @@
 | 
			
		||||
AS = /opt/cross/bin/i686-elf-as
 | 
			
		||||
CC = /opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = /opt/cross/bin/i686-elf-g++
 | 
			
		||||
CFLAGS =  -ffreestanding -Og -ggdb  -Wall -Wextra  -I ../build/CoreLib/include
 | 
			
		||||
BUILD_DIR = ../build/kernel
 | 
			
		||||
OBJ_DIR = ../bin/kernel
 | 
			
		||||
 | 
			
		||||
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
 | 
			
		||||
CRTEND_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
 | 
			
		||||
 | 
			
		||||
CRTI_OBJ = $(OBJ_DIR)/crti.o
 | 
			
		||||
CRTN_OBJ = $(OBJ_DIR)/crtn.o
 | 
			
		||||
 | 
			
		||||
OFILES = $(OBJ_DIR)/boot.o	\
 | 
			
		||||
 		 $(OBJ_DIR)/kterm.o \
 | 
			
		||||
 		 $(OBJ_DIR)/kernel.o \
 | 
			
		||||
 		 $(OBJ_DIR)/memory.o \
 | 
			
		||||
 		 $(OBJ_DIR)/paging.o \
 | 
			
		||||
 		 $(OBJ_DIR)/VFS.o \
 | 
			
		||||
 		 $(OBJ_DIR)/pit.o \
 | 
			
		||||
 		 $(OBJ_DIR)/time.o \
 | 
			
		||||
 		 $(OBJ_DIR)/keyboard.o \
 | 
			
		||||
 		 $(OBJ_DIR)/io.o \
 | 
			
		||||
 		 $(OBJ_DIR)/processor.o \
 | 
			
		||||
		 $(OBJ_DIR)/gdtc.o \
 | 
			
		||||
		 $(OBJ_DIR)/idt.o \
 | 
			
		||||
		 $(OBJ_DIR)/pic.o \
 | 
			
		||||
		 $(OBJ_DIR)/sv-terminal.o \
 | 
			
		||||
		 $(OBJ_DIR)/prekernel.o \
 | 
			
		||||
		 $(OBJ_DIR)/KHeap.o \
 | 
			
		||||
		 $(OBJ_DIR)/pci.o \
 | 
			
		||||
		 $(OBJ_DIR)/pcidevice.o \
 | 
			
		||||
		 $(OBJ_DIR)/atapiDevice.o \
 | 
			
		||||
		 $(OBJ_DIR)/ataDevice.o \
 | 
			
		||||
		 $(OBJ_DIR)/rsdp.o \
 | 
			
		||||
		 $(OBJ_DIR)/acpi.o \
 | 
			
		||||
		 $(OBJ_DIR)/fat.o \
 | 
			
		||||
		 $(OBJ_DIR)/serial.o \
 | 
			
		||||
		 $(OBJ_DIR)/klog.o
 | 
			
		||||
 | 
			
		||||
OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ)  
 | 
			
		||||
INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ)
 | 
			
		||||
 | 
			
		||||
all: clean build
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm $(OBJ_DIR)/* -r
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
build: $(OBJ_LINK_LIST)
 | 
			
		||||
	$(CPP) -T linker.ld -o $(BUILD_DIR)/myos.bin -ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc -L ../build/CoreLib -lCoreLib
 | 
			
		||||
 | 
			
		||||
# C++ definition -> Object files
 | 
			
		||||
$(OBJ_DIR)/kernel.o: kernel.cpp
 | 
			
		||||
	$(CPP) -c kernel.cpp -o $(OBJ_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/kterm.o:
 | 
			
		||||
	$(CPP) -c terminal/kterm.cpp  -o $(OBJ_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/io.o:
 | 
			
		||||
	$(CPP) -c io/io.cpp  -o $(OBJ_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c interrupts/idt.cpp -o $(OBJ_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/gdtc.o:
 | 
			
		||||
	$(CPP) -c memory/gdt/gdtc.cpp -o $(OBJ_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c drivers/pic/pic.cpp -o $(OBJ_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/PhysicalMemoryManager.o:
 | 
			
		||||
	$(CPP) -c memory/PhysicalMemoryManager.cpp  -o $(OBJ_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/pci.o:
 | 
			
		||||
	$(CPP) -c pci/pci.cpp  -o $(OBJ_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/pcidevice.o:
 | 
			
		||||
	$(CPP) -c pci/pciDevice.cpp  -o $(OBJ_DIR)/pcidevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/atapiDevice.o:
 | 
			
		||||
	$(CPP) -c storage/atapi/atapiDevice.cpp  -o $(OBJ_DIR)/atapiDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/ataDevice.o:
 | 
			
		||||
	$(CPP) -c "storage/ata pio/ATAPIO.cpp"  -o $(OBJ_DIR)/ataDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/rsdp.o:
 | 
			
		||||
	$(CPP) -c acpi/rsdp.cpp  -o $(OBJ_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/acpi.o:
 | 
			
		||||
	$(CPP) -c acpi/acpi.cpp -o $(OBJ_DIR)/acpi.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/pit.o:
 | 
			
		||||
	$(CPP) -c drivers/pit/pit.cpp  -o $(OBJ_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/VFS.o:
 | 
			
		||||
	$(CPP) -c storage/vfs/vfs.cpp  -o $(OBJ_DIR)/VFS.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/keyboard.o:
 | 
			
		||||
	$(CPP) -c drivers/ps-2/keyboard.cpp  -o $(OBJ_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/time.o:
 | 
			
		||||
	$(CPP) -c time.cpp  -o $(OBJ_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/sv-terminal.o:
 | 
			
		||||
	$(CPP) -c supervisorterminal/superVisorTerminal.cpp  -o $(OBJ_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/memory.o:
 | 
			
		||||
	$(CPP) -c memory/PhysicalMemoryManager.cpp  -o $(OBJ_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/paging.o:
 | 
			
		||||
	$(CPP) -c memory/VirtualMemoryManager.cpp -o $(OBJ_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/KHeap.o:
 | 
			
		||||
	$(CPP) -c memory/KernelHeap.cpp -o $(OBJ_DIR)/KHeap.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/prekernel.o:
 | 
			
		||||
	$(CPP) -c prekernel/prekernel.cpp -o $(OBJ_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/processor.o:
 | 
			
		||||
	$(CPP) -c i386/processor.cpp -o $(OBJ_DIR)/processor.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/fat.o:
 | 
			
		||||
	$(CPP) -c storage/filesystems/FAT/FAT.cpp -o $(OBJ_DIR)/fat.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/serial.o:
 | 
			
		||||
	$(CPP) -c drivers/serial/serial.cpp -o $(OBJ_DIR)/serial.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/klog.o:
 | 
			
		||||
	$(CPP) -c klog.cpp -o $(OBJ_DIR)/klog.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
# Assembly -> Object files
 | 
			
		||||
$(OBJ_DIR)/boot.o:
 | 
			
		||||
	$(AS) boot/boot.s -o $(OBJ_DIR)/boot.o
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/crti.o:
 | 
			
		||||
	$(AS) crti.s -o $(OBJ_DIR)/crti.o
 | 
			
		||||
 | 
			
		||||
$(OBJ_DIR)/crtn.o:
 | 
			
		||||
	$(AS) crtn.s -o $(OBJ_DIR)/crtn.o
 | 
			
		||||
							
								
								
									
										76
									
								
								kernel/acpi/acpi.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								kernel/acpi/acpi.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
			
		||||
#include "acpi.h"
 | 
			
		||||
#include "../../CoreLib/Memory.h"
 | 
			
		||||
#include "../memory/VirtualMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
RSDPDescriptor* ACPI::rsd_ptr;
 | 
			
		||||
RSCPDescriptor20* ACPI::rsd2_ptr;
 | 
			
		||||
RSDT* ACPI::rsd_table;
 | 
			
		||||
 | 
			
		||||
const int KERNEL_OFFSET = 0xC0000000;
 | 
			
		||||
 | 
			
		||||
void ACPI::initialize(){
 | 
			
		||||
    // Find the Root System Description Pointer
 | 
			
		||||
    ACPI::rsd_ptr = FindRSD();
 | 
			
		||||
    printf("RSD address: 0x%x\n", ACPI::rsd_ptr);
 | 
			
		||||
    printRSD(rsd_ptr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if( rsd_ptr->Revision == 0 ){
 | 
			
		||||
        // Using version 1.0 of the ACPI specification
 | 
			
		||||
        int sum = rsd_ptr->Checksum;
 | 
			
		||||
        for (int i =0; i < sizeof(RSDPDescriptor) ; i++) {
 | 
			
		||||
            sum += ((char*)rsd_ptr)[i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" 0x%x sum\n", sum);
 | 
			
		||||
        if(sum & 0xfff0)
 | 
			
		||||
            printf("valid rsd!\n");
 | 
			
		||||
        else
 | 
			
		||||
            printf("invalid rsd\n");
 | 
			
		||||
 | 
			
		||||
        printf("rsdp: 0x%x\n", rsd_ptr);
 | 
			
		||||
 | 
			
		||||
        printf("0x%x address\n", (rsd_ptr->RsdtAddress));
 | 
			
		||||
        Immediate_Map(rsd_ptr->RsdtAddress + KERNEL_OFFSET, rsd_ptr->RsdtAddress);
 | 
			
		||||
 | 
			
		||||
        RSDT* rootSystemDescriptionTable = (RSDT*)(rsd_ptr->RsdtAddress + KERNEL_OFFSET);
 | 
			
		||||
        //printf("0x%x Root System Descriptor address\n", rootSystemDescriptionTable);
 | 
			
		||||
        // checksum it, but we'll ignore it for now
 | 
			
		||||
        printf("signature ");
 | 
			
		||||
        for (int i = 0; i < 4; i++) {
 | 
			
		||||
            kterm_put( rootSystemDescriptionTable->h.Signature[i]);
 | 
			
		||||
        }
 | 
			
		||||
        kterm_put('\n');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        int entries = (rootSystemDescriptionTable->h.Length - sizeof (rootSystemDescriptionTable->h)) /4;
 | 
			
		||||
        printf("%d num entries\n", entries);
 | 
			
		||||
        for( int i = 0; i < entries; i++){
 | 
			
		||||
            ACPISDTHeader* h = (ACPISDTHeader*) rootSystemDescriptionTable->PointerToSDT + i ;
 | 
			
		||||
            if(strncmp(h->Signature, "FACP", 4)){
 | 
			
		||||
                printf("Found FACP Entry!\n");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    } else{
 | 
			
		||||
        // parse it as of version2.0
 | 
			
		||||
        printf("rsd2_ptr\n");
 | 
			
		||||
        ACPI::rsd2_ptr = (RSCPDescriptor20*)rsd_ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    auto tableHeader = &rootSystemDescriptionTable->h;
 | 
			
		||||
 | 
			
		||||
    // do checksum
 | 
			
		||||
    sum = 0;
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; i < tableHeader->Length; i ++) {
 | 
			
		||||
        sum += ((char*) tableHeader)[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( sum != 0)
 | 
			
		||||
        printf("Table invalid!");*/
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								kernel/acpi/acpi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								kernel/acpi/acpi.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "rsdp.h"
 | 
			
		||||
class ACPI {
 | 
			
		||||
    public:
 | 
			
		||||
        static void initialize();
 | 
			
		||||
        
 | 
			
		||||
        // In the future ACPI might start
 | 
			
		||||
        // doing more systems initialization
 | 
			
		||||
 | 
			
		||||
    static RSDPDescriptor* rsd_ptr;
 | 
			
		||||
    static RSCPDescriptor20* rsd2_ptr;
 | 
			
		||||
    static RSDT* rsd_table;
 | 
			
		||||
    private:
 | 
			
		||||
};
 | 
			
		||||
@ -1,6 +1,9 @@
 | 
			
		||||
#include "rsdp.h"
 | 
			
		||||
#include "../memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "../../CoreLib/Memory.h"
 | 
			
		||||
 | 
			
		||||
void printRSD(RSDPTR* rsd){
 | 
			
		||||
 | 
			
		||||
void printRSD(RSDPDescriptor* rsd){
 | 
			
		||||
    printf("Signature: ");
 | 
			
		||||
    for(int i = 0; i < 8; i++){
 | 
			
		||||
        kterm_put(rsd->signature[i]);
 | 
			
		||||
@ -14,33 +17,28 @@ void printRSD(RSDPTR* rsd){
 | 
			
		||||
    kterm_put('\n');
 | 
			
		||||
 | 
			
		||||
    printf("Revision: %d\n", rsd->Revision);
 | 
			
		||||
    printf("RSDT Address: 0x%x\n", rsd->RsdtAddress );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RSDPTR* FindRSD(){
 | 
			
		||||
RSDPDescriptor* FindRSD(){
 | 
			
		||||
    char* memory_byte = (char*) 0x000f2e14;
 | 
			
		||||
    const void* string = "RSD PTR ";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    for( ; (uint32_t) memory_byte < 0x0100000; memory_byte+=10){
 | 
			
		||||
        if( memcmp(memory_byte , string , 8 ) ==  0 ) {
 | 
			
		||||
        printf("RSD PTR found at 0x%x !\n", memory_byte);
 | 
			
		||||
        return (RSDPDescriptor*) memory_byte;
 | 
			
		||||
        break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printRSD((RSDPTR*) memory_byte);
 | 
			
		||||
    return (RSDPTR*) memory_byte;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RSDT* getRSDT(RSDPTR* rsd){
 | 
			
		||||
 | 
			
		||||
        RSDT* rsdt = (RSDT*) rsd->RsdtAddress;
 | 
			
		||||
 | 
			
		||||
        printf("OEMID: ");
 | 
			
		||||
        for(int i = 0; i < 6; i++){
 | 
			
		||||
            kterm_put(rsdt->header.OEMID[i]);
 | 
			
		||||
    memory_byte = (char*) 0x000E0000;
 | 
			
		||||
    for ( ;(uint32_t) memory_byte < 0x000FFFFF; memory_byte += 1)
 | 
			
		||||
    {
 | 
			
		||||
        if( memcmp(memory_byte , string , 8 ) ==  0 ) {
 | 
			
		||||
            printf("RSD PTR found at 0x%x !\n", memory_byte);
 | 
			
		||||
            return (RSDPDescriptor*) memory_byte;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        kterm_put('\n');
 | 
			
		||||
        return rsdt;
 | 
			
		||||
}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								kernel/acpi/rsdp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								kernel/acpi/rsdp.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct ACPISDTHeader{
 | 
			
		||||
    char Signature[4];
 | 
			
		||||
    uint32_t Length;
 | 
			
		||||
    uint8_t Revision;
 | 
			
		||||
    uint8_t CheckSum;
 | 
			
		||||
    char OEMID[6];
 | 
			
		||||
    char OEMTableID[8];
 | 
			
		||||
    uint32_t OEMRevision;
 | 
			
		||||
    uint32_t CreatorID;
 | 
			
		||||
    uint32_t CreatorRevision;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct RSDT{
 | 
			
		||||
    struct ACPISDTHeader h;
 | 
			
		||||
    uint32_t *PointerToSDT; // Length of array : (header.Length - sizeof(header))/ 4
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct RSDPDescriptor {
 | 
			
		||||
    char signature[8];
 | 
			
		||||
    uint8_t Checksum ;
 | 
			
		||||
    char OEMID [6];
 | 
			
		||||
    uint8_t Revision;
 | 
			
		||||
    uint32_t RsdtAddress;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct RSCPDescriptor20{
 | 
			
		||||
   RSDPDescriptor base;
 | 
			
		||||
   uint32_t Length;
 | 
			
		||||
   uint64_t XsdtAddress;
 | 
			
		||||
   uint8_t ExtendedChecksum;
 | 
			
		||||
   uint8_t reserved[3];
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
RSDPDescriptor* FindRSD();
 | 
			
		||||
 | 
			
		||||
void printRSD(RSDPDescriptor* rsd);
 | 
			
		||||
 | 
			
		||||
RSDT* getRSDT(RSDPDescriptor* rsd);
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
.include "./source/kernel/boot/multiboot.s"
 | 
			
		||||
.include "./boot/multiboot.s"
 | 
			
		||||
/*
 | 
			
		||||
*	Allocate initial stack
 | 
			
		||||
*/
 | 
			
		||||
.section .bootstrap_stack, "aw", @nobits
 | 
			
		||||
stack_bottom:
 | 
			
		||||
.skip 16384 # 16 KiB
 | 
			
		||||
.globl stack_top
 | 
			
		||||
stack_top:
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -75,16 +76,7 @@ _start:
 | 
			
		||||
4:
 | 
			
		||||
	# At this point, paging is fully set up and enabled
 | 
			
		||||
isPaging:
 | 
			
		||||
	/* push the pointer to the Multiboot information structure*/
 | 
			
		||||
	pushl %ebx
 | 
			
		||||
 | 
			
		||||
	/* push the magic value */
 | 
			
		||||
	pushl %eax
 | 
			
		||||
	call prekernelSetup
 | 
			
		||||
 | 
			
		||||
	# Unmap the identity mapping as it is now unnecessary  
 | 
			
		||||
	movl $0, boot_page_directory + 0
 | 
			
		||||
	
 | 
			
		||||
	# Reload cr3 to force tlb flush 
 | 
			
		||||
	movl %cr3, %ecx
 | 
			
		||||
	movl %ecx, %cr3
 | 
			
		||||
@ -97,17 +89,42 @@ isPaging:
 | 
			
		||||
	pushl $0 
 | 
			
		||||
	popf 
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	/* push the pointer to the Multiboot information structure*/
 | 
			
		||||
	pushl %ebx
 | 
			
		||||
 | 
			
		||||
	call early_main
 | 
			
		||||
	/* push the magic value */
 | 
			
		||||
	pushl %eax
 | 
			
		||||
	call prekernelSetup
 | 
			
		||||
 | 
			
		||||
	# Unmap the identity mapping as it is now unnecessary  
 | 
			
		||||
	# movl $0, boot_page_directory + 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	call kernel
 | 
			
		||||
 | 
			
		||||
	cli
 | 
			
		||||
1:	hlt
 | 
			
		||||
	jmp 1b
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.include "./source/kernel/memory/gdt/gdt.s"
 | 
			
		||||
.include "./source/kernel/irs_table.s"
 | 
			
		||||
.include "./source/kernel/irq_table.s"
 | 
			
		||||
.include "./source/kernel/interrupts/idt/idt.s"
 | 
			
		||||
.include "./memory/gdt/gdt.s"
 | 
			
		||||
.include "./irs_table.s"
 | 
			
		||||
.include "./irq_table.s"
 | 
			
		||||
.include "./interrupts/idt.s"
 | 
			
		||||
 | 
			
		||||
.globl jump_usermode
 | 
			
		||||
jump_usermode:
 | 
			
		||||
    mov $((4*8) | 3) , %ax
 | 
			
		||||
    mov %ax, %ds
 | 
			
		||||
    mov %ax, %es
 | 
			
		||||
    mov %ax, %fs
 | 
			
		||||
    mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
    mov %esp, %eax
 | 
			
		||||
    push $( (3*8) | 3)
 | 
			
		||||
    push %eax
 | 
			
		||||
    pushf
 | 
			
		||||
    push $( ( 3 * 8) | 3)
 | 
			
		||||
    push startSuperVisorTerminal
 | 
			
		||||
    iret
 | 
			
		||||
@ -4,6 +4,6 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __DEBUG__ false
 | 
			
		||||
#define KERNEL_VERSION 0
 | 
			
		||||
#define KERNEL_VERSION 0.03
 | 
			
		||||
 | 
			
		||||
#define ARCHITECTURE "I386"
 | 
			
		||||
							
								
								
									
										11
									
								
								kernel/devices/BlockDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								kernel/devices/BlockDevice.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 21/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
class BlockDevice {
 | 
			
		||||
    virtual char* Read()=0;
 | 
			
		||||
    virtual void Write() =0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								kernel/devices/CharacterDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								kernel/devices/CharacterDevice.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 21/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
class CharacterDevice {
 | 
			
		||||
    virtual char Read()=0;
 | 
			
		||||
    virtual void Write()=0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../io/io.h"
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "../../io/io.h"
 | 
			
		||||
 | 
			
		||||
#define PIC1		0x20		/* IO base address for master PIC */
 | 
			
		||||
#define PIC2		0xA0		/* IO base address for slave PIC */
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../io/io.h"
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "../../io/io.h"
 | 
			
		||||
#define PIT_DATA_0 0x40
 | 
			
		||||
#define PIT_DATA_1 0x41
 | 
			
		||||
#define PIT_DATA_2 0x42
 | 
			
		||||
							
								
								
									
										52
									
								
								kernel/drivers/serial/serial.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								kernel/drivers/serial/serial.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
#include "serial.h"
 | 
			
		||||
#include "../../io/io.h"
 | 
			
		||||
 | 
			
		||||
// Initializes communication according to the spec given
 | 
			
		||||
Serial::Serial(SerialConfig config) {
 | 
			
		||||
    port = config.port;
 | 
			
		||||
    // Disable interrupts
 | 
			
		||||
    outb(config.port + 1, 0x00);
 | 
			
		||||
 | 
			
		||||
    // Enable DLAB
 | 
			
		||||
    outb(config.port + 3, 0x80);
 | 
			
		||||
 | 
			
		||||
    // set the baudrate
 | 
			
		||||
    outb(config.port + 0, 0x03);
 | 
			
		||||
    outb(config.port + 1, 0x00);
 | 
			
		||||
 | 
			
		||||
    // configure for 8bits, no parity, one stop bit
 | 
			
		||||
    outb(config.port + 3, 0x03);
 | 
			
		||||
 | 
			
		||||
    // Enable FIFO, clear them, with 14-byte threshhold
 | 
			
		||||
    outb(config.port + 2, 0xC7);
 | 
			
		||||
    // Enable IRQ's, RTS/DSR set
 | 
			
		||||
    outb(config.port + 4, 0x0B );
 | 
			
		||||
    // Set in loopback mode, test the serial chip.
 | 
			
		||||
    outb(config.port + 4, 0x1E);
 | 
			
		||||
 | 
			
		||||
    // TEST
 | 
			
		||||
    outb(config.port + 0 , 0xAE);
 | 
			
		||||
 | 
			
		||||
    if(inb(config.port + 0) != 0xAE)
 | 
			
		||||
        return ; // FAIL
 | 
			
		||||
 | 
			
		||||
    outb(config.port + 4, 0x0F);
 | 
			
		||||
    return ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Serial::write(void* data, int len) {
 | 
			
		||||
    while (is_transmit_empty() == 0); // Wait for transmit queue to be free
 | 
			
		||||
    for (int i = 0; i < len ; i++){
 | 
			
		||||
        outb(port, ((uint8_t*)data)[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char Serial::read() {
 | 
			
		||||
    return inb(port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Serial::is_transmit_empty() {
 | 
			
		||||
    return inb(port + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								kernel/drivers/serial/serial.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								kernel/drivers/serial/serial.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
// For now these are the standard
 | 
			
		||||
// serial ports we can talk to
 | 
			
		||||
enum SERIALPORT {
 | 
			
		||||
    COM1 = 0x3F8,
 | 
			
		||||
    COM2 = 0x2F8,
 | 
			
		||||
    COM3 = 0x3E8,
 | 
			
		||||
    COM4 = 0x2E8
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SerialConfig {
 | 
			
		||||
    SERIALPORT port;
 | 
			
		||||
    char baud_rate_lo ;
 | 
			
		||||
    char baud_rate_hi;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Serial   {
 | 
			
		||||
 | 
			
		||||
    public: 
 | 
			
		||||
        Serial (SerialConfig config );
 | 
			
		||||
 | 
			
		||||
        char read();
 | 
			
		||||
        void write(void* data, int length);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        SERIALPORT port;
 | 
			
		||||
        int is_transmit_empty();
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										2
									
								
								kernel/i386/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								kernel/i386/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
# architecture specific implementations 
 | 
			
		||||
## This will contain I386 Architecture specific implementations
 | 
			
		||||
							
								
								
									
										127
									
								
								kernel/i386/processor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								kernel/i386/processor.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 17/02/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "processor.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::cap_page;
 | 
			
		||||
uint32_t processor::cap_page1;
 | 
			
		||||
uint32_t processor::cap_page7 ;
 | 
			
		||||
 | 
			
		||||
void processor::initialize()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    asm volatile ("movl $0x80000001, %%eax;"
 | 
			
		||||
                  "CPUID;"
 | 
			
		||||
                  "movl %%edx, %0"
 | 
			
		||||
                  :: "m"(cap_page));
 | 
			
		||||
 | 
			
		||||
    asm volatile ("movl $0x01, %%eax; "
 | 
			
		||||
                  "CPUID;"
 | 
			
		||||
                  "movl %%edx, %0"
 | 
			
		||||
                  :: "m"(cap_page1));
 | 
			
		||||
 | 
			
		||||
    asm volatile ("movl $0x07, %%eax;"
 | 
			
		||||
                  "movl $0x0, %%ecx;"
 | 
			
		||||
                  "CPUID;"
 | 
			
		||||
                  "movl %%edx, %0"
 | 
			
		||||
                  :: "m"(cap_page7));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool processor::hasAMXExtension()
 | 
			
		||||
{
 | 
			
		||||
    return (cap_page7 & AMX_TYPE::AMX_BF16) || (cap_page7 & AMX_TYPE::AMX_TILE) || (cap_page7 & AMX_TYPE::AMX_INT8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PSE: page-size extensions for 32-bit paging.
 | 
			
		||||
 * If CPUID.01H:EDX.PSE [bit 3] = 1, CR4.PSE may be set to 1, enabling support for 4-MByte pages with 32-bit paging
 | 
			
		||||
 */
 | 
			
		||||
bool processor::has32bitPagingSupport() {
 | 
			
		||||
    // is the PSE bit set
 | 
			
		||||
    return cap_page1 & (0x1 << 3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PAE: physical-address extension.
 | 
			
		||||
 * If CPUID.01H:EDX.PAE [bit 6] = 1, CR4.PAE may be set to 1, enabling PAE paging (this setting is also required
 | 
			
		||||
 * for 4-level paging and 5-level paging).
 | 
			
		||||
 */
 | 
			
		||||
bool processor::hasPAEExtension(){
 | 
			
		||||
    return cap_page1 & (0x1 << 6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * PGE: global-page support.
 | 
			
		||||
 * If CPUID.01H:EDX.PGE [bit 13] = 1, CR4.PGE may be set to 1, enabling the global-page feature (see Section
 | 
			
		||||
 * 4.10.2.4).
 | 
			
		||||
 */
 | 
			
		||||
bool processor::hasPageSupport(){
 | 
			
		||||
    return cap_page1 & (0x1 << 13);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Page1GB: 1-GByte pages.
 | 
			
		||||
 * If CPUID.80000001H:EDX.Page1GB [bit 26] = 1, 1-GByte pages may be supported with 4-level paging and 5-
 | 
			
		||||
 * level paging (see Section 4.5).
 | 
			
		||||
 */
 | 
			
		||||
bool processor::gigabytePages() {
 | 
			
		||||
    return cap_page & (0x1 << 26);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void processor::enable_protectedMode()
 | 
			
		||||
{
 | 
			
		||||
    // Set the protected bit of control register 0
 | 
			
		||||
    // this will put the CPU into protected mode
 | 
			
		||||
    // NOTE: This should really be an assembly procedure
 | 
			
		||||
    // We cant directly write to control register 0
 | 
			
		||||
    // therefor we copy the value of control register 0 into eax
 | 
			
		||||
    // once we are done manipulating the value we write the value in
 | 
			
		||||
    // eax back to control register 0
 | 
			
		||||
 | 
			
		||||
    asm volatile("mov %cr0, %eax ");
 | 
			
		||||
    asm volatile("or $1, %eax");
 | 
			
		||||
    asm volatile("mov %eax, %cr0");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::GetEFLAGS()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t EFLAGS = 0;
 | 
			
		||||
    asm volatile ("pushfl;" "movl 4(%%esp), %%edx" : "=d"(EFLAGS));
 | 
			
		||||
    return EFLAGS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::GetCR0()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t cr0_value;
 | 
			
		||||
    asm volatile ("movl %%cr0, %%edx" : "=d"(cr0_value));
 | 
			
		||||
    return cr0_value;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::GetCR2(){
 | 
			
		||||
    uint32_t cr2_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr2, %%edx": "=d"(cr2_value));
 | 
			
		||||
    return cr2_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::GetCR3(){
 | 
			
		||||
    uint32_t cr3_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr3, %%edx": "=d"(cr3_value));
 | 
			
		||||
    return cr3_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t processor::GetCR4(){
 | 
			
		||||
    uint32_t cr4_value;
 | 
			
		||||
    __asm__ volatile("movl %%cr4, %%edx": "=d"(cr4_value));
 | 
			
		||||
    return cr4_value;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								kernel/i386/processor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								kernel/i386/processor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 17/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma  once
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
class processor {
 | 
			
		||||
public:
 | 
			
		||||
    static void initialize();
 | 
			
		||||
 | 
			
		||||
    // Based on information from https://en.wikichip.org/wiki/x86/amx#Detection
 | 
			
		||||
    enum  AMX_TYPE{
 | 
			
		||||
        AMX_BF16 = (0x1 << 22),
 | 
			
		||||
        AMX_TILE = (0x1 << 24),
 | 
			
		||||
        AMX_INT8 = (0x1 << 25)
 | 
			
		||||
    };
 | 
			
		||||
    static bool hasAMXExtension();
 | 
			
		||||
    static bool has32bitPagingSupport();
 | 
			
		||||
    static bool hasPageSupport();
 | 
			
		||||
    static bool gigabytePages();
 | 
			
		||||
 | 
			
		||||
    static bool hasPAEExtension();
 | 
			
		||||
    static void enable_protectedMode();
 | 
			
		||||
 | 
			
		||||
    static uint32_t GetEFLAGS();
 | 
			
		||||
    static uint32_t GetCR0();
 | 
			
		||||
    static uint32_t GetCR2();
 | 
			
		||||
    static uint32_t GetCR3();
 | 
			
		||||
    static uint32_t GetCR4();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static uint32_t cap_page;
 | 
			
		||||
    static uint32_t cap_page1;
 | 
			
		||||
    static uint32_t cap_page7;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
#include "../../drivers/pit/pit.h"
 | 
			
		||||
#include "../../drivers/ps-2/keyboard.h"
 | 
			
		||||
#include "../../cpu.h"
 | 
			
		||||
#include "../../drivers/ps-2/keyboard.h"
 | 
			
		||||
#include "../drivers/pit/pit.h"
 | 
			
		||||
#include "../drivers/ps-2/keyboard.h"
 | 
			
		||||
#include "../i386/processor.h"
 | 
			
		||||
#include "../memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "../syscalls.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IDT_entry idt_table[256];
 | 
			
		||||
IDT_ptr idt_ptr;
 | 
			
		||||
@ -17,25 +19,25 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel,  uint8_t flags){
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void irs_handler (registers regs) {
 | 
			
		||||
void irs_handler (registers* regs) {
 | 
			
		||||
     uint32_t FaultingAddress;
 | 
			
		||||
        //printf("(IRS) Interrupt number: %d \r", regs.int_no);
 | 
			
		||||
        switch (regs.int_no)
 | 
			
		||||
        printf("(IRS) Interrupt number: %d \n EAX: ", regs->int_no, regs->eax);
 | 
			
		||||
        switch (regs->int_no)
 | 
			
		||||
        {
 | 
			
		||||
        case 0:
 | 
			
		||||
            // Divide Error #DE
 | 
			
		||||
            printf("#DE\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 1:
 | 
			
		||||
            // Debug Exception #DB
 | 
			
		||||
            printf("#DB\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 2:
 | 
			
		||||
@ -46,49 +48,50 @@ void irs_handler (registers regs) {
 | 
			
		||||
        case 3:
 | 
			
		||||
            // Breakpoint Exception #BP
 | 
			
		||||
            printf("#BP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 4:
 | 
			
		||||
            // Overflow Exception #OF
 | 
			
		||||
            printf("#OF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 5:
 | 
			
		||||
            // BOUND Range Exceeded Exception #BR
 | 
			
		||||
            printf("#BR\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 6:
 | 
			
		||||
            // Invalid OpCode Exception #UD 
 | 
			
		||||
            printf("#UD\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 7:
 | 
			
		||||
            // Device Not Available Exception  #NM
 | 
			
		||||
            printf("#NM\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 8:
 | 
			
		||||
            // Double Fault Exception #DF
 | 
			
		||||
            printf("#DF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
            while(true);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 9:
 | 
			
		||||
@ -99,64 +102,74 @@ void irs_handler (registers regs) {
 | 
			
		||||
        case 10:
 | 
			
		||||
            // Invalid TSS Exception #TS
 | 
			
		||||
            printf("#TS\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
            __asm__("cli;" "1: hlt;" "jmp 1b;");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 11:
 | 
			
		||||
            // Segment Not Present #NP
 | 
			
		||||
            printf("#NP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 12:
 | 
			
		||||
            // Stack Fault Exception #SS
 | 
			
		||||
            printf("#SS\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 13:
 | 
			
		||||
        case 13:{
 | 
			
		||||
            // General Protection Exception #GP
 | 
			
		||||
            printf("#GP\n");
 | 
			
		||||
 | 
			
		||||
            printf("Accessing memory caused a general protectuion exception.\n");
 | 
			
		||||
            
 | 
			
		||||
            printf("Fault due to entry at index: %d", (regs.err_code >> 3 & 0xFFF ) );
 | 
			
		||||
            printf("Accessing memory caused a general protection exception.\n");
 | 
			
		||||
            printf("Faulting instruction at addres: 0x%x\n", regs->eip );
 | 
			
		||||
            printf("Error code: 0x%x\n", regs->err_code);
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 0   ){
 | 
			
		||||
                printf("* Index references GDT");
 | 
			
		||||
            }
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 1  ){
 | 
			
		||||
                printf("* Index references IDT");
 | 
			
		||||
            }
 | 
			
		||||
            if (regs->err_code != 0){
 | 
			
		||||
                printf("Fault due to entry at index: 0x%x (%d)\n", (regs->err_code >> 3 & 0xFFF ) , regs->err_code);
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 2   ){
 | 
			
		||||
                printf("* Index references LDT");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & 0x3 >> 1 == 4  ){
 | 
			
		||||
                printf("* Index references IDT");
 | 
			
		||||
            }
 | 
			
		||||
                uint8_t table = regs->err_code >> 1 & 0x3 ;
 | 
			
		||||
                
 | 
			
		||||
                if(table == 0   ){
 | 
			
		||||
                    printf("* Index references GDT\n");
 | 
			
		||||
                }
 | 
			
		||||
                if(table == 1  ){
 | 
			
		||||
                    printf("* Index references IDT\n");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            if( regs.err_code & 0x1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("* Originated externally!");
 | 
			
		||||
                if(table  == 2   ){
 | 
			
		||||
                    printf("* Index references LDT\n");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if(table  == 3 ){
 | 
			
		||||
                    printf("* Index references IDT\n");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( regs->err_code & 0x1)
 | 
			
		||||
                {
 | 
			
		||||
                    printf("* Originated externally!\n");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            __asm__("cli;" "1: hlt;" "jmp 1b;");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 14:
 | 
			
		||||
            // Page Fault Exception #PF
 | 
			
		||||
            printf("#PF\n");
 | 
			
		||||
 | 
			
		||||
            FaultingAddress = GetCR2();
 | 
			
		||||
            #define ALIGN(addr, align) (((addr) & ~((align) - 1)) + (align))
 | 
			
		||||
            FaultingAddress = processor::GetCR2();
 | 
			
		||||
            
 | 
			
		||||
            printf("Accessing the linear address 0x%x resulted in a page fault!\n\n", FaultingAddress);
 | 
			
		||||
        
 | 
			
		||||
            // Error code of 32 bits are on the stack
 | 
			
		||||
@ -174,97 +187,114 @@ void irs_handler (registers regs) {
 | 
			
		||||
            printf("REASON: \n\n");
 | 
			
		||||
 | 
			
		||||
         
 | 
			
		||||
            if (regs.err_code & PF_ERR_PRESENT_BIT ){
 | 
			
		||||
            if (regs->err_code & PF_ERR_PRESENT_BIT ){
 | 
			
		||||
                printf("* Page protection violation!\n");
 | 
			
		||||
            } else{
 | 
			
		||||
                printf("* Page not-present!\n");
 | 
			
		||||
                //Immediate_Map(FaultingAddress, FaultingAddress);
 | 
			
		||||
             
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_WRITE_BIT){
 | 
			
		||||
            if(regs->err_code & PF_ERR_WRITE_BIT){
 | 
			
		||||
                printf("* Write access violation!\n");
 | 
			
		||||
            } else{
 | 
			
		||||
                printf("* Read access violation!\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_USER_BIT){
 | 
			
		||||
            if(regs->err_code & PF_ERR_USER_BIT){
 | 
			
		||||
                printf("* Violation from user-space (CPL=3)\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
 | 
			
		||||
            if(regs->err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
 | 
			
		||||
                printf("* Caused by an instruction fetch. \n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
                Check the error code to figure out what happened here
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            __asm__("cli;" "1: hlt;" "jmp 1b;");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
    
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 16:
 | 
			
		||||
            // x87 FPU Floating-point Error #MF
 | 
			
		||||
            printf("#MF\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp);
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp);
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 17:
 | 
			
		||||
            // Alignment Check Exception #AC
 | 
			
		||||
            printf("#AC\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 18:
 | 
			
		||||
            // Machine-Check Exception #MC
 | 
			
		||||
            printf("#MC\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 19:
 | 
			
		||||
            // SIMD Floating-point Exception #XM
 | 
			
		||||
            printf("#XM\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 20:
 | 
			
		||||
             // Virtualization Exception #VE
 | 
			
		||||
            printf("#VE\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
        case 21:
 | 
			
		||||
             // Control Protection Exception #CP
 | 
			
		||||
            printf("#CP\n");
 | 
			
		||||
            printf("EIP: 0x%x\n", regs.eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs.eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs.ebp); 
 | 
			
		||||
            printf("EIP: 0x%x\n", regs->eip);
 | 
			
		||||
            printf("EAX: 0x%x\n", regs->eax);
 | 
			
		||||
            printf("EBP: 0x%x\n", regs->ebp); 
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
        case 50:
 | 
			
		||||
            printf("SYSTEMCALL\n");
 | 
			
		||||
            printf("EAX 0x%x\n", regs->eax);
 | 
			
		||||
 | 
			
		||||
                switch (regs->eax) {
 | 
			
		||||
                    case 0x0:
 | 
			
		||||
                        printf("test!\n");
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x5:
 | 
			
		||||
                        sys_open();
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x10:
 | 
			
		||||
                        sys_read((FILE*)regs->ebx, (char*)regs->ecx);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x20:
 | 
			
		||||
                        sys_write((FILE*)regs->ebx, (const char*)regs->ecx, regs->edx);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x666:
 | 
			
		||||
                        sys_version();
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                };
 | 
			
		||||
        break;
 | 
			
		||||
        default:
 | 
			
		||||
            // PANIC!!!
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
      
 | 
			
		||||
        
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void irq_handler (registers regs) {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    switch (regs.int_no) {
 | 
			
		||||
    case 0:
 | 
			
		||||
            pit_tick++;
 | 
			
		||||
@ -301,8 +331,8 @@ void irq_handler (registers regs) {
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        printf("Interrupt happened!");
 | 
			
		||||
        printf("Received INT: 0x%x\n", regs.int_no);
 | 
			
		||||
        //printf("Interrupt happened!");
 | 
			
		||||
        //printf("Received INT: 0x%x\n", regs.int_no);
 | 
			
		||||
        break;
 | 
			
		||||
    }        
 | 
			
		||||
 | 
			
		||||
@ -320,8 +350,8 @@ void irq_handler (registers regs) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_idt(){
 | 
			
		||||
    // Initialise the IDT pointer
 | 
			
		||||
void initidt(){
 | 
			
		||||
    // Initialize the IDT pointer
 | 
			
		||||
    idt_ptr.length = sizeof(IDT_entry) * 255;
 | 
			
		||||
    idt_ptr.base = (uint32_t)&idt_table;
 | 
			
		||||
 | 
			
		||||
@ -364,7 +394,7 @@ void init_idt(){
 | 
			
		||||
    set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
 | 
			
		||||
    set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    set_id_entry(0x50, (uint32_t) irs50, 0x08, 0x8E);
 | 
			
		||||
    //print_serial("Remapping PIC\n");
 | 
			
		||||
    PIC_remap(0x20, 0x28);
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,10 @@
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "../../drivers/vga/colors.h"
 | 
			
		||||
#include "../../drivers/pic/pic.h"
 | 
			
		||||
#include "../drivers/vga/colors.h"
 | 
			
		||||
#include "../drivers/pic/pic.h"
 | 
			
		||||
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
@ -32,11 +32,11 @@ extern "C" {
 | 
			
		||||
 | 
			
		||||
    extern void idt_flush(uint32_t); 
 | 
			
		||||
    void set_id_entry (uint8_t num , uint32_t base, uint16_t sel,  uint8_t flags);
 | 
			
		||||
    void init_idt();
 | 
			
		||||
    void initidt();
 | 
			
		||||
 | 
			
		||||
    void irq_handler (registers regs);
 | 
			
		||||
 | 
			
		||||
    void irs_handler (registers regs);
 | 
			
		||||
    void irs_handler (registers* regs);
 | 
			
		||||
 | 
			
		||||
    extern void irs0 ();
 | 
			
		||||
    extern void irs1 ();
 | 
			
		||||
@ -70,6 +70,7 @@ extern "C" {
 | 
			
		||||
    extern void irs29 ();
 | 
			
		||||
    extern void irs30 ();
 | 
			
		||||
    extern void irs31 ();
 | 
			
		||||
    extern void irs50();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								kernel/irq_table.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								kernel/irq_table.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
.globl irq0
 | 
			
		||||
 | 
			
		||||
.macro IRQ NAME, VECTOR
 | 
			
		||||
    .globl irq\NAME
 | 
			
		||||
    irq\NAME:
 | 
			
		||||
        cli
 | 
			
		||||
        push $0
 | 
			
		||||
        push \VECTOR
 | 
			
		||||
        jmp irq_common
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
IRQ 0 $0
 | 
			
		||||
IRQ 1 $1
 | 
			
		||||
IRQ 2 $2
 | 
			
		||||
IRQ 3 $3
 | 
			
		||||
IRQ 4 $4
 | 
			
		||||
IRQ 5 $5
 | 
			
		||||
IRQ 6 $6
 | 
			
		||||
IRQ 7 $7
 | 
			
		||||
IRQ 8 $8
 | 
			
		||||
IRQ 9 $9
 | 
			
		||||
IRQ 10 $10
 | 
			
		||||
IRQ 11 $11
 | 
			
		||||
IRQ 12 $12
 | 
			
		||||
IRQ 13 $13
 | 
			
		||||
IRQ 14 $14
 | 
			
		||||
IRQ 15 $15
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
irq_common:
 | 
			
		||||
	pusha
 | 
			
		||||
 | 
			
		||||
	mov %ds, %ax
 | 
			
		||||
	push %eax
 | 
			
		||||
 | 
			
		||||
	mov $0x10, %ax
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	call irq_handler
 | 
			
		||||
 | 
			
		||||
	pop %eax
 | 
			
		||||
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
 | 
			
		||||
	popa
 | 
			
		||||
	add  $8, %esp  # cleans push error and irs code
 | 
			
		||||
	sti
 | 
			
		||||
	iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
 | 
			
		||||
							
								
								
									
										87
									
								
								kernel/irs_table.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								kernel/irs_table.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,87 @@
 | 
			
		||||
.code32
 | 
			
		||||
/*
 | 
			
		||||
* Interupt handlers
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
.macro ISR_NOERRORCODE NAME, VECTOR
 | 
			
		||||
	.globl irs\NAME
 | 
			
		||||
	irs\NAME:
 | 
			
		||||
		cli 
 | 
			
		||||
		push $0
 | 
			
		||||
		push \VECTOR
 | 
			
		||||
		jmp irs_common
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
.macro ISR_ERROCODE NAME, VECTOR
 | 
			
		||||
	.globl irs\NAME
 | 
			
		||||
	irs\NAME:
 | 
			
		||||
		cli
 | 
			
		||||
		push \VECTOR
 | 
			
		||||
		jmp irs_common
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ISR_NOERRORCODE 0 $0
 | 
			
		||||
ISR_NOERRORCODE 1 $1
 | 
			
		||||
ISR_NOERRORCODE 2 $2
 | 
			
		||||
ISR_NOERRORCODE 3 $3
 | 
			
		||||
ISR_NOERRORCODE 4 $4
 | 
			
		||||
ISR_NOERRORCODE 5 $5
 | 
			
		||||
ISR_NOERRORCODE 6 $6
 | 
			
		||||
ISR_NOERRORCODE 7 $7
 | 
			
		||||
ISR_NOERRORCODE 8 $8
 | 
			
		||||
ISR_NOERRORCODE 9 $9
 | 
			
		||||
ISR_NOERRORCODE 10 $10
 | 
			
		||||
ISR_NOERRORCODE 11 $11
 | 
			
		||||
ISR_NOERRORCODE 12 $12
 | 
			
		||||
ISR_NOERRORCODE 13 $13
 | 
			
		||||
ISR_NOERRORCODE 14 $14
 | 
			
		||||
ISR_NOERRORCODE 15 $15
 | 
			
		||||
ISR_NOERRORCODE 16 $16
 | 
			
		||||
ISR_NOERRORCODE 17 $17
 | 
			
		||||
ISR_NOERRORCODE 18 $18
 | 
			
		||||
ISR_NOERRORCODE 19 $19
 | 
			
		||||
ISR_NOERRORCODE 20 $20
 | 
			
		||||
ISR_NOERRORCODE 21 $21
 | 
			
		||||
ISR_NOERRORCODE 22 $22
 | 
			
		||||
ISR_NOERRORCODE 23 $23
 | 
			
		||||
ISR_NOERRORCODE 24 $24
 | 
			
		||||
ISR_NOERRORCODE 25 $25
 | 
			
		||||
ISR_NOERRORCODE 26 $26
 | 
			
		||||
ISR_NOERRORCODE 27 $27
 | 
			
		||||
ISR_NOERRORCODE 28 $28
 | 
			
		||||
ISR_NOERRORCODE 29 $29
 | 
			
		||||
ISR_NOERRORCODE 30 $30
 | 
			
		||||
ISR_NOERRORCODE 31 $31
 | 
			
		||||
ISR_NOERRORCODE 50 $50
 | 
			
		||||
 | 
			
		||||
irs_common:
 | 
			
		||||
	pusha 				# Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
 | 
			
		||||
 | 
			
		||||
	mov %ds, %ax
 | 
			
		||||
	push %eax
 | 
			
		||||
 | 
			
		||||
	/* load the kernel data segment descriptor*/
 | 
			
		||||
 | 
			
		||||
	mov $0x10, %ax
 | 
			
		||||
	mov %ax, %ds
 | 
			
		||||
	mov %ax, %es
 | 
			
		||||
	mov %ax, %fs
 | 
			
		||||
	mov %ax, %gs
 | 
			
		||||
	
 | 
			
		||||
	mov %esp, %eax
 | 
			
		||||
	push %eax 
 | 
			
		||||
 | 
			
		||||
	call irs_handler
 | 
			
		||||
	
 | 
			
		||||
	pop %eax        // pop stack pointer
 | 
			
		||||
	pop %ebx		// reload ther orignal data segment descriptor
 | 
			
		||||
	mov %bx, %ds
 | 
			
		||||
	mov %bx, %es
 | 
			
		||||
	mov %bx, %fs
 | 
			
		||||
	mov %bx, %gs
 | 
			
		||||
 | 
			
		||||
	popa
 | 
			
		||||
	add  $8, %esp  # cleans push error and irs code
 | 
			
		||||
 | 
			
		||||
	iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
 | 
			
		||||
							
								
								
									
										88
									
								
								kernel/kernel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								kernel/kernel.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
    Copyright © Nigel Barink 2023
 | 
			
		||||
*/
 | 
			
		||||
#include "memory/memory.h"
 | 
			
		||||
#include "memory/KernelHeap.h"
 | 
			
		||||
#include "memory/gdt/gdtc.h"
 | 
			
		||||
#include "memory/TaskStateSegment.h"
 | 
			
		||||
#include "supervisorterminal/superVisorTerminal.h"
 | 
			
		||||
#include "drivers/vga/VBE.h"
 | 
			
		||||
#include "pci/pci.h"
 | 
			
		||||
#include "drivers/pit/pit.h"
 | 
			
		||||
#include "i386/processor.h"
 | 
			
		||||
#include "terminal/kterm.h"
 | 
			
		||||
#include "interrupts/idt.h"
 | 
			
		||||
#include "storage/vfs/vfs.h"
 | 
			
		||||
#include "storage/filesystems/FAT/FAT.h"
 | 
			
		||||
#include "acpi/acpi.h"
 | 
			
		||||
#include "memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "klog.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern BootInfoBlock* BIB;
 | 
			
		||||
extern "C"  void LoadGlobalDescriptorTable();
 | 
			
		||||
extern "C" void jump_usermode();
 | 
			
		||||
 | 
			
		||||
void initBootDrive(){
 | 
			
		||||
    printf("Boot device: 0x%x\n", BIB->bootDeviceID);
 | 
			
		||||
    unsigned int part3 = BIB->bootDeviceID & 0xFF;
 | 
			
		||||
    unsigned int part2 = (BIB->bootDeviceID & 0xFF00) >> 8;
 | 
			
		||||
    unsigned int part1 = (BIB->bootDeviceID & 0xFF0000) >> 16;
 | 
			
		||||
    unsigned int drive = (BIB->bootDeviceID & 0xFF000000) >> 24;
 | 
			
		||||
    if (drive == 0x80 )
 | 
			
		||||
        printf("booted from disk!\n");
 | 
			
		||||
    if(drive == 0x00)
 | 
			
		||||
        printf("booted from floppy disk\n");
 | 
			
		||||
 | 
			
		||||
    printf("Part1: %d, Part2: %d, Part3: %d\n", part1, part2 , part3);
 | 
			
		||||
    ATAPIO::Identify(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void kernel ()
 | 
			
		||||
{
 | 
			
		||||
    kterm_init();
 | 
			
		||||
    setup_tss();
 | 
			
		||||
    initGDT();
 | 
			
		||||
    initidt();
 | 
			
		||||
    LoadGlobalDescriptorTable();
 | 
			
		||||
    flush_tss();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    print_info("Memory setup complete!\n");
 | 
			
		||||
    // Enable interrupts
 | 
			
		||||
    asm volatile("STI");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    initHeap();
 | 
			
		||||
    //pit_initialise();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //ACPI::initialize();
 | 
			
		||||
    //PCI::Scan();
 | 
			
		||||
    processor::initialize();
 | 
			
		||||
    processor::enable_protectedMode();
 | 
			
		||||
    initBootDrive();
 | 
			
		||||
    VirtualFileSystem::initialize();
 | 
			
		||||
 | 
			
		||||
    print_dbg("Hello debug!\n");
 | 
			
		||||
    print_info("Hello info!\n");
 | 
			
		||||
    print_err("Hello error!\n");
 | 
			
		||||
 | 
			
		||||
#define VFS_EXAMPLE
 | 
			
		||||
#ifdef VFS_EXAMPLE
 | 
			
		||||
    auto fontFile = VirtualFileSystem::open("/FONT    PSF", 0);
 | 
			
		||||
    printf("Size of font file: %d bytes\n", fontFile->root->size); // COOL This Works like a charm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USERMODE_RELEASE
 | 
			
		||||
    // Lets jump into user mode
 | 
			
		||||
    jump_usermode();
 | 
			
		||||
#else
 | 
			
		||||
    startSuperVisorTerminal();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								kernel/kernel.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
#define PANIC(message) {return;} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								kernel/klog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								kernel/klog.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 10/28/23.
 | 
			
		||||
//
 | 
			
		||||
#include "klog.h"
 | 
			
		||||
#include "terminal/kterm.h"
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
 | 
			
		||||
const char* ForeGroundColourReset = "\e[39m";
 | 
			
		||||
void print_dbg(const char* message, ...){
 | 
			
		||||
    auto **arg = (unsigned char**)&message;
 | 
			
		||||
    // Send it to the VGA
 | 
			
		||||
    printf(message, arg);
 | 
			
		||||
 | 
			
		||||
    // Now send the message to the serial
 | 
			
		||||
    Serial com1= Serial({
 | 
			
		||||
                        COM1,
 | 
			
		||||
                        0x03,
 | 
			
		||||
                        0x00
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
    const char* ForeGroundColour = "\e[32m";
 | 
			
		||||
    com1.write((void*)ForeGroundColour, strlen(ForeGroundColour));
 | 
			
		||||
    com1.write((void*)message, strlen(message));
 | 
			
		||||
    com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void print_info(const char* message, ...){
 | 
			
		||||
    auto **arg = (unsigned char**)&message;
 | 
			
		||||
    // Send it to the VGA
 | 
			
		||||
    printf(message, arg);
 | 
			
		||||
 | 
			
		||||
    Serial com1 = Serial({
 | 
			
		||||
        COM1,
 | 
			
		||||
        0x03,
 | 
			
		||||
        0x00
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const char* ForeGroundColour = "\e[34m";
 | 
			
		||||
    com1.write((void*)ForeGroundColour, strlen(ForeGroundColour));
 | 
			
		||||
    com1.write((void*)message, strlen(message));
 | 
			
		||||
    com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset));
 | 
			
		||||
}
 | 
			
		||||
void print_err(const char* message, ...){
 | 
			
		||||
    auto **arg = (unsigned char**)&message;
 | 
			
		||||
    // Send it to the VGA
 | 
			
		||||
    printf(message, arg);
 | 
			
		||||
    Serial com1 = Serial({
 | 
			
		||||
                                 COM1,
 | 
			
		||||
                                 0x03,
 | 
			
		||||
                                 0x00
 | 
			
		||||
                         });
 | 
			
		||||
    const char* ForeGroundColour = "\e[31m";
 | 
			
		||||
    com1.write((void*)ForeGroundColour, strlen(ForeGroundColour));
 | 
			
		||||
    com1.write((void*)message, strlen(message));
 | 
			
		||||
    com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								kernel/klog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								kernel/klog.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 10/28/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "drivers/serial/serial.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void print_dbg(const char* message, ...);
 | 
			
		||||
void print_info(const char* message, ...);
 | 
			
		||||
void print_err(const char* message, ...);
 | 
			
		||||
@ -25,6 +25,7 @@ SECTIONS
 | 
			
		||||
	.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
		*(.rodata)
 | 
			
		||||
		*(.symtab)
 | 
			
		||||
	}
 | 
			
		||||
	.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
 | 
			
		||||
	{
 | 
			
		||||
@ -36,6 +37,8 @@ SECTIONS
 | 
			
		||||
		*(.bss)
 | 
			
		||||
		*(.bootstrap_stack)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	_kernel_end = .;
 | 
			
		||||
	kernel_end = .; /* For legacy reasons */
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#include "KernelHeap.h"
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
extern "C" const uint32_t kernel_end;
 | 
			
		||||
// Size of heap meta data is 5 bytes 
 | 
			
		||||
// Size of heap metadata is 5 bytes
 | 
			
		||||
struct heap_block{
 | 
			
		||||
    uint8_t Used;
 | 
			
		||||
    uint32_t Size;
 | 
			
		||||
@ -12,7 +12,7 @@ heap_block* start ;
 | 
			
		||||
 | 
			
		||||
void* malloc(size_t size)
 | 
			
		||||
{
 | 
			
		||||
    printf("Received request for %d bytes of memory\n", size);
 | 
			
		||||
    //printf("Received request for %d bytes of memory\n", size);
 | 
			
		||||
    heap_block* current = start;
 | 
			
		||||
 | 
			
		||||
    // look for a free block
 | 
			
		||||
@ -21,14 +21,14 @@ void* malloc(size_t size)
 | 
			
		||||
        if(current->Size >= size && current->Used == false )
 | 
			
		||||
        {
 | 
			
		||||
            // We found a spot 
 | 
			
		||||
            printf("Block found!\n");
 | 
			
		||||
           // printf("Block found!\n");
 | 
			
		||||
 | 
			
		||||
            // Set the spot to in-use 
 | 
			
		||||
            current->Used = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // split the block 
 | 
			
		||||
            printf("Split block.\n");
 | 
			
		||||
            //printf("Split block.\n");
 | 
			
		||||
            uint32_t oldSize = current->Size;
 | 
			
		||||
            current->Size = size;
 | 
			
		||||
 | 
			
		||||
@ -57,32 +57,30 @@ void free(void* addr)
 | 
			
		||||
{
 | 
			
		||||
    // clear the free boolean that corresponds to this adddress
 | 
			
		||||
    // This should be fairly simple
 | 
			
		||||
    heap_block* allocatedBlock = (heap_block*)(addr - sizeof(heap_block));
 | 
			
		||||
    heap_block* allocatedBlock = (heap_block*)((uint32_t)addr - sizeof(heap_block));
 | 
			
		||||
    allocatedBlock->Used = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void initHeap()
 | 
			
		||||
{
 | 
			
		||||
    // put the start of our kernel heap 1 page after the kernel_end address
 | 
			
		||||
    // Lets calculate the address 
 | 
			
		||||
    printf("FIND SUITABLE HEAP_ADDRESS\n");
 | 
			
		||||
    uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0);
 | 
			
		||||
    uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096;
 | 
			
		||||
    printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS);
 | 
			
		||||
 | 
			
		||||
    // NOTE: we can't check if the mapping has failed or not here!
 | 
			
		||||
    AllocatePage(HEAP_ADDRESS);
 | 
			
		||||
    start = (heap_block*) HEAP_ADDRESS;
 | 
			
		||||
    void* HEAP_ADDRESS = allocate_block();
 | 
			
		||||
    printf("0x%x HEAP Paddr\n", HEAP_ADDRESS);
 | 
			
		||||
 
 | 
			
		||||
    Immediate_Map((uint32_t)HEAP_ADDRESS + 0xC0000000, (uint32_t)HEAP_ADDRESS );
 | 
			
		||||
    start = (heap_block*) ((uint32_t)HEAP_ADDRESS + 0xC0000000);
 | 
			
		||||
    heap_size = 4096;
 | 
			
		||||
 | 
			
		||||
    printf("Clear heap\n");
 | 
			
		||||
    // Clear the heap 
 | 
			
		||||
    printf("set at 0x%x %d bytes to zero\n", start , heap_size);
 | 
			
		||||
 | 
			
		||||
    memset((void*)start, 0x00,  heap_size /4);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("Init first heap block\n");
 | 
			
		||||
    // initialzie 
 | 
			
		||||
    start->Size = heap_size - sizeof(heap_block);
 | 
			
		||||
 | 
			
		||||
    start->Used = false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +1,9 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
 | 
			
		||||
#include "../prekernel/bootstructure.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../../lib/include/mem.h"
 | 
			
		||||
#include "../bitmap.h"
 | 
			
		||||
 | 
			
		||||
#define BLOCK_SIZE 4092 
 | 
			
		||||
							
								
								
									
										60
									
								
								kernel/memory/TaskStateSegment.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								kernel/memory/TaskStateSegment.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "gdt/gdtc.h"
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
 | 
			
		||||
struct TaskStateSegment {
 | 
			
		||||
    uint32_t prev_tss;
 | 
			
		||||
    uint32_t esp0;
 | 
			
		||||
    uint32_t ss0;
 | 
			
		||||
    // everythinge else is unused 
 | 
			
		||||
    uint32_t esp1;
 | 
			
		||||
    uint32_t ss1;
 | 
			
		||||
    uint32_t esp2;
 | 
			
		||||
    uint32_t ss2;
 | 
			
		||||
    uint32_t cr3;
 | 
			
		||||
    uint32_t eip;
 | 
			
		||||
    uint32_t eflags;
 | 
			
		||||
    uint32_t eax;
 | 
			
		||||
    uint32_t ecx;
 | 
			
		||||
    uint32_t edx;
 | 
			
		||||
    uint32_t ebx;
 | 
			
		||||
    uint32_t esp;
 | 
			
		||||
	uint32_t ebp;
 | 
			
		||||
	uint32_t esi;
 | 
			
		||||
	uint32_t edi;
 | 
			
		||||
	uint32_t es;
 | 
			
		||||
	uint32_t cs;
 | 
			
		||||
	uint32_t ss;
 | 
			
		||||
	uint32_t ds;
 | 
			
		||||
	uint32_t fs;
 | 
			
		||||
	uint32_t gs;
 | 
			
		||||
	uint32_t ldt;
 | 
			
		||||
	uint16_t trap;
 | 
			
		||||
	uint16_t iomap_base;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TaskStateSegment tss0 ={};
 | 
			
		||||
 | 
			
		||||
inline void flush_tss()
 | 
			
		||||
{
 | 
			
		||||
     asm volatile("mov $0x2B, %ax ; ltr %ax");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setup_tss(){
 | 
			
		||||
    // ensure the tss is zero'd
 | 
			
		||||
    memset((void*)&tss0, 0, sizeof(tss0));
 | 
			
		||||
    tss0.ss0 =  (uint32_t) &GlobalDescriptorTable[KERNEL_DATA_SEGMENT];
 | 
			
		||||
     
 | 
			
		||||
    extern uint32_t stack_top;
 | 
			
		||||
    tss0.esp0 = (unsigned long)&stack_top;
 | 
			
		||||
 | 
			
		||||
    // Task Segment Descriptor
 | 
			
		||||
 | 
			
		||||
    uint32_t address = (unsigned long) &tss0;
 | 
			
		||||
    uint32_t size = sizeof(tss0);
 | 
			
		||||
    uint32_t limit = (address + size );
 | 
			
		||||
 | 
			
		||||
    add_descriptor(TASK_STATE_SEGMENT, address, limit- 1, 0xE9, 0x0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										130
									
								
								kernel/memory/VirtualMemoryManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								kernel/memory/VirtualMemoryManager.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,130 @@
 | 
			
		||||
#include "VirtualMemoryManager.h"
 | 
			
		||||
#include "../../CoreLib/Memory.h"
 | 
			
		||||
 | 
			
		||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
 | 
			
		||||
 | 
			
		||||
extern uint32_t boot_page_directory[1024] ; // points to the wrong location
 | 
			
		||||
 | 
			
		||||
extern uint32_t boot_page_table[1024];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void flush_cr3(){
 | 
			
		||||
    asm volatile("movl %cr3, %ecx;"
 | 
			
		||||
	             "movl %ecx, %cr3");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void AllocatePage(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    //uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
    printf("Allocation happening at PDE: %d PTE: %d\n", PageDirectoryEntryIndex, PageTableEntryIndex);
 | 
			
		||||
 | 
			
		||||
    // check if the page directory entry is marked as present 
 | 
			
		||||
    if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) 
 | 
			
		||||
    {
 | 
			
		||||
        printf("Directory entry is marked as present\n");
 | 
			
		||||
        uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ;
 | 
			
		||||
        //page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
 | 
			
		||||
        printf("Page table address: 0x%x\n", (uint32_t)&page_table);
 | 
			
		||||
 | 
			
		||||
        // check if the page table entry is marked as present 
 | 
			
		||||
        if ( page_table[PageTableEntryIndex] & 0x1 )
 | 
			
		||||
        {   
 | 
			
		||||
            printf("page already present!\n");
 | 
			
		||||
        } else{
 | 
			
		||||
            printf("Mapping a physical page.\n");
 | 
			
		||||
            // Map the entry to a physical page
 | 
			
		||||
            page_table[PageTableEntryIndex] = (uint32_t)allocate_block() | 0x3;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("Mapping a new page directory entry with a page table\n");
 | 
			
		||||
        // mark the page table as present and allocate a physical block for it
 | 
			
		||||
        boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)allocate_block() | 0x3;
 | 
			
		||||
   
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FreePage(uint32_t vaddr )
 | 
			
		||||
{
 | 
			
		||||
    // uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
    uint32_t* pageTable = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & (0xFFFFE000 + 0xC0000000));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void* physicalAddressToFree = (void*)(pageTable[PageTableEntryIndex] & (0xFFFFE000 + 0xC0000000));
 | 
			
		||||
    free_block(physicalAddressToFree);
 | 
			
		||||
 | 
			
		||||
    pageTable[PageTableEntryIndex] = 0x0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Immediate_Map (  uint32_t vaddr, uint32_t paddr)
 | 
			
		||||
{
 | 
			
		||||
    printf("map 0x%x to 0x%x\n", paddr, vaddr);
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
    printf("Map address at PDE 0x%x PTE  0x%x\n", PageDirectoryEntryIndex, PageTableEntryIndex);
 | 
			
		||||
    printf("boot pagedirectoy address: 0x%x\n", &boot_page_directory);
 | 
			
		||||
    printf("PDE : 0x%x\n", boot_page_directory[PageTableEntryIndex]);
 | 
			
		||||
     if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) {
 | 
			
		||||
        printf("Directory entry is marked as present\n");
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("Mapping a new page directory entry with a page table\n");
 | 
			
		||||
        // mark the page table as present and allocate a physical block for it
 | 
			
		||||
 | 
			
		||||
        void* new_page_dir = allocate_block();
 | 
			
		||||
         memset(new_page_dir, 0 , 1024 * sizeof (uint32_t));
 | 
			
		||||
        printf("New page directory address 0x%x\n", &new_page_dir);
 | 
			
		||||
        boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)new_page_dir | 0x3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("PDE found at : 0x%x\n", (uint32_t) &boot_page_directory[PageDirectoryEntryIndex]);
 | 
			
		||||
    uint32_t* page_table = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000) ;
 | 
			
		||||
    printf("Page table address: 0x%x\n", (uint32_t)page_table);
 | 
			
		||||
 | 
			
		||||
      // check if the page table entry is marked as present
 | 
			
		||||
    if ( page_table[PageTableEntryIndex] & 0x1 )
 | 
			
		||||
    {
 | 
			
		||||
        printf("page already present!\n");
 | 
			
		||||
        printf("Entry found at addr: 0x%x\n", &(page_table[PageTableEntryIndex]));
 | 
			
		||||
    } else{
 | 
			
		||||
        printf("Mapping a physical page.\n");
 | 
			
		||||
        // Map the entry to a physical page
 | 
			
		||||
        page_table[PageTableEntryIndex] = (uint32_t)(paddr | 0x3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    asm ("invlpg (%0)" :: "r" (vaddr) : "memory" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// NOT IMPLEMENTED
 | 
			
		||||
void Immediate_Unmap(uint32_t vaddr)
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: I will implement lazy unmapping for now 
 | 
			
		||||
    //uint32_t page_aligned_address = ALIGN(vaddr, 4096);
 | 
			
		||||
 | 
			
		||||
    // allocate a page at  virtual address
 | 
			
		||||
    //int PageDirectoryEntryIndex = vaddr >> 22;
 | 
			
		||||
    //int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../cpu.h"
 | 
			
		||||
#include "../i386/processor.h"
 | 
			
		||||
#include "PhysicalMemoryManager.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ void SetupVMM();
 | 
			
		||||
void AllocatePage(uint32_t v_addr );
 | 
			
		||||
void FreePage(uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
void Immediate_Map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
void Immediate_Map(uint32_t vaddr, uint32_t paddr);
 | 
			
		||||
void Immediate_Unmap (uint32_t v_addr);
 | 
			
		||||
 | 
			
		||||
// void Demand_map(uint32_t p_addr, uint32_t v_addr);
 | 
			
		||||
@ -1,15 +1,11 @@
 | 
			
		||||
#include "gdtc.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
 | 
			
		||||
#define NULL_SEGMENT          0
 | 
			
		||||
#define KERNEL_CODE_SEGMENT   1
 | 
			
		||||
#define KERNEL_DATA_SEGMENT   2
 | 
			
		||||
#define USER_CODE_SEGMENT     3
 | 
			
		||||
#define USER_DATA_SEGMENT     4
 | 
			
		||||
 | 
			
		||||
SegmentDescriptor GlobalDescriptorTable[5];
 | 
			
		||||
SegmentDescriptor GlobalDescriptorTable[6];
 | 
			
		||||
GlobalDescriptorTableDescriptor gdtDescriptor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){
 | 
			
		||||
   GlobalDescriptorTable[which].base_low = (base & 0xFFFF );
 | 
			
		||||
   GlobalDescriptorTable[which].base_middle = (base >> 6) & 0xFF;
 | 
			
		||||
@ -21,7 +17,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
 | 
			
		||||
   GlobalDescriptorTable[which].granularity |= (granularity & 0xF0);
 | 
			
		||||
   GlobalDescriptorTable[which].access = access;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,9 +24,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
 | 
			
		||||
 | 
			
		||||
void initGDT(){
 | 
			
		||||
 | 
			
		||||
#ifdef __VERBOSE__
 | 
			
		||||
      printf("Init GDT!\n");
 | 
			
		||||
#endif
 | 
			
		||||
      // NULL segment
 | 
			
		||||
      add_descriptor(NULL_SEGMENT, 0,0,0,0);
 | 
			
		||||
 | 
			
		||||
@ -42,17 +34,13 @@ void initGDT(){
 | 
			
		||||
      add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF);      
 | 
			
		||||
 | 
			
		||||
      // User Code Segment
 | 
			
		||||
      // TODO:
 | 
			
		||||
      add_descriptor(USER_CODE_SEGMENT, 0, 0xFFFFFFFF, 0xFA, 0xCF);
 | 
			
		||||
      
 | 
			
		||||
      // User Data Segement
 | 
			
		||||
      // TODO: 
 | 
			
		||||
      
 | 
			
		||||
      add_descriptor(USER_DATA_SEGMENT, 0, 0xFFFFFFFF, 0xF2, 0xCF);
 | 
			
		||||
 | 
			
		||||
      // init Gdt Descriptor
 | 
			
		||||
      gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
 | 
			
		||||
      gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      LoadGlobalDescriptorTable();
 | 
			
		||||
      gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 6 ) - 1);
 | 
			
		||||
      gdtDescriptor.base = (unsigned int) (&GlobalDescriptorTable);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define NULL_SEGMENT          0
 | 
			
		||||
#define KERNEL_CODE_SEGMENT   1
 | 
			
		||||
#define KERNEL_DATA_SEGMENT   2
 | 
			
		||||
#define USER_CODE_SEGMENT     3
 | 
			
		||||
#define USER_DATA_SEGMENT     4
 | 
			
		||||
#define TASK_STATE_SEGMENT    5
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct SegmentDescriptor {
 | 
			
		||||
   unsigned short limit_low;
 | 
			
		||||
   unsigned short base_low;
 | 
			
		||||
@ -10,18 +20,16 @@ struct SegmentDescriptor {
 | 
			
		||||
   unsigned char base_high;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
extern SegmentDescriptor GlobalDescriptorTable[6];
 | 
			
		||||
 | 
			
		||||
struct GlobalDescriptorTableDescriptor{
 | 
			
		||||
   unsigned short limit;
 | 
			
		||||
   unsigned int base;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
}__attribute__((packed)) ;
 | 
			
		||||
 | 
			
		||||
extern SegmentDescriptor GlobalDescriptorTable[];
 | 
			
		||||
extern GlobalDescriptorTableDescriptor gdtDescriptor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" void LoadGlobalDescriptorTable();
 | 
			
		||||
void initGDT();
 | 
			
		||||
@ -5,7 +5,8 @@
 | 
			
		||||
#include "memoryinfo.h"
 | 
			
		||||
#include "../prekernel/multiboot.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "../../lib/include/mem.h"
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
 | 
			
		||||
#include "../bitmap.h"
 | 
			
		||||
 | 
			
		||||
#define BLOCK_SIZE 4092
 | 
			
		||||
							
								
								
									
										164
									
								
								kernel/pci/pci.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								kernel/pci/pci.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,164 @@
 | 
			
		||||
#include "pci.h"
 | 
			
		||||
 | 
			
		||||
void PCI::Scan(){
 | 
			
		||||
     
 | 
			
		||||
        int devicesFound = 0;
 | 
			
		||||
 | 
			
		||||
        printf("Start finding devices, Found: %d devices");
 | 
			
		||||
        // loop through all possible busses, devices and their functions;
 | 
			
		||||
        for( int bus = 0 ; bus < 256 ; bus++)
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
            for(int device = 0; device < 32 ; device ++)
 | 
			
		||||
            {
 | 
			
		||||
                int function = 0;
 | 
			
		||||
 | 
			
		||||
                uint64_t DeviceIdentify = PCI::ConfigReadWord(bus, device, function,0x0);
 | 
			
		||||
                uint32_t DeviceID = GetDevice(bus, device, function) >> 16;
 | 
			
		||||
 | 
			
		||||
                if( DeviceID != 0xFFFF){
 | 
			
		||||
                    PCIBusAddress busAddress =
 | 
			
		||||
                    PCIBusAddress{bus, device, function };
 | 
			
		||||
 | 
			
		||||
                    PrintPCIDevice(busAddress);
 | 
			
		||||
 | 
			
		||||
                    // iterate over the functions if it is a multi function device!
 | 
			
		||||
                    if( PCI::IsMultiFunctionDevice(busAddress) ){
 | 
			
		||||
                        printf("Multi function device! \n");
 | 
			
		||||
                        printf("Check remaining Functions\n");
 | 
			
		||||
                        for ( function = 1  ; function < 8; function++)
 | 
			
		||||
                        {
 | 
			
		||||
                            uint32_t DeviceID = GetDevice(bus, device, function) >> 16;
 | 
			
		||||
 | 
			
		||||
                            if( DeviceID != 0xFFFF){
 | 
			
		||||
                                PCIBusAddress busAddress2 = PCIBusAddress{bus, device, function};
 | 
			
		||||
                                PrintPCIDevice(busAddress2);
 | 
			
		||||
                                devicesFound++;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    
 | 
			
		||||
                    devicesFound++;            
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("Found %d PCI devices!\n", devicesFound);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* PCI::getClassName (uint8_t ClassCode){
 | 
			
		||||
    bool isKnown = (ClassCode < PCI::KnownClassCodes);
 | 
			
		||||
    return  isKnown ? PCI::ClassCodeNames[ClassCode].name : "Unknown ClassCode";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* PCI::getVendor( uint32_t VendorID){
 | 
			
		||||
    switch (VendorID)
 | 
			
		||||
    {
 | 
			
		||||
        case 0x8086:
 | 
			
		||||
            return "Intel Corporation";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0x10DE:
 | 
			
		||||
            return "NVIDIA Corporation";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0x1022:
 | 
			
		||||
            return "Advanced Micro Devices, Inc.[AMD]";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0x1002:
 | 
			
		||||
            return "Advanced Micor Devices, Inc.[AMD/ATI]";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0xbeef:
 | 
			
		||||
            return "VirtualBox Graphics Adapter";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0xcafe:
 | 
			
		||||
            return "VirtualBox Guest Service";
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return "Vendor Unkown";
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t PCI::GetDevice (int bus, int device, int function ){
 | 
			
		||||
    return PCI::ConfigReadWord(bus, device, function,0x0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PCI::IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t header_information = ConfigReadWord(PCIDeviceAddress, 0xC);
 | 
			
		||||
    return (((header_information>>16)
 | 
			
		||||
             & 0x80)
 | 
			
		||||
            >> 7  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t PCI::GetClassCodes( PCIBusAddress& PCIDeviceAddress ){
 | 
			
		||||
    return (uint16_t)(ConfigReadWord(PCIDeviceAddress, 0x8) >> 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t PCI::GetHeaderType( PCIBusAddress& PCIDeviceAddress ){
 | 
			
		||||
    uint32_t header_information = ConfigReadWord(PCIDeviceAddress , 0xC);
 | 
			
		||||
    return (uint8_t) (
 | 
			
		||||
            ((header_information >> 16) //Get higher half
 | 
			
		||||
             & 0x00FF) // Select the last two bytes
 | 
			
		||||
            & 0x7F ); // Mask bit 7 as it indicates if the device is a mulit function device!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t PCI::ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset){
 | 
			
		||||
    uint32_t address;
 | 
			
		||||
 | 
			
		||||
    address = (uint32_t) (
 | 
			
		||||
            ((uint32_t) 1 << PCI_ENABLE_ADDR_SHIFT) |
 | 
			
		||||
            ((uint32_t)bus << PCI_BUS_ADDR_SHIFT) |
 | 
			
		||||
            ((uint32_t)device << PCI_DEVICE_ADDR_SHIFT) |
 | 
			
		||||
            ((uint32_t)func << PCI_FUNCTION_ADDR_SHIFT) |
 | 
			
		||||
            offset );
 | 
			
		||||
 | 
			
		||||
    outl(CONFIG_ADDRESS, address);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return inl(CONFIG_DATA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t PCI::GetProgIF (PCIBusAddress& PCIDeviceAddress){
 | 
			
		||||
    uint32_t data = ConfigReadWord(PCIDeviceAddress, 0x8);
 | 
			
		||||
    return ((data >> 8) & 0xFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t PCI::ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset){
 | 
			
		||||
    outl(CONFIG_ADDRESS , PCIDeviceAddress.getAddress() | offset );
 | 
			
		||||
    return inl(CONFIG_DATA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t PCI::ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number){
 | 
			
		||||
    int offsetToBar = 0x10 + (bar_number* 0x4);
 | 
			
		||||
    return ConfigReadWord(PCIDeviceAddress, offsetToBar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PCI::PrintPCIDevice (PCIBusAddress& PCIDeviceAddress)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t DeviceID =  (PCI::GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) >> 16);
 | 
			
		||||
    uint32_t VendorID  = PCI::GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) & 0xFFFF;
 | 
			
		||||
    printf("Device found!\n");
 | 
			
		||||
    printf("Bus: %d, Device: %d, function: %d \n", PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function);
 | 
			
		||||
    printf("DeviceID: 0x%x, Vendor: %s\n",
 | 
			
		||||
           DeviceID
 | 
			
		||||
            , PCI::getVendor(VendorID)  );
 | 
			
		||||
 | 
			
		||||
    uint8_t header_type = PCI::GetHeaderType(PCIDeviceAddress);
 | 
			
		||||
    printf( "Header type: 0x%x\n", header_type);
 | 
			
		||||
 | 
			
		||||
    uint16_t deviceClasses = PCI::GetClassCodes(PCIDeviceAddress);
 | 
			
		||||
 | 
			
		||||
    printf("class: %s, subClass: %d\n\n", PCI::getClassName((deviceClasses >> 8)), deviceClasses & 0xFF);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								kernel/pci/pci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								kernel/pci/pci.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../io/io.h"
 | 
			
		||||
#include "../terminal/kterm.h"
 | 
			
		||||
#include "pciDevice.h"
 | 
			
		||||
 | 
			
		||||
// Configuration Space Access Mechanism #1
 | 
			
		||||
#define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed
 | 
			
		||||
#define CONFIG_DATA 0xCFC // Will do the actual configuration operation
 | 
			
		||||
#define PCI_BUS_ADDR_SHIFT 16
 | 
			
		||||
#define PCI_DEVICE_ADDR_SHIFT  11
 | 
			
		||||
#define PCI_FUNCTION_ADDR_SHIFT 8
 | 
			
		||||
#define PCI_ENABLE_ADDR_SHIFT 31
 | 
			
		||||
 | 
			
		||||
class PCI  {
 | 
			
		||||
public:
 | 
			
		||||
    static void Scan();
 | 
			
		||||
    static uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset);
 | 
			
		||||
    static uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress);
 | 
			
		||||
    static uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number);
 | 
			
		||||
    static uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset);
 | 
			
		||||
    static uint8_t GetHeaderType( PCIBusAddress& PCIDeviceAddress );
 | 
			
		||||
    static uint16_t GetClassCodes( PCIBusAddress& PCIDeviceAddress );
 | 
			
		||||
    static bool IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress);
 | 
			
		||||
    static uint64_t GetDevice (int bus, int device, int function );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static const char* getClassName (uint8_t ClassCode);
 | 
			
		||||
    static const char* getVendor( uint32_t VendorID);
 | 
			
		||||
    static void PrintPCIDevice(PCIBusAddress& PCIDevice);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    struct ClassCode {
 | 
			
		||||
        const char* name;
 | 
			
		||||
        uint8_t code;
 | 
			
		||||
    };
 | 
			
		||||
    static constexpr ClassCode ClassCodeNames []= {
 | 
			
		||||
            {"Unclassified", 0x0},
 | 
			
		||||
            {"MassStorage Controller", 0x1},
 | 
			
		||||
            {"Network Controller", 0x2},
 | 
			
		||||
            {"Display Controller", 0x3},
 | 
			
		||||
            {"Multimedia Controller", 0x4},
 | 
			
		||||
            {"Memory Controller", 0x5},
 | 
			
		||||
            {"Bridge", 0x6},
 | 
			
		||||
            {"Simple Communication Controller", 0x7},
 | 
			
		||||
            {"Base System Peripheral", 0x8},
 | 
			
		||||
            {"Input Device Controller", 0x9},
 | 
			
		||||
            {"Docking Station", 0xA},
 | 
			
		||||
            {"Processor", 0xB},
 | 
			
		||||
            {"Serial Bus Controller", 0xC},
 | 
			
		||||
            { "Wireless Controller", 0xD},
 | 
			
		||||
            {"Intelligent Controller", 0xE},
 | 
			
		||||
            {"Satellite Communication Controller", 0xF},
 | 
			
		||||
            {"Encryption Controller", 0x10},
 | 
			
		||||
            {"Signal Processing Controller", 0x11},
 | 
			
		||||
            { "Processing Accelerator", 0x12},
 | 
			
		||||
            { "Non-Essential Instrumentation", 0x13}
 | 
			
		||||
    };
 | 
			
		||||
    static const uint8_t KnownClassCodes = sizeof(ClassCodeNames) / sizeof(ClassCode);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -2,15 +2,16 @@
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "multiboot.h"
 | 
			
		||||
#include "../memory/PhysicalMemoryManager.h"
 | 
			
		||||
#include "../memory/VirtualMemoryManager.h"
 | 
			
		||||
#include "../acpi/acpi.h"
 | 
			
		||||
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
#define VADDR_TO_PADDR(vaddr) (vaddr - 0xC0000000)
 | 
			
		||||
#define PADDR_TO_VADDR(paddr) (paddr + 0xC0000000)
 | 
			
		||||
 | 
			
		||||
BootInfoBlock* BIB;
 | 
			
		||||
 | 
			
		||||
extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi) 
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        * Check Multiboot magic number
 | 
			
		||||
        */ 
 | 
			
		||||
@ -21,19 +22,13 @@ extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mbi = PADDR_TO_VADDR(mbi);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // Setup the physical memory manager immmediatly 
 | 
			
		||||
        // Doing so saves the complications of doing it later when 
 | 
			
		||||
        // paging is enabled 
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        If we got a memory map from our bootloader we 
 | 
			
		||||
        should be parsing it to find out the memory regions available.
 | 
			
		||||
        */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 6))
 | 
			
		||||
        {  
 | 
			
		||||
               
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
                // Calculate total memory size 
 | 
			
		||||
                uint32_t RAM_size = 0;
 | 
			
		||||
                for(
 | 
			
		||||
@ -57,6 +52,8 @@ extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi)
 | 
			
		||||
                                deallocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                                // memory map
 | 
			
		||||
                                Immediate_Map(mmap->addr , mmap->addr);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_RESERVED)
 | 
			
		||||
                                allocate_region(mmap->addr, mmap->len);
 | 
			
		||||
                        if(mmap->type == MULTIBOOT_MEMORY_NVS)
 | 
			
		||||
@ -82,13 +79,14 @@ extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // allocate a full block for the other boot info!
 | 
			
		||||
        BootInfoBlock* BIB = (BootInfoBlock*) allocate_block();
 | 
			
		||||
        BIB = (BootInfoBlock*) allocate_block();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /* is boot device valid ? */
 | 
			
		||||
        if (CHECK_FLAG (mbi->flags, 1))
 | 
			
		||||
        {
 | 
			
		||||
                BIB->bootDeviceID = mbi->boot_device;
 | 
			
		||||
 | 
			
		||||
        } else{
 | 
			
		||||
                BIB->bootDeviceID = 0x11111111;
 | 
			
		||||
        }
 | 
			
		||||
@ -99,8 +97,6 @@ extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi)
 | 
			
		||||
                uint32_t i;
 | 
			
		||||
 | 
			
		||||
                BIB->GrubModuleCount = mbi->mods_count;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
 | 
			
		||||
                        
 | 
			
		||||
                }
 | 
			
		||||
@ -135,6 +131,6 @@ extern "C" void prekernelSetup  ( unsigned long magic, multiboot_info_t* mbi)
 | 
			
		||||
 | 
			
		||||
                   // NOTE: Do something with it.. (Store it , process it etc...)
 | 
			
		||||
        } else{
 | 
			
		||||
                BIB->EnabledVBE;
 | 
			
		||||
                BIB->EnabledVBE  = false;
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
@ -1,113 +1,9 @@
 | 
			
		||||
#include "ataDevice.h"
 | 
			
		||||
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1) 
 | 
			
		||||
#include "ATAPIO.h"
 | 
			
		||||
#include "../../io/io.h"
 | 
			
		||||
 | 
			
		||||
void ATA_DEVICE::Soft_Reset(uint8_t DEVICE_CHANNEL,DEVICE_DRIVE drive){
 | 
			
		||||
        printf("Soft reseting drive...\n");
 | 
			
		||||
        outb(channels[DEVICE_CHANNEL].base + 7 , 0x4);
 | 
			
		||||
        // wait a bit..
 | 
			
		||||
        for(int i = 0 ; i < 1000000; i++){
 | 
			
		||||
            asm volatile("NOP");
 | 
			
		||||
        }   
 | 
			
		||||
        outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
 | 
			
		||||
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ATA_DEVICE::Identify(uint16_t DEVICE_CHANNEL,DEVICE_DRIVE drive ){
 | 
			
		||||
    // lets ignore which port we actually want to check for now !
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
        THE STEPS INVOLVED
 | 
			
		||||
 | 
			
		||||
        1. Select the target drive by sending master (0x0A) or slave (0x0B) to the 
 | 
			
		||||
        drive select IO port
 | 
			
		||||
 | 
			
		||||
        2. Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0 
 | 
			
		||||
 | 
			
		||||
        3. Send the identify command (0xEC) to the command IO port 
 | 
			
		||||
 | 
			
		||||
        4. Read the status port 
 | 
			
		||||
            4.2 If the value is 0x0 the drive does not exist
 | 
			
		||||
            4.3 If it has any other value continue
 | 
			
		||||
        5. poll the status port until bit 7 is clear.
 | 
			
		||||
        6. Check if the LBAmid and LBAhi ports are non-zero
 | 
			
		||||
            6.2. If non-zero stop polling this is not an ATA device
 | 
			
		||||
            6.3 If zero continue
 | 
			
		||||
        
 | 
			
		||||
        7. poll status port until bit 3 is set or bit 0 is set
 | 
			
		||||
 | 
			
		||||
        8. if err is clear, read the data from the data port 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
    //printf("channel selected: 0x%x", DEVICE_CHANNEL);
 | 
			
		||||
    // Assuming Master here 
 | 
			
		||||
    // Select the target drive
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6, drive); // on the primary bus select the master drive
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6 , 0x0); // write 0 to the controlport for some reason
 | 
			
		||||
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6, drive);
 | 
			
		||||
    uint8_t status = inb(DEVICE_CHANNEL | 7 );
 | 
			
		||||
    if(status == 0x00){
 | 
			
		||||
        printf("No drive\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // send the identify command;
 | 
			
		||||
    outb(DEVICE_CHANNEL | 7, 0xEC);
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
   // set the sectorCount, LBAlo, LBAmid, LBA,hi IO ports to 0
 | 
			
		||||
   outb(DEVICE_CHANNEL | 2, 0);
 | 
			
		||||
 | 
			
		||||
   outb(DEVICE_CHANNEL | 3, 0);
 | 
			
		||||
 | 
			
		||||
   outb(DEVICE_CHANNEL | 4, 0);
 | 
			
		||||
 | 
			
		||||
   outb(DEVICE_CHANNEL | 5, 0);
 | 
			
		||||
 | 
			
		||||
   // send the identify command ;
 | 
			
		||||
   //printf("command sent!\n");
 | 
			
		||||
   outb(DEVICE_CHANNEL | 7 , 0xEC);
 | 
			
		||||
 | 
			
		||||
   // read the status port 
 | 
			
		||||
   uint8_t status2 = inb(DEVICE_CHANNEL | 7);
 | 
			
		||||
   if( status2 == 0x00){
 | 
			
		||||
       printf("No drive\n");
 | 
			
		||||
       return;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   //printf("Waiting until ready...\n");
 | 
			
		||||
   while(((status2 & 0x80 == 0x80) 
 | 
			
		||||
   && (status2 & 0x01) != 0x01)
 | 
			
		||||
   ) status2 = inb(DEVICE_CHANNEL | 7);
 | 
			
		||||
 | 
			
		||||
   if( status2 & 0x01){
 | 
			
		||||
       printf("Error!\n");
 | 
			
		||||
       return ;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
    uint16_t deviceIdentify [256] = {0};
 | 
			
		||||
 | 
			
		||||
    for ( int i = 0; i < 256; i++){
 | 
			
		||||
        uint16_t data;
 | 
			
		||||
        asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
 | 
			
		||||
 | 
			
		||||
        deviceIdentify[i] = data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("Model-label (ASCII hex): ");
 | 
			
		||||
    for(int i = 27; i < 47; i++){
 | 
			
		||||
        kterm_put((char)(deviceIdentify[i] >> 8));
 | 
			
		||||
        kterm_put((char)(deviceIdentify[i] & 0x00FF));
 | 
			
		||||
    }
 | 
			
		||||
    kterm_put('\n');
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL,  DEVICE_DRIVE drive, uint32_t LBA, uint16_t* buffer) {
 | 
			
		||||
void ATAPIO::Read(uint16_t DEVICE_CHANNEL,  DEVICE_DRIVE drive, uint32_t LBA, uint16_t* buffer) {
 | 
			
		||||
    /*
 | 
			
		||||
    Assume you have a sectorcount byte and a 28 bit LBA value. A sectorcount of 0 means 256 sectors = 128K.
 | 
			
		||||
 | 
			
		||||
@ -128,7 +24,7 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL,  DEVICE_DRIVE drive, uint32_t LBA
 | 
			
		||||
        return ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Read LBA: 0x%x\n", LBA);
 | 
			
		||||
    //printf("Read LBA: 0x%x\n", LBA);
 | 
			
		||||
    // Send 0xE0 for the "master" or 0xF0 for the "slave", ORed with the highest 4 bits of the LBA to port 0x1F6: outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F))
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6 , ( 0xE0 | (LBA >>28) ) );
 | 
			
		||||
    // Send a NULL byte to port 0x1F1, if you like (it is ignored and wastes lots of CPU time): outb(0x1F1, 0x00)
 | 
			
		||||
@ -156,7 +52,7 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL,  DEVICE_DRIVE drive, uint32_t LBA
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Status: %x\n", status);
 | 
			
		||||
    //printf("Status: %x\n", status);
 | 
			
		||||
    // Check if busy!
 | 
			
		||||
    while((status & 0x80) == 0x80){
 | 
			
		||||
        printf("Reading....\r");
 | 
			
		||||
@ -189,6 +85,115 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL,  DEVICE_DRIVE drive, uint32_t LBA
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ATA_DEVICE::Write(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
 | 
			
		||||
void ATAPIO::Write(uint16_t data, DEVICE_DRIVE dev){
 | 
			
		||||
 | 
			
		||||
    printf("Not implemented\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ATAPIO::Identify(ATAPIO_PORT DEVICE_CHANNEL, DEVICE_DRIVE drive ){
 | 
			
		||||
    // lets ignore which port we actually want to check for now !
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
        THE STEPS INVOLVED
 | 
			
		||||
 | 
			
		||||
        1. Select the target drive by sending master (0x0A) or slave (0x0B) to the
 | 
			
		||||
        drive select IO port
 | 
			
		||||
 | 
			
		||||
        2. Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
 | 
			
		||||
 | 
			
		||||
        3. Send the identify command (0xEC) to the command IO port
 | 
			
		||||
 | 
			
		||||
        4. Read the status port
 | 
			
		||||
            4.2 If the value is 0x0 the drive does not exist
 | 
			
		||||
            4.3 If it has any other value continue
 | 
			
		||||
        5. poll the status port until bit 7 is clear.
 | 
			
		||||
        6. Check if the LBAmid and LBAhi ports are non-zero
 | 
			
		||||
            6.2. If non-zero stop polling this is not an ATA device
 | 
			
		||||
            6.3 If zero continue
 | 
			
		||||
 | 
			
		||||
        7. poll status port until bit 3 is set or bit 0 is set
 | 
			
		||||
 | 
			
		||||
        8. if err is clear, read the data from the data port
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //printf("channel selected: 0x%x", DEVICE_CHANNEL);
 | 
			
		||||
    // Assuming Master here
 | 
			
		||||
    // Select the target drive
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6, drive); // on the primary bus select the master drive
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6 , 0x0); // write 0 to the controlport for some reason
 | 
			
		||||
    outb(DEVICE_CHANNEL | 6, drive);
 | 
			
		||||
    uint8_t status = inb(DEVICE_CHANNEL | 7 );
 | 
			
		||||
    if(status == 0x00){
 | 
			
		||||
        printf("No drive\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // send the identify command;
 | 
			
		||||
    outb(DEVICE_CHANNEL | 7, 0xEC);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // set the sectorCount, LBAlo, LBAmid, LBA,hi IO ports to 0
 | 
			
		||||
    outb(DEVICE_CHANNEL | 2, 0);
 | 
			
		||||
 | 
			
		||||
    outb(DEVICE_CHANNEL | 3, 0);
 | 
			
		||||
 | 
			
		||||
    outb(DEVICE_CHANNEL | 4, 0);
 | 
			
		||||
 | 
			
		||||
    outb(DEVICE_CHANNEL | 5, 0);
 | 
			
		||||
 | 
			
		||||
    // send the identify command ;
 | 
			
		||||
    //printf("command sent!\n");
 | 
			
		||||
    outb(DEVICE_CHANNEL | 7 , 0xEC);
 | 
			
		||||
 | 
			
		||||
    // read the status port
 | 
			
		||||
    uint8_t status2 = inb(DEVICE_CHANNEL | 7);
 | 
			
		||||
    if( status2 == 0x00){
 | 
			
		||||
        printf("No drive\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //printf("Waiting until ready...\n");
 | 
			
		||||
    while(((status2 & 0x80 == 0x80)
 | 
			
		||||
           && (status2 & 0x01) != 0x01)
 | 
			
		||||
            ) status2 = inb(DEVICE_CHANNEL | 7);
 | 
			
		||||
 | 
			
		||||
    if( status2 & 0x01){
 | 
			
		||||
        printf("Error!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint16_t deviceIdentify [256] = {0};
 | 
			
		||||
 | 
			
		||||
    for ( int i = 0; i < 256; i++){
 | 
			
		||||
        uint16_t data;
 | 
			
		||||
        asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
 | 
			
		||||
 | 
			
		||||
        deviceIdentify[i] = data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("Model-label (ASCII hex): ");
 | 
			
		||||
    for(int i = 27; i < 47; i++){
 | 
			
		||||
        kterm_put((char)(deviceIdentify[i] >> 8));
 | 
			
		||||
        kterm_put((char)(deviceIdentify[i] & 0x00FF));
 | 
			
		||||
    }
 | 
			
		||||
    kterm_put('\n');
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ATAPIO::Soft_Reset(ATAPIO_PORT DEVICE_CHANNEL, DEVICE_DRIVE drive){
 | 
			
		||||
    printf("Soft reseting drive...\n");
 | 
			
		||||
    outb(DEVICE_CHANNEL + 7 , 0x4);
 | 
			
		||||
    // wait a bit..
 | 
			
		||||
    for(int i = 0 ; i < 1000000; i++){
 | 
			
		||||
        asm volatile("NOP");
 | 
			
		||||
    }
 | 
			
		||||
    outb(DEVICE_CHANNEL + 7 , 0x0);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								kernel/storage/ata pio/ATAPIO.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								kernel/storage/ata pio/ATAPIO.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "../ide/ideCommands.h"
 | 
			
		||||
#include "../ide/sampleIDE.definitions.h"
 | 
			
		||||
#include "../../devices/BlockDevice.h"
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* This first driver wil make use of IO ports.
 | 
			
		||||
* Doing so means reading or writing from disk is going
 | 
			
		||||
* to be very cpu intensive.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
enum DEVICE_DRIVE{
 | 
			
		||||
    MASTER = 0xA0,
 | 
			
		||||
    SLAVE = 0xB0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum  ATAPIO_PORT {
 | 
			
		||||
    Primary = 0x1f0,
 | 
			
		||||
    Secondary = 0x170
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ATAPIO
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static bool Identify(ATAPIO_PORT, DEVICE_DRIVE);
 | 
			
		||||
    static void Read (uint16_t, DEVICE_DRIVE, uint32_t, uint16_t*);
 | 
			
		||||
    static void Write(uint16_t, DEVICE_DRIVE);
 | 
			
		||||
    static void Soft_Reset(ATAPIO_PORT , DEVICE_DRIVE );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../io/io.h"
 | 
			
		||||
#include "../../io/io.h"
 | 
			
		||||
#include "../ide/ideCommands.h"
 | 
			
		||||
#include "../ide/sampleIDE.definitions.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										404
									
								
								kernel/storage/filesystems/FAT/FAT.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								kernel/storage/filesystems/FAT/FAT.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,404 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 21/02/23.
 | 
			
		||||
//
 | 
			
		||||
#include "FAT.h"
 | 
			
		||||
#include "../../ata pio/ATAPIO.h"
 | 
			
		||||
#include "../../../memory/KernelHeap.h"
 | 
			
		||||
#include "../../partitiontables/mbr/MasterBootRecord.h"
 | 
			
		||||
#include "../../../../CoreLib/ctype.h"
 | 
			
		||||
#include "../../../../CoreLib/Memory.h"
 | 
			
		||||
#include <CoreLib/Memory.h>
 | 
			
		||||
#include <CoreLib/ctype.h>
 | 
			
		||||
 | 
			
		||||
// exposed driver API
 | 
			
		||||
FS_SUPER* FAT::Mount(filesystem *fs, const char* name , vfsmount *mnt)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    if( strncmp (fs->name, "fat", 3 ) != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        printf("Can't mount filesystem with none fat type!\n");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    auto* bpb =  GetBiosParameterBlock();
 | 
			
		||||
    auto fat_type = DetermineFATType(bpb);
 | 
			
		||||
 | 
			
		||||
    if(fat_type != FAT_TYPE::FAT16)
 | 
			
		||||
        return nullptr;
 | 
			
		||||
 | 
			
		||||
    FS_SUPER* sb = (FS_SUPER*) malloc(sizeof(FS_SUPER));
 | 
			
		||||
    DirectoryNode* root = (DirectoryNode*) malloc(sizeof (DirectoryNode));
 | 
			
		||||
    inode* node = (inode*) malloc(sizeof(inode));
 | 
			
		||||
 | 
			
		||||
    root->children = nullptr;
 | 
			
		||||
    node->internal = (void*)FAT::GetSectorOfRootDirectory(bpb); //sector number;
 | 
			
		||||
    node->lookup = FAT::Lookup;
 | 
			
		||||
    root->name = (char*) name;
 | 
			
		||||
    root->node = node;
 | 
			
		||||
    root->parent = nullptr;
 | 
			
		||||
    root->compare = FAT::Compare;
 | 
			
		||||
    mnt->mnt_count =1;
 | 
			
		||||
    mnt->mnt_devname = "QEMU HDD";
 | 
			
		||||
    mnt->mnt_flags = 0;
 | 
			
		||||
    mnt->mnt_parent = nullptr;
 | 
			
		||||
    mnt->root = root;
 | 
			
		||||
    mnt->sb = sb;
 | 
			
		||||
    sb->type = fs;
 | 
			
		||||
    sb->root = root;
 | 
			
		||||
    sb->fs_info = bpb;
 | 
			
		||||
 | 
			
		||||
    return sb;
 | 
			
		||||
}
 | 
			
		||||
FILE FAT::Open(char* filename){
 | 
			
		||||
 | 
			
		||||
    return (FILE){nullptr, 0, nullptr, nullptr, 1} ;
 | 
			
		||||
}
 | 
			
		||||
int FAT::Read(FILE* file, void* buffer , unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    if(file == nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        printf("NO FILE!!\n");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    inode* node = file->root;
 | 
			
		||||
 | 
			
		||||
    if(node== nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        printf("No INODE!\n");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int cluster = (int)node->internal;
 | 
			
		||||
    auto* bpb = FAT::GetBiosParameterBlock();
 | 
			
		||||
 | 
			
		||||
    unsigned int FAT_entry = FAT::GetFATEntry(bpb, cluster);
 | 
			
		||||
    unsigned int root_dir_sector = FAT::RootDirSize(bpb);
 | 
			
		||||
    unsigned int fat_size = bpb->FATSz16;
 | 
			
		||||
    unsigned int first_data_sector = bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sector;
 | 
			
		||||
    unsigned int file_data_sector = ((cluster - 2) * bpb->SecPerClus) + first_data_sector;
 | 
			
		||||
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, file_data_sector, (uint16_t*)buffer);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int FAT::Write(FILE* file, const void* buffer, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int FAT::Compare (DirectoryNode*, char* filename, char* filename2)
 | 
			
		||||
{
 | 
			
		||||
    //TODO Implement proper compare method for 8.3 filenames
 | 
			
		||||
   // printf("COMPARE: %s with %s\n", filename, filename2);
 | 
			
		||||
    return memcmp(filename, filename2, 11);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int FAT::Create(inode* dir_node, inode** target, const char* component_name){}
 | 
			
		||||
 | 
			
		||||
DirectoryNode* FAT::Lookup (inode* currentDir , DirectoryNode*  dir)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    uint16_t data[256];
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, (int)currentDir->internal , data);
 | 
			
		||||
 | 
			
		||||
    List* lastAdded = nullptr;
 | 
			
		||||
    auto* directory = (DIR*)data;
 | 
			
		||||
    for(int i = 0; i < sizeof(data) / sizeof (DIR); i++)
 | 
			
		||||
    {
 | 
			
		||||
        DIR* entry = (DIR*)((uint32_t)directory + (i * sizeof(DIR)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(
 | 
			
		||||
            entry->Name[0] == FAT::FREE_DIR ||
 | 
			
		||||
            entry->ATTR & FAT::ATTRIBUTES::ATTR_VOLUME_ID ||
 | 
			
		||||
            entry->ATTR & FAT::ATTRIBUTES::ATTR_SYSTEM ||
 | 
			
		||||
            entry->ATTR & FAT::ATTRIBUTES::ATTR_HIDDEN
 | 
			
		||||
        ){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if( entry->ATTR & FAT::ATTRIBUTES::ATTR_DIRECTORY){
 | 
			
		||||
            printf("entry in directory\n");
 | 
			
		||||
            for(int i = 0; i < 11 ;i ++)
 | 
			
		||||
                kterm_put(entry->Name[i]);
 | 
			
		||||
            kterm_put('\n');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if( entry->Name[0] == FAT::FREE_DIR_2 )
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        auto* dirNode = (DirectoryNode*) malloc(sizeof (DirectoryNode));
 | 
			
		||||
 | 
			
		||||
        char* name = (char*)malloc(sizeof(char[11]));
 | 
			
		||||
        memcpy(name, entry->Name, 11 );
 | 
			
		||||
        dirNode->name = name;
 | 
			
		||||
        dirNode->compare = dir->compare;
 | 
			
		||||
        dirNode->parent = dir;
 | 
			
		||||
 | 
			
		||||
        dirNode->node= (inode*) malloc(sizeof (inode));
 | 
			
		||||
        dirNode->node->internal = (void*)entry->FstClusLo;
 | 
			
		||||
 | 
			
		||||
        dirNode->node->read = currentDir->read;
 | 
			
		||||
        dirNode->node->lookup = currentDir->lookup;
 | 
			
		||||
        dirNode->node->sb = currentDir->sb;
 | 
			
		||||
        dirNode->node->size = entry->FileSize;
 | 
			
		||||
 | 
			
		||||
        List* dirlist = (List*) malloc(sizeof (List));
 | 
			
		||||
        dirlist->data = dirNode;
 | 
			
		||||
        dirlist->next = nullptr;
 | 
			
		||||
 | 
			
		||||
        lastAdded = dirlist;
 | 
			
		||||
        auto* temp = dir->children;
 | 
			
		||||
        dir->children = lastAdded;
 | 
			
		||||
        lastAdded->next = temp;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (DirectoryNode*)dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// internal functions
 | 
			
		||||
FAT_TYPE FAT::DetermineFATType(BiosParameterBlock* bpb){
 | 
			
		||||
    int RootDirSector = ((bpb->RootEntCnt * 32) + (bpb->BytsPerSec -1)) / bpb->BytsPerSec;
 | 
			
		||||
    int FATSz = 0;
 | 
			
		||||
    if(bpb->FATSz16 != 0){
 | 
			
		||||
        FATSz = bpb->FATSz16;
 | 
			
		||||
    } else{
 | 
			
		||||
       // FATSz = bpb->FATSz32;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    int TotSec = 0;
 | 
			
		||||
    if(bpb->TotSec16 != 0){
 | 
			
		||||
        TotSec= bpb->TotSec16;
 | 
			
		||||
    }else{
 | 
			
		||||
        TotSec = bpb->TotSec32;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int DataSec = TotSec - (bpb->RsvdSecCnt + (bpb->NumFATs * FATSz) + RootDirSector);
 | 
			
		||||
    int CountofClusters = DataSec / bpb->SecPerClus;
 | 
			
		||||
 | 
			
		||||
    if(CountofClusters < 4085){
 | 
			
		||||
        return FAT_TYPE::FAT12;
 | 
			
		||||
    } else if (CountofClusters < 65525) {
 | 
			
		||||
        return FAT_TYPE::FAT16;
 | 
			
		||||
    } else{
 | 
			
		||||
        return FAT_TYPE::FAT32;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
BiosParameterBlock* FAT::GetBiosParameterBlock(bool DEBUG  ){
 | 
			
		||||
    BiosParameterBlock* bpb = (BiosParameterBlock*) malloc(sizeof(BiosParameterBlock));
 | 
			
		||||
    uint16_t StartAddress = 0x00 ;
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, StartAddress, (uint16_t*) bpb);
 | 
			
		||||
 | 
			
		||||
    if(DEBUG)
 | 
			
		||||
    {
 | 
			
		||||
        printf("OEM ID: %s\n", bpb->OEMName);
 | 
			
		||||
        printf("Bytes per sector: %d\n", bpb->BytsPerSec);
 | 
			
		||||
        printf("Sectors per cluster: %d\n", bpb->SecPerClus);
 | 
			
		||||
        printf("Reserved sectors: %d\n", bpb->RsvdSecCnt);
 | 
			
		||||
        printf("Number of FAT: %d\n", bpb->NumFATs);
 | 
			
		||||
        printf("Number of Dir entries: %d\n", bpb->RootEntCnt);
 | 
			
		||||
        printf("Total Sectors in volume: %d\n", bpb->TotSec16 == 0 ? bpb->TotSec32 : bpb->TotSec16);
 | 
			
		||||
        printf("Sectors per FAT: %d\n", bpb->FATSz16 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return bpb;
 | 
			
		||||
}
 | 
			
		||||
uint16_t FAT::GetFATEntry (BiosParameterBlock* bpb, unsigned int cluster){
 | 
			
		||||
    int FATSz = bpb->FATSz16;
 | 
			
		||||
    int FATOffset = 0;
 | 
			
		||||
    FAT_TYPE type = FAT::DetermineFATType(bpb);
 | 
			
		||||
    if( type == FAT_TYPE::FAT16){
 | 
			
		||||
        FATOffset = cluster *2;
 | 
			
		||||
    } else if( type == FAT_TYPE::FAT32){
 | 
			
		||||
        FATOffset = cluster * 4;
 | 
			
		||||
    }
 | 
			
		||||
    int thisFATSecNum = bpb->RsvdSecCnt + (FATOffset / bpb->BytsPerSec); // Sector number containing the entry for the cluster
 | 
			
		||||
 | 
			
		||||
    // For any other FAT other than the default
 | 
			
		||||
    // SectorNumber = (FATNumber * FATSz) + ThisFATSecNum
 | 
			
		||||
 | 
			
		||||
    uint16_t buff[bpb->BytsPerSec];
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, thisFATSecNum, buff );
 | 
			
		||||
    int thisFATEntOffset = FATOffset % bpb->BytsPerSec; // offset  for the entry in the sector containing the entry for the cluster
 | 
			
		||||
    uint16_t ClusterEntryValue = 0;
 | 
			
		||||
    // Get the FATEntry
 | 
			
		||||
    if(type == FAT_TYPE::FAT16){
 | 
			
		||||
        return *((uint16_t*) &buff[thisFATEntOffset]);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    else{
 | 
			
		||||
        // FAT32 logic
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
uint16_t FAT::DetermineFreeSpace()
 | 
			
		||||
{
 | 
			
		||||
    // Loop through all FAT entries in all FAT's
 | 
			
		||||
    // to construct a list of free/available clusters
 | 
			
		||||
    // Free clusters are recorded with all 0's except on FAT32 where
 | 
			
		||||
    // the highest order 4 bits should be ignored.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The number of sectors reserved for each FAT (count of sectors in the BPB_FATSz16 or
 | 
			
		||||
BPB_FATSz32 fields) may be bigger than the actual number of sectors required for
 | 
			
		||||
containing the entire FAT. Therefore, there may be totally unused FAT sectors at the end of
 | 
			
		||||
each FAT in the FAT region of the volume. Each implementation must determine the value
 | 
			
		||||
for the last valid sector in the FAT using CountOfClusters (the last valid sector in the FAT
 | 
			
		||||
is the one containing the FAT entry numbered CountOfClusters + 1).
 | 
			
		||||
All sectors reserved for the FAT beyond the last valid sector (defined as the one containing
 | 
			
		||||
the FAT entry for the last cluster) must be set to 0x0 during volume initialization/format.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
int FAT::GetSectorOfRootDirectory (BiosParameterBlock* bpb)
 | 
			
		||||
{
 | 
			
		||||
   return (bpb->RsvdSecCnt + (bpb->NumFATs * bpb->FATSz16));
 | 
			
		||||
}
 | 
			
		||||
unsigned int FAT::RootDirSize(BiosParameterBlock* bpb)
 | 
			
		||||
{
 | 
			
		||||
    return ((bpb->RootEntCnt * 32) + (bpb->BytsPerSec -1)) /bpb->BytsPerSec;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
void FAT::OpenSubdir(DIR* directory, BiosParameterBlock* bpb ){
 | 
			
		||||
 | 
			
		||||
    unsigned int cluster = directory->FstClusLo;
 | 
			
		||||
    printf("Listing contents of " );
 | 
			
		||||
 | 
			
		||||
     for(unsigned char n : directory->Name){
 | 
			
		||||
         if(n == 0x20)
 | 
			
		||||
             continue;
 | 
			
		||||
         kterm_put(n);
 | 
			
		||||
     }
 | 
			
		||||
    kterm_put('\n');
 | 
			
		||||
    printf("FsCluHi: 0x%x , FsCluLo: 0x%x\n", directory->FstClusHi, directory->FstClusLo);
 | 
			
		||||
    printf("Cluster: 0x%x\n", cluster);
 | 
			
		||||
    unsigned int FATEntry = FAT::GetFATEntry(bpb, cluster);
 | 
			
		||||
    printf("FAT_Entry: 0x%x\n", FATEntry);
 | 
			
		||||
 | 
			
		||||
    unsigned int root_dir_sectors = FAT::RootDirSize(bpb);
 | 
			
		||||
    unsigned int fat_size = bpb->FATSz16;
 | 
			
		||||
    unsigned int first_data_sector = bpb->RsvdSecCnt + ( bpb->NumFATs * fat_size) + root_dir_sectors;
 | 
			
		||||
    unsigned int first_directory_sector = ((cluster - 2) * bpb->SecPerClus) + first_data_sector;
 | 
			
		||||
    printf("Directory first sector 0x%x\n" , first_directory_sector);
 | 
			
		||||
    uint16_t data[256];
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, first_directory_sector, data);
 | 
			
		||||
 | 
			
		||||
    auto* directoryContents = (DIR*) data;
 | 
			
		||||
    for(int i = 0; i < sizeof(data) / sizeof(DIR); i++){
 | 
			
		||||
        DIR* entry = (DIR*)((uint32_t)directoryContents + (i * sizeof(DIR)));
 | 
			
		||||
 | 
			
		||||
        if(entry->Name[0] == FAT::FREE_DIR || entry->Name[0] == FAT::FREE_DIR_2 || entry->Name[0] == 0xE5)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_HIDDEN){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_SYSTEM)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_VOLUME_ID){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!(entry->ATTR & FAT::ATTRIBUTES::ATTR_LONG_NAME)){
 | 
			
		||||
            for(char n : entry->Name){
 | 
			
		||||
                if(n == 0x20)
 | 
			
		||||
                    continue;
 | 
			
		||||
                kterm_put(n);
 | 
			
		||||
            }
 | 
			
		||||
            kterm_put('\n');
 | 
			
		||||
        }else{
 | 
			
		||||
            printf("LFN\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
void FAT::ReadFileContents(DIR* fileEntry , BiosParameterBlock* bpb){
 | 
			
		||||
    unsigned int cluster = fileEntry->FstClusLo;
 | 
			
		||||
    printf("cluster NR: %x\n", cluster);
 | 
			
		||||
    unsigned int FATEntry = FAT::GetFATEntry(bpb, cluster);
 | 
			
		||||
    unsigned int root_dir_sectors = FAT::RootDirSize(bpb);
 | 
			
		||||
    unsigned int fat_size = bpb->FATSz16;
 | 
			
		||||
    unsigned int first_data_sector = bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sectors;
 | 
			
		||||
    unsigned int file_data_sector = ((cluster -2) * bpb->SecPerClus) + first_data_sector;
 | 
			
		||||
    printf("FAT entry = %x\n", FATEntry);
 | 
			
		||||
    uint16_t data[256];
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, file_data_sector, data);
 | 
			
		||||
 | 
			
		||||
    for (unsigned short n : data)
 | 
			
		||||
    {
 | 
			
		||||
        kterm_put(n & 0x00ff);
 | 
			
		||||
        kterm_put(n >> 8);
 | 
			
		||||
    }
 | 
			
		||||
    kterm_put('\n');
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
void FAT::ListRootDirectoryContents(BiosParameterBlock* bpb){
 | 
			
		||||
    int total_sectors = bpb->TotSec32;
 | 
			
		||||
    int fat_size = bpb->FATSz16;
 | 
			
		||||
    int root_dir_sectors = FAT::RootDirSize(bpb);
 | 
			
		||||
    int first_data_sector = bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sectors ;
 | 
			
		||||
    int data_sectors = bpb->TotSec32 - (bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sectors);
 | 
			
		||||
    int total_clusters = data_sectors / bpb->SecPerClus;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    int first_root_dir_sector = first_data_sector - root_dir_sectors;
 | 
			
		||||
    //int first_sector_of_cluster = ((cluster - 2) * bpb->SecPerClus) + first_data_sector;
 | 
			
		||||
    uint16_t data[256];
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, first_root_dir_sector, data);
 | 
			
		||||
 | 
			
		||||
    auto* RootDirectory = (DIR*)data;
 | 
			
		||||
    for(int i = 0; i < sizeof(data) / sizeof (DIR); i++)
 | 
			
		||||
    {
 | 
			
		||||
        DIR* entry = (DIR*)((uint32_t)RootDirectory + (i * sizeof(DIR)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(entry->Name[0] == FAT::FREE_DIR || entry->Name[0] == FAT::FREE_DIR_2 || entry->Name[0] == 0xE5){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_HIDDEN){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_SYSTEM)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_VOLUME_ID){
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (!(entry->ATTR & FAT::ATTRIBUTES::ATTR_LONG_NAME)){
 | 
			
		||||
            for(char n : entry->Name){
 | 
			
		||||
                if(n == 0x20)
 | 
			
		||||
                    continue;
 | 
			
		||||
                kterm_put(n);
 | 
			
		||||
            }
 | 
			
		||||
        }else{
 | 
			
		||||
            printf("Long file name detected!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" [Size: %d bytes, Attributes: %d]\n", entry->ATTR, entry->FileSize);
 | 
			
		||||
        if(entry->ATTR & FAT::ATTRIBUTES::ATTR_DIRECTORY ){
 | 
			
		||||
            FAT::OpenSubdir(entry, bpb);
 | 
			
		||||
        } else {
 | 
			
		||||
            FAT::ReadFileContents(entry, bpb);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								kernel/storage/filesystems/FAT/FAT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								kernel/storage/filesystems/FAT/FAT.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 21/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "../../vfs/vfs_types.h"
 | 
			
		||||
#include "../../vfs/vfs_types.h"
 | 
			
		||||
#include "../../partitiontables/mbr/MasterBootRecord.h"
 | 
			
		||||
 | 
			
		||||
struct ExtendedBootRecord_FAT16{
 | 
			
		||||
    uint8_t DrvNum;
 | 
			
		||||
    uint8_t Reserved1;
 | 
			
		||||
    uint8_t BootSig;
 | 
			
		||||
    const uint32_t VolID;
 | 
			
		||||
    uint8_t VolLab [11];
 | 
			
		||||
    uint8_t FilSysType [8];
 | 
			
		||||
    uint8_t bootCode [448];
 | 
			
		||||
    uint16_t Signature_word;
 | 
			
		||||
    uint8_t SecRmndr[512];
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct BiosParameterBlock {
 | 
			
		||||
    uint8_t jmpBoot[3];
 | 
			
		||||
    uint8_t OEMName [8];
 | 
			
		||||
    uint16_t  BytsPerSec ; // I suspect would be 512
 | 
			
		||||
    uint8_t SecPerClus ;
 | 
			
		||||
    uint16_t RsvdSecCnt;
 | 
			
		||||
    uint8_t NumFATs; // Probably equals 2
 | 
			
		||||
    uint16_t RootEntCnt; // Root directory must contain entire sectors
 | 
			
		||||
    uint16_t TotSec16 ; // 0 means >65535 sectors in volume , actual count can be found in LargeSectorCount
 | 
			
		||||
    uint8_t Media ; // Indication the media descriptor type
 | 
			
		||||
    uint16_t FATSz16;// only in FAT12 / FAT 16
 | 
			
		||||
    uint16_t SecPerTrk;
 | 
			
		||||
    uint16_t NumHeads;
 | 
			
		||||
    uint32_t HiddSec;
 | 
			
		||||
    uint32_t TotSec32;
 | 
			
		||||
    ExtendedBootRecord_FAT16 ebpb;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct DIR {
 | 
			
		||||
    uint8_t Name [11];
 | 
			
		||||
    uint8_t ATTR ;
 | 
			
		||||
    uint8_t NTRes;
 | 
			
		||||
    uint8_t CrtTimeTenth; // File Creation time component - count of tenths of a second (between 0 and 199)
 | 
			
		||||
    uint16_t CrtTime; // Creation time. Granularity is 2 seconds
 | 
			
		||||
    uint16_t CrtDate; // Creation date.
 | 
			
		||||
    uint16_t LstAccDate; // Last Access Date (Last read or write date)
 | 
			
		||||
    uint16_t FstClusHi; // High Word of first data cluster for file/directory described
 | 
			
		||||
    uint16_t WrtTime; // Last Modification time | Must equal CrtTime
 | 
			
		||||
    uint16_t WrtDate; // Last Modification date |  Must equal CrtDate
 | 
			
		||||
    uint16_t FstClusLo; // Low word of first data cluster for file/directory described
 | 
			
		||||
    uint32_t FileSize; // size in bytes of file/directory described
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum struct FAT_TYPE{
 | 
			
		||||
    FAT12,
 | 
			
		||||
    FAT16,
 | 
			
		||||
    FAT32,
 | 
			
		||||
    VFAT,
 | 
			
		||||
    UNKOWN
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class FAT {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // Wanted API for vfs
 | 
			
		||||
    static FILE Open(char* filename);
 | 
			
		||||
    static int close(FILE* file);
 | 
			
		||||
    static int Read(FILE* file, void* buffer , unsigned  int length);
 | 
			
		||||
    static int Write(FILE* file, const void* buffer, unsigned int length);
 | 
			
		||||
    static int Create(inode* dir_node, inode** target, const char* component_name);
 | 
			
		||||
    static DirectoryNode* Lookup(inode* , DirectoryNode*);
 | 
			
		||||
    static int Compare(DirectoryNode* , char *filename, char *filename2);
 | 
			
		||||
    static FS_SUPER* Mount(filesystem* fs, const char* name , vfsmount* mount);
 | 
			
		||||
 | 
			
		||||
    static const int FREE = 0x0000;
 | 
			
		||||
    static const int ALLOCATED = 0x0002;
 | 
			
		||||
    static const int BAD = 0xFFF7;
 | 
			
		||||
    static const int EOF = 0xFFFF;
 | 
			
		||||
 | 
			
		||||
    static const int ClnShutBitMask = 0x8000;
 | 
			
		||||
    static const int HrdErrBitMask = 0x4000;
 | 
			
		||||
 | 
			
		||||
    static const char DOS_TRAILING_SPACE = 0x20;
 | 
			
		||||
    static const char FREE_DIR = 0xE5; // If KANJI charset 0x05
 | 
			
		||||
    static const char FREE_DIR_2 = 0x00; // All directories after this are free including this one
 | 
			
		||||
    static void ListRootDirectoryContents(BiosParameterBlock* bpb );
 | 
			
		||||
    static BiosParameterBlock* GetBiosParameterBlock(bool DEBUG =false );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    enum ATTRIBUTES {
 | 
			
		||||
        ATTR_READ_ONLY = 0x01,
 | 
			
		||||
        ATTR_HIDDEN = 0x02,
 | 
			
		||||
        ATTR_SYSTEM = 0x04,
 | 
			
		||||
        ATTR_VOLUME_ID = 0x08,
 | 
			
		||||
        ATTR_DIRECTORY = 0x10,
 | 
			
		||||
        ATTR_ARCHIVE = 0x20,
 | 
			
		||||
        ATTR_LONG_NAME = (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    static FAT_TYPE DetermineFATType(BiosParameterBlock* bpb);
 | 
			
		||||
    static uint16_t GetFATEntry(BiosParameterBlock*, unsigned int);
 | 
			
		||||
    static uint16_t DetermineFreeSpace();
 | 
			
		||||
    static int GetSectorOfRootDirectory(BiosParameterBlock*);
 | 
			
		||||
    static unsigned int RootDirSize(BiosParameterBlock*);
 | 
			
		||||
    static void OpenSubdir (DIR*, BiosParameterBlock*);
 | 
			
		||||
    static void ReadFileContents(DIR *fileEntry, BiosParameterBlock *bpb);
 | 
			
		||||
 | 
			
		||||
    enum ENTRY_SIZE {
 | 
			
		||||
        FAT12 = 12,
 | 
			
		||||
        FAT16 = 16,
 | 
			
		||||
        FAT32 = 32
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										42
									
								
								kernel/storage/filesystems/FAT/msdosDate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								kernel/storage/filesystems/FAT/msdosDate.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 23/02/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../../../terminal/kterm.h"
 | 
			
		||||
#include "../../../memory/KernelHeap.h"
 | 
			
		||||
#include "../../../../CoreLib/Memory.h"
 | 
			
		||||
 | 
			
		||||
// Date Format
 | 
			
		||||
// [0..4] Day
 | 
			
		||||
// [5..8] Month
 | 
			
		||||
// [9..15] Year
 | 
			
		||||
class MSDOSDATE {
 | 
			
		||||
    static void ParseDate(unsigned int date){
 | 
			
		||||
        printf("Date (hex) 0x%x\n", date);
 | 
			
		||||
        unsigned int year = (date >> 9 )+ 1980;
 | 
			
		||||
        unsigned int month = (date & 0xf0   ) >> 4;
 | 
			
		||||
        unsigned int day = date & 0xf ;
 | 
			
		||||
        printf("Date: (D,M,Y) %d, %d ,%d\n", day , month, year );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Time Format
 | 
			
		||||
// [0..4] Seconds
 | 
			
		||||
// [5..10] Minute
 | 
			
		||||
// [11..15] Hour
 | 
			
		||||
class MSDOSTIME {
 | 
			
		||||
    static void ParseTime(unsigned int time)
 | 
			
		||||
    {
 | 
			
		||||
        printf("Time (hex) 0x%x\n", time);
 | 
			
		||||
        unsigned int seconds =  ( time & 0x0f) * 2;
 | 
			
		||||
        unsigned int minutes = (time & 0xf0);
 | 
			
		||||
        unsigned int hours = (time & 0xf00);
 | 
			
		||||
        printf("Time (H:M:S) %d:%d:%d\n", hours, minutes, seconds);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h> 
 | 
			
		||||
#include "../pci/pciDevice.h"
 | 
			
		||||
#include "../pci/pci.h"
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#include "ideCommands.h"
 | 
			
		||||
#include "sampleIDE.h"
 | 
			
		||||
#include "../../pci/pciDevice.h"
 | 
			
		||||
#include "../../pci/pci.h"
 | 
			
		||||
 | 
			
		||||
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1) 
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ inline void TestIDEController(){
 | 
			
		||||
    int device =1  , function = 1;
 | 
			
		||||
    PCIBusAddress IDEControllerPCIAddress = PCIBusAddress{bus,device, function};
 | 
			
		||||
 | 
			
		||||
    uint8_t ProgIF = GetProgIF(IDEControllerPCIAddress);
 | 
			
		||||
    uint8_t ProgIF = PCI::GetProgIF(IDEControllerPCIAddress);
 | 
			
		||||
    printf( "ProgIF: 0x%x\n" ,ProgIF);
 | 
			
		||||
 | 
			
		||||
    //CheckProgIF(ProgIF);
 | 
			
		||||
@ -66,15 +66,15 @@ inline void TestIDEController(){
 | 
			
		||||
 | 
			
		||||
    uint32_t BAR0,BAR1,BAR2,BAR3, BAR4;
 | 
			
		||||
 | 
			
		||||
    BAR0 = ReadBAR(IDEControllerPCIAddress, 0); 
 | 
			
		||||
    BAR0 = PCI::ReadBAR(IDEControllerPCIAddress, 0);
 | 
			
		||||
 | 
			
		||||
    BAR1 = ReadBAR(IDEControllerPCIAddress, 1);
 | 
			
		||||
    BAR1 = PCI::ReadBAR(IDEControllerPCIAddress, 1);
 | 
			
		||||
 | 
			
		||||
    BAR2 = ReadBAR(IDEControllerPCIAddress, 2);
 | 
			
		||||
    BAR2 = PCI::ReadBAR(IDEControllerPCIAddress, 2);
 | 
			
		||||
 | 
			
		||||
    BAR3 = ReadBAR(IDEControllerPCIAddress, 3);
 | 
			
		||||
    BAR3 = PCI::ReadBAR(IDEControllerPCIAddress, 3);
 | 
			
		||||
 | 
			
		||||
    BAR4 = ReadBAR(IDEControllerPCIAddress, 4);
 | 
			
		||||
    BAR4 = PCI::ReadBAR(IDEControllerPCIAddress, 4);
 | 
			
		||||
 | 
			
		||||
    // All bars are return 0xffffff for some as of yet mysterious reason!
 | 
			
		||||
    printf( "BAR 0: 0x%x\n", BAR0);
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h> 
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "../../terminal/kterm.h"
 | 
			
		||||
#include "sampleIDE.definitions.h"
 | 
			
		||||
#include "ideCommands.h"
 | 
			
		||||
@ -155,7 +155,7 @@ inline void init_IDE( uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 3- Detect ATA-ATAPI Devices:
 | 
			
		||||
void DetectDevices(){
 | 
			
		||||
inline void DetectDevices(){
 | 
			
		||||
   int i, j, k, count = 0;
 | 
			
		||||
 | 
			
		||||
   for (i = 0; i < 2; i++)
 | 
			
		||||
@ -228,7 +228,7 @@ void DetectDevices(){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){
 | 
			
		||||
inline void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){
 | 
			
		||||
    // 1 Detect I/O Ports which interface an IDE Controller
 | 
			
		||||
 | 
			
		||||
   // Based on the implementation within serenity
 | 
			
		||||
@ -239,4 +239,20 @@ void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3,
 | 
			
		||||
    channels[ATA_PRIMARY  ].bmide = (BAR4 & (~1)) + 0; // Bus Master IDE
 | 
			
		||||
    channels[ATA_SECONDARY].bmide = (BAR4 & (~1)) + 8; // Bus Master IDE
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool driveAvailable(){
 | 
			
		||||
    int devNumber = 0;
 | 
			
		||||
    for ( auto device : ide_devices){
 | 
			
		||||
        if(!device.Reserved)
 | 
			
		||||
            continue;
 | 
			
		||||
        devNumber++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // FIXME: If no drive is connected we continue trying to read from
 | 
			
		||||
    // a not connected drive!
 | 
			
		||||
    //ATAPIO::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								kernel/storage/partitions/partitionManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								kernel/storage/partitions/partitionManager.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 23/02/23.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "partitionManager.h"
 | 
			
		||||
 | 
			
		||||
bool partitionManager::Validate( )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    //auto* bootParams = getBPB(this, true);
 | 
			
		||||
 | 
			
		||||
    //if(bootParams->OEM_id) {
 | 
			
		||||
    //    return true;
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								kernel/storage/partitions/partitionManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								kernel/storage/partitions/partitionManager.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by nigel on 23/02/23.
 | 
			
		||||
//
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
class partitionManager {
 | 
			
		||||
public:
 | 
			
		||||
    static bool Validate();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								kernel/storage/partitiontables/mbr/MasterBootRecord.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								kernel/storage/partitiontables/mbr/MasterBootRecord.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint-gcc.h>
 | 
			
		||||
#include "PartitionTableEntry.h"
 | 
			
		||||
#include "../../../memory/KernelHeap.h"
 | 
			
		||||
#include "../../ata pio/ATAPIO.h"
 | 
			
		||||
 | 
			
		||||
struct MBR {
 | 
			
		||||
    uint8_t code [440];
 | 
			
		||||
    uint32_t uniqueID;
 | 
			
		||||
    uint16_t Reserved;
 | 
			
		||||
    struct PartitionTableEntry TableEntries[4];
 | 
			
		||||
    uint16_t ValidBootsector;
 | 
			
		||||
}__attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline MBR* GetPartitions(bool DEBUG = false){
 | 
			
		||||
    const int C = 0;
 | 
			
		||||
    const int H = 0;
 | 
			
		||||
    const int HPC = 16;
 | 
			
		||||
    const int SPT = 63;
 | 
			
		||||
 | 
			
		||||
    int S =1;
 | 
			
		||||
    uint32_t LBA = (C*HPC+H) * SPT + (S-1);
 | 
			
		||||
 | 
			
		||||
    uint16_t* mbr =(uint16_t*) malloc(sizeof (MBR));
 | 
			
		||||
 | 
			
		||||
    ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, LBA,  mbr );
 | 
			
		||||
    auto bootRecord = (MBR*)(mbr);
 | 
			
		||||
 | 
			
		||||
    printf("MBR (In Memory) Address 0x%x, Size = %d\n", bootRecord, sizeof (MBR));
 | 
			
		||||
    if(DEBUG){
 | 
			
		||||
        printf("BootSector: 0x%x\n", bootRecord->ValidBootsector );
 | 
			
		||||
        for( int i = 0 ; i < 4 ; i ++){
 | 
			
		||||
            PartitionTableEntry PT = bootRecord->TableEntries[i];
 | 
			
		||||
 | 
			
		||||
            printf("Partition %d [  %d sectors,  PartitionType: 0x%x, 0x%x, \nLBA Start: 0x%x ]\n" ,
 | 
			
		||||
                   i, PT.Number_sectors_inPartition, PT.PartitionType, bootRecord->uniqueID,  PT.LBA_partition_start );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return bootRecord;
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user