Compare commits

4 Commits

87 changed files with 1380 additions and 3071 deletions

View File

@ -5,27 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
CFLAGS = -ffreestanding -O2 -Wall -Wextra
OFILES = \
$(BUILD_DIR)/boot.o \
$(BUILD_DIR)/kterm.o \
$(BUILD_DIR)/kernel.o \
$(BUILD_DIR)/memory.o \
$(BUILD_DIR)/io.o \
$(BUILD_DIR)/gdtc.o \
$(BUILD_DIR)/idt.o \
$(BUILD_DIR)/pci.o \
$(BUILD_DIR)/pic.o \
$(BUILD_DIR)/string.o \
$(BUILD_DIR)/pcidevice.o \
$(BUILD_DIR)/atapiDevice.o \
$(BUILD_DIR)/ataDevice.o \
$(BUILD_DIR)/rsdp.o \
$(BUILD_DIR)/pit.o \
$(BUILD_DIR)/time.o \
$(BUILD_DIR)/keyboard.o \
$(BUILD_DIR)/sv-terminal.o \
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/window.o $(BUILD_DIR)/cursor.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/vesa.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
SRC_DIR = src
BUILD_DIR = build
@ -43,6 +23,8 @@ 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
@ -52,14 +34,11 @@ iso: clean_iso clean build
cp build/myos.bin root/boot/myos.bin
cp src/grub.cfg root/boot/grub/grub.cfg
grub-mkrescue -o build/barinkOS.iso root
run: all
virtualboxvm --startvm "BarinkOS_test"
test:
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo # -monitor stdio
test_iso:
$(EMULATOR) -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo
$(EMULATOR) -cdrom build/barinkOS.iso -serial mon: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 \
@ -73,13 +52,13 @@ clean:
rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
$(BUILD_DIR)/kernel.o:
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti -fpermissive
$(BUILD_DIR)/kterm.o:
$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/boot.o:
$(AS) $(SRC_DIR)/kernel/boot.s -o $(BUILD_DIR)/boot.o
$(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o
$(BUILD_DIR)/crti.o:
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
@ -88,8 +67,10 @@ $(BUILD_DIR)/crtn.o:
$(AS) $(SRC_DIR)/kernel/crtn.s -o $(BUILD_DIR)/crtn.o
$(BUILD_DIR)/io.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/IO/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/PageDirectory.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/idt.o:
$(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -107,35 +88,11 @@ $(BUILD_DIR)/string.o:
$(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/IO/PCI/pci.cpp -o $(BUILD_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/vesa.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/vesa/vesa.cpp -o $(BUILD_DIR)/vesa.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/pcidevice.o:
$(CPP) -c $(SRC_DIR)/kernel/pci/pciDevice.cpp -o $(BUILD_DIR)/pcidevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/window.o:
$(CPP) -c $(SRC_DIR)/gui/window.cpp -o $(BUILD_DIR)/window.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/atapiDevice.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/IO/atapi/atapiDevice.cpp -o $(BUILD_DIR)/atapiDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/ataDevice.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/IO/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/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/keyboard.o:
$(CPP) -c $(SRC_DIR)/kernel/keyboard/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/sv-terminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/memory.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/memory.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/cursor.o:
$(CPP) -c $(SRC_DIR)/gui/cursor.cpp -o $(BUILD_DIR)/cursor.o $(CFLAGS) -fno-exceptions -fno-rtti

View File

@ -6,6 +6,9 @@
________________________
### Screenshot(s)
![Graphics mode](screenshots/BarinkOS_VBE_GRAPHICS.png) \
It may not look like much but I am proud of it! We are in graphics mode.
![Scrolling the terminal](screenshots/Screenshot1.png) \
The first scrolling boot screen. 😲
@ -16,21 +19,10 @@ W.I.P - Working on interrupt handling
![Multiboot integration](screenshots/multiboot.png) \
Multiboot information can be read by the kernel.
![PCI enumeration](screenshots/PCIBusEnumeration.png) \
Enumerating the PCI bus
![ATAPI CD-ROM Identification](screenshots/CD-ROM_Identify.png) \
Correctly identified our ATAPI device 🎉
![Reading Files from FAT-16](screenshots/ReadingFilesFromFAT16.png) \
Reading a file from a FAT-16 Formatted drive
________________________
### The goal
Writing a hobby operating system to better understand the basic building blocks of any operating system.Initially I'd like for my
operating system to be able to run bash.
Writing a hobby operating system to better understand the basic building blocks of any operating system.
________________________
### Operating System Technical specs/details

View File

@ -1,38 +1,29 @@
# TODO list
## Basics
## Start planning
<input type="checkbox" checked/> Setup Cross-Compiler \
<input type="checkbox" checked/> Multiboot to kernel \
<input type="checkbox" checked/> Printing string to the screen \
<input type="checkbox" checked/> Printing values/numbers to the screen \
<input type="checkbox" checked/> Basic Terminal \
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
<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/> Time measurement (PIC &| PIT) \
<input type="checkbox" /> Time measurement (PIC &| PIT) \
<input type="checkbox" /> Detect CPU speed \
<input type="checkbox" checked/> Interrupt / exception system (API) \
<input type="checkbox" checked/> PCI support \
<input type="checkbox" checked/> ATA PIO Mode support \
<input type="checkbox" checked/> FAT Filesystem \
<input type="checkbox" /> Virtual filesystem \
<input type="checkbox" checked/> Keyboard support ( P/S2 Keyboard) \
<input type="checkbox" checked/> Physical memory management \
<input type="checkbox" /> Paging \
<input type="checkbox" /> Virtual memory management \
<input type="checkbox" checked/> Plan your memory map (virtual, and physical) : decide where you want the data to be. \
<input type="checkbox" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
<input type="checkbox" /> Enable SIMD Extensions (SSE)
## Other features I am thinking of:
<input type="checkbox" checked/> PCI support \
<input type="checkbox" /> PCI support \
<input type="checkbox" /> ATA PIO Mode support \
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
<input type="checkbox" /> ATAPI support \
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
<input type="checkbox" checked/> Memory Management (MMU)
<input type="checkbox" /> Hardware Management system
<input type="checkbox" /> Preemptive multi tasking \
<input type="checkbox" /> Processes \
<input type="checkbox" /> Threads
@ -41,11 +32,9 @@
<input type="checkbox" /> POSIX compliance (partially) \
<input type="checkbox" /> RPC - for interprocess communication \
<input type="checkbox" /> Sync primitives - Semaphores, Mutexes, spinlocks et al. \
<input type="checkbox" /> ACPI support \
<input type="checkbox" /> ATAPI support \
## Optional
<input type="checkbox" /> Basic Terminal \
<input type="checkbox" /> Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \
<input type="checkbox" /> Basic Window server/client \
## Support for more filesystems if I like the challenge in writing these ...
<input type="checkbox" /> FAT Filesystem \
<input type="checkbox" /> EXT2 Filesystem
<input type="checkbox" /> USTAR Filesystem \

BIN
screenshots/BarinkOS_VBE_GRAPHICS.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
screenshots/CD-ROM_Identify.png (Stored with Git LFS)

Binary file not shown.

BIN
screenshots/PCIBusEnumeration.png (Stored with Git LFS)

Binary file not shown.

BIN
screenshots/ReadingFilesFromFAT16.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,8 +1,3 @@
GRUB_DEFAULT=0
GRUB_TIMEOUT=-1
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUITE=true
menuentry "BarinkOS" {
menuentry "BarinkOS"{
multiboot /boot/myos.bin
}

5
src/gui/Graphics.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
class Graphics {
};

7
src/gui/Widget.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
class Widget{
virtual void draw();
};

17
src/gui/cursor.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "cursor.h"
void Cursor::draw(){
for(int i = 0; i < this->width; i++){
for(int j = 0; j < this->height; j++){
if(this->bitmap[j * this->width + i] == 1 ){
putPixel(i + this->x,j + this->y, 0xFF000000);
}
}
}
}
Cursor::Cursor(int x, int y){
this->x = x;
this->y = y;
}

38
src/gui/cursor.h Normal file
View File

@ -0,0 +1,38 @@
#pragma once
#include "../kernel/drivers/vesa/vesa.h"
class Cursor{
public:
void draw();
Cursor(int x, int y);
private:
int x;
int y;
const int width= 16;
const int height= 10;
const int bitmap [160] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
};

33
src/gui/window.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "window.h"
int Window::getWidth(){
return this->rect.width;
}
int Window::getHeight(){
return this->rect.height;
}
void Window::setWidth(int& width){
this->rect.width = width;
}
void Window::setHeight(int& height){
this->rect.height = height;
}
int Window::getX(){
return this->rect.x;
}
int Window::getY(){
return this->rect.y;
}
Window::Window (Rect& rect , uint32_t colour){
this->rect = rect;
this->Background_colour = colour;
}
void Window::draw(){
drawRect(this->getX() , this->getY() , this->getWidth() , this->getHeight() ,this->Background_colour );
}

37
src/gui/window.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include "../kernel/drivers/vesa/vesa.h"
#include "Widget.h"
struct Rect {
int width;
int height;
int x;
int y;
};
class Window : Widget{
public:
int getX();
int getY();
int getWidth();
int getHeight();
void setWidth(int&);
void setHeight(int&);
Window (Rect& rect , uint32_t colour);
void draw();
private:
Rect rect;
uint32_t Background_colour;
};

View File

@ -1,11 +0,0 @@
#pragma once
#include <stdint.h>
#include "PartitionTableEntry.h"
struct MBR {
uint8_t code [440];
uint32_t uniqueID;
uint16_t Reserved;
PartitionTableEntry TableEntries[4];
uint16_t ValidBootsector;
}__attribute__((packed));

View File

@ -1,11 +0,0 @@
#pragma once
#include <stdint.h>
struct PartitionTableEntry{
uint8_t driveAttribute;
uint8_t CHS_start_address [3];
uint8_t PartitionType;
uint8_t CHS_lastSector_Address[3];
uint32_t LBA_partition_start;
uint32_t Number_sectors_inPartition;
}__attribute__((packed));

87
src/kernel/boot.S Normal file
View File

@ -0,0 +1,87 @@
/*
* Multiboot
*/
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
.set MEMINFO, 1<<1 /* provide memory map */
.set VIDEO, 1<<2 /* provide video mode */
.set FLAGS, ALIGN | MEMINFO | VIDEO /* this is the Multiboot 'flag' field */
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.long 0 # unused
.long 0 # .
.long 0 # .
.long 0 # .
.long 0 # unused
.long 0 # set graphics mode
.long 800 # screen witdh
.long 600 # screen height
.long 32 # bpp
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .text
.include "./src/kernel/irs_table.s"
.include "./src/kernel/irq_table.s"
.include "./src/kernel/idt/idt.s"
.include "./src/kernel/paging.s"
.global _start
.type _start, @function
_start:
/*Setup the stack pointer to point to the beginning of our stack */
/* I believe its a high address growing down to lower adress for the stack on x86*/
mov $stack_top, %esp
/*Reset EFLAGS*/
pushl $0
popf
/* push the pointer to the Multiboot information structure*/
pushl %ebx
/* push the magic value */
pushl %eax
call early_main
cli
.include "./src/kernel/gdt/gdt.s"
loadIDT:
#load idt
call init_idt
sti
# Try enable A20
# mov $0x2401, %ax
# int $0x15
# enable protected mode
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
call kernel_main
cli
1: hlt
jmp 1b
.size _start, . - _start

View File

@ -1,66 +0,0 @@
/*
* Multiboot
*/
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
.set MEMINFO, 1<<1 /* provide memory map */
.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .text
.include "./src/kernel/gdt/gdt.s"
.include "./src/kernel/irs_table.s"
.include "./src/kernel/irq_table.s"
.include "./src/kernel/idt/idt.s"
.include "./src/kernel/memory/paging.s"
.global _start
.type _start, @function
_start:
/*Setup the stack pointer to point to the beginning of our stack */
/* I believe its a high address growing down to lower adress for the stack on x86*/
mov $stack_top, %esp
/*Reset EFLAGS*/
pushl $0
popf
/* push the pointer to the Multiboot information structure*/
pushl %ebx
/* push the magic value */
pushl %eax
call early_main
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
call kernel_main
cli
1: hlt
jmp 1b
.size _start, . - _start

View File

@ -1,91 +1,108 @@
#pragma once
#include "bootloader/multiboot.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
#include "../gui/window.h"
#include "../gui/cursor.h"
#include "tty/kterm.h"
#include "drivers/vesa/vesa.h"
void CheckMBT ( multiboot_info_t* mbt ){
/* Set MBI to the addresss of the multiboot information structure*/
multiboot_info_t * mbi = (multiboot_info_t *) mbt;
/* Set MBI to the addresss of the multiboot information structure*/
multiboot_info_t * mbi = (multiboot_info_t *) mbt;
#ifdef __VERBOSE__
/* Print out the flags */
printf("flags = 0x%x\n", (unsigned) mbi->flags);
#endif
/* Are mem_* valid? */
if ( CHECK_FLAG(mbi->flags,0)){
// Do nothing
}
/* Print out the flags */
printf("flags = 0x%8x\n", (unsigned) mbi->flags);
/* is boot device valid ? */
if (CHECK_FLAG (mbi->flags, 1))
{
#ifdef __VERBOSE__
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
#endif
}
/* Are mem_* valid? */
if ( CHECK_FLAG(mbi->flags,0)){
printf("mem_lower = %uKB, mem_upper = %uKB\n");
}
/* is the command line passed? */
if (CHECK_FLAG ( mbi->flags,2))
{
#ifdef __VERBOSE__
printf("cmdline = %s\n", (char *) mbi->cmdline);
#endif
}
/* is boot device valid ? */
if (CHECK_FLAG (mbi->flags, 1)){
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
}
/* Are mods_* valid? */
if(CHECK_FLAG ( mbi->flags, 3)){
multiboot_module_t *mod;
uint32_t i;
#ifdef __VERBOSE__
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
/* is the command line passed? */
if (CHECK_FLAG ( mbi->flags,2)){
printf("cmdline = %s\n", (char *) mbi->cmdline);
}
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
}
#endif
}
/* Are mods_* valid? */
if(CHECK_FLAG ( mbi->flags, 3)){
multiboot_module_t *mod;
uint32_t i;
/* Bits 4 and 5 are mutually exclusive! */
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5))
{
#ifdef __VERBOSE__
printf("Both bits 4 and 5 are set.\n");
#endif
return;
}
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
/* Is the symbol table of a.out valid? */
if (CHECK_FLAG(mbi->flags, 4)){
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
#ifdef __VERBOSE__
printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n",
(unsigned) multiboot_aout_sym->tabsize,
(unsigned) multiboot_aout_sym->strsize,
(unsigned) multiboot_aout_sym->addr);
#endif
}
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
}
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG(mbi->flags, 5)){
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
#ifdef __VERBOSE__
printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
/* Bits 4 and 5 are mutually exclusive! */
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){
printf("Both bits 4 and 5 are set.\n");
return;
}
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
#endif
/* Is the symbol table of a.out valid? */
if (CHECK_FLAG(mbi->flags, 4)){
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
}
printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n",
(unsigned) multiboot_aout_sym->tabsize,
(unsigned) multiboot_aout_sym->strsize,
(unsigned) multiboot_aout_sym->addr);
/* Draw diagonal blue line */
if (CHECK_FLAG (mbt->flags, 12)){
#ifdef __VERBOSE__
printf("Can draw!\n");
#endif
}
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG(mbi->flags, 5)){
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
}
/* Draw diagonal blue line */
if (CHECK_FLAG (mbt->flags, 11)){
printf("Can draw!");
// Init vesa driver
initVBEDevice(mbt);
// Fill screen with blue
// colours AARRGGBB
drawRect(0, 0 , VbeModeInfo->width,VbeModeInfo->height, 0xFF0000FF);
// Create two windows
Rect rect_window1 {};
Rect rect_window2 {};
rect_window1.height =200;
rect_window1.width = 300;
rect_window1.x = 50;
rect_window1.y = 50;
rect_window2.height =200;
rect_window2.width = 300;
rect_window2.x = 300;
rect_window2.y = 200;
Window window_1 ( rect_window1, 0xFF00F0FF);
Window window_2 (rect_window2, 0xFFAACCDD);
window_1.draw();
window_2.draw();
Cursor cursor (70,100);
cursor.draw();
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include "memory/memoryinfo.h"
struct BootInfo{
const char* BootStructureID = "BarinkOS";
MemoryInfo* memory;
};

View File

@ -1,11 +0,0 @@
#pragma once
/**
* Kernel definitions
*/
#define __DEBUG__ false
#define KERNEL_VERSION 0
#define ARCHITECTURE "I386"

17
src/kernel/disk.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a
// storage device
// PRIMARY_ATA_BUS
// 0x1F0 through 0x1F7
// SECONDARY_ATA_BUS
// 0x170 through 0x177
#define DEVICE_CONTROL_REGISTER 0x3F6
#define DEVICE_CONTROL_ALTERNATE 0x376
// IRQ14 Primary bus interrupt
// IRQ15 Secondary bus interrupt

View File

@ -1,46 +0,0 @@
#include "rsdp.h"
void printRSD(RSDPTR* rsd){
printf("Signature: ");
for(int i = 0; i < 8; i++){
kterm_put(rsd->signature[i]);
}
kterm_put('\n');
printf("OEMID: ");
for(int i =0; i < 6 ; i++){
kterm_put (rsd->OEMID[i]);
}
kterm_put('\n');
printf("Revision: %d\n", rsd->Revision);
printf("RSDT Address: 0x%x\n", rsd->RsdtAddress );
}
RSDPTR* 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);
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]);
}
kterm_put('\n');
return rsdt;
}

View File

@ -1,36 +0,0 @@
#pragma once
#include <stdint.h>
#include "./../../tty/kterm.h"
#include "../../../libc/include/mem.h"
struct RSDPTR {
char signature[8];
uint8_t Checksum ;
char OEMID [6];
uint8_t Revision;
uint32_t RsdtAddress;
}__attribute__((packed));
struct ACPISDTHeader{
char Signature[4];
uint32_t Length;
uint8_t CheckSum;
char OEMID[6];
char OEMTableID[8];
uint32_t OEMRevision;
uint32_t CreatorID;
uint32_t CreatorRevision;
}__attribute__((packed));
struct RSDT{
struct ACPISDTHeader header;
uint32_t PointerToSDT[]; // Length of array : (header.Length - sizeof(header))/ 4
}__attribute__((packed));
//NOTE: only scans EBDA enough to find RSD PTR in QEMU
RSDPTR* FindRSD();
void printRSD(RSDPTR* rsd);
RSDT* getRSDT(RSDPTR* rsd);

View File

@ -1,247 +0,0 @@
#include "pci.h"
#define PCI_BUS_ADDR_SHIFT 16
#define PCI_DEVICE_ADDR_SHIFT 11
#define PCI_FUNCTION_ADDR_SHIFT 8
#define PCI_ENABLE_ADDR_SHIFT 31
const char* GetClassCodeName (uint64_t ClassCode ) {
switch (ClassCode)
{
case 0x0 :
return "Unclassified";
break;
case 0x1:
return "Mass Storage Controller";
break;
case 0x2:
return "Network Controller";
break;
case 0x3:
return "Display Controller";
break;
case 0x4:
return "Multimedia Controller";
break;
case 0x5:
return "Memory Controller";
break;
case 0x6:
return "Bridge";
break;
case 0x7 :
return "Simple Communication Controller";
break;
case 0x8:
return "Base System Peripheral";
break;
case 0x9:
return "Input Device Controller";
break;
case 0xA:
return "Docking station";
break;
case 0xB:
return "Processor";
break;
case 0xC:
return "Serial Bus Controller";
break;
case 0xD:
return "Wireless Controller";
break;
case 0xE:
return "Intelligent Controller";
break;
case 0xF:
return "Satellite Communication Controller";
break;
case 0x10:
return "Encryption Controller";
break;
case 0x11:
return "Signal Processing Controller";
break;
case 0x12:
return "Processing Accelerator";
break;
case 0x13:
return "Non-Essential Instrumentation";
break;
default:
return "Unknown";
break;
}
}
const char* 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;
default:
return "Vendor Unkown";
break;
}
}
uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset){
outl(CONFIG_ADDRESS , PCIDeviceAddress.getAddress() | offset );
return inl(CONFIG_DATA);
}
uint32_t 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 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!
}
uint16_t GetClassCodes( PCIBusAddress& PCIDeviceAddress ){
uint32_t classcodes = ConfigReadWord(PCIDeviceAddress, 0x8);
return (uint16_t)((uint32_t)classcodes >> 16);
}
bool IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress){
uint32_t header_information = ConfigReadWord(PCIDeviceAddress, 0xC);
return (((header_information>>16)
& 0x80)
>> 7 );
}
void PrintPCIDeviceInfo (PCIBusAddress& PCIDeviceAddress)
{
uint32_t DeviceID = (GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) >> 16);
uint32_t VendorID = 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
, getVendor(VendorID) );
uint8_t header_type = GetHeaderType(PCIDeviceAddress);
printf( "Header type: 0x%x\n", header_type);
uint16_t deviceClasses = GetClassCodes(PCIDeviceAddress);
printf("class: %s, subClass: %d\n\n", GetClassCodeName((deviceClasses >>8)), deviceClasses & 0xFF);
}
void PCI_Enumerate(){
int devicesFound = 0;
// 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 = ConfigReadWord(bus, device, function,0x0);
uint32_t DeviceID = GetDevice(bus, device, function) >> 16;
if( DeviceID != 0xFFFF){
PCIBusAddress busAddress =
PCIBusAddress{bus, device, function };
PrintPCIDeviceInfo(busAddress);
// iterate over the functions if it is a multi function device!
if( 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};
PrintPCIDeviceInfo(busAddress2);
devicesFound++;
}
}
}
devicesFound++;
}
}
}
printf("Found %d PCI devices!\n", devicesFound);
}
uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress){
uint32_t data = ConfigReadWord(PCIDeviceAddress, 0x8);
return ((data >> 8) & 0xFF);
}
uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number){
int offsetToBar = 0x10 + (bar_number* 0x4);
return ConfigReadWord(PCIDeviceAddress, offsetToBar);
}

View File

@ -1,38 +0,0 @@
#pragma once
#include <stdint.h>
#include "../io.h"
#include "../../../tty/kterm.h"
#include "../../../pci/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
extern const char* ClassCodeTable [0x13];
// Note: this could be used to make the api for receiving PCI class codes a bit
// nicer.
struct ClassCodes {
uint8_t ClassCode;
uint8_t DeviceClass;
}__attribute__((packed));
uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset);
uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset);
inline uint64_t GetDevice (int bus, int device, int function ){
return ConfigReadWord(bus, device, function,0x0);
}
uint8_t GetHeaderType( PCIBusAddress& PCIDeviceAddress );
uint16_t GetClassCodes( PCIBusAddress& PICDeviceAddress );
const char* getVendor( uint64_t VendorID);
const char* GetClassCodeName (uint64_t ClassCode );
uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress);
void PCI_Enumerate();
uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number);

View File

@ -1,194 +0,0 @@
#include "ataDevice.h"
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
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);
}
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) {
/*
Assume you have a sectorcount byte and a 28 bit LBA value. A sectorcount of 0 means 256 sectors = 128K.
Notes: - When you send a command byte and the RDY bit of the Status Registers is clear, you may have to wait (technically up to 30 seconds) for the drive to spin up, before DRQ sets. You may also need to ignore ERR and DF the first four times that you read the Status, if you are polling.
- for polling PIO drivers: After transferring the last uint16_t of a PIO data block to the data IO port, give the drive a 400ns delay to reset its DRQ bit (and possibly set BSY again, while emptying/filling its buffer to/from the drive).
- on the "magic bits" sent to port 0x1f6: Bit 6 (value = 0x40) is the LBA bit. This must be set for either LBA28 or LBA48 transfers. It must be clear for CHS transfers. Bits 7 and 5 are obsolete for current ATA drives, but must be set for backwards compatibility with very old (ATA1) drives.
An example of a 28 bit LBA PIO mode read on the Primary bus:
*/
const int sectorCount = 1;
// Floating bus check
uint8_t floatingBus = inb(DEVICE_CHANNEL | 7);
if (floatingBus == 0xFF){
printf("Floating bus!!");
return ;
}
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)
outb(DEVICE_CHANNEL | 1, 0x0000 );
//Send the sectorcount to port 0x1F2: outb(0x1F2, (unsigned char) count)
outb(DEVICE_CHANNEL | 2, sectorCount);
//Send the low 8 bits of the LBA to port 0x1F3: outb(0x1F3, (unsigned char) LBA))
outb(DEVICE_CHANNEL | 3, LBA);
//Send the next 8 bits of the LBA to port 0x1F4: outb(0x1F4, (unsigned char)(LBA >> 8))
outb(DEVICE_CHANNEL | 4, (LBA >> 8));
//Send the next 8 bits of the LBA to port 0x1F5: outb(0x1F5, (unsigned char)(LBA >> 16))
outb(DEVICE_CHANNEL | 5, (LBA >> 16));
//Send the "READ SECTORS" command (0x20) to port 0x1F7: outb(0x1F7, 0x20)
outb(DEVICE_CHANNEL | 7, 0x20);
volatile int i,j;
for(i=0;i<2000;i++)
for(j=0;j<25000;j++)
asm("NOP");
//Wait for an IRQ or poll.
uint8_t status = inb(DEVICE_CHANNEL | 7);
if( status == 0x00){
printf("No drive\n");
return;
}
printf("Status: %x\n", status);
// Check if busy!
while((status & 0x80) == 0x80){
printf("Reading....\r");
status = inb(DEVICE_CHANNEL | 7);
}
if ((status & 0x01) == 0x01){
printf("Error occured during read!\n");
return;
}
//Transfer 256 16-bit values, a uint16_t at a time, into your buffer from I/O port 0x1F0.
if( status & 0x01){
printf("Error!\n");
printf("Status: 0x%x\n", status);
uint16_t error_register = inb(DEVICE_CHANNEL | 1);
printf("Error register 0x%x\n",error_register );
return ;
}
for ( int i = 0; i < 256; i++){
uint16_t data;
asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
// printf (" %x ", data);
buffer[i] = data;
}
//Then loop back to waiting for the next IRQ (or poll again -- see next note) for each successive sector.
}
void ATA_DEVICE::Write(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
printf("Not implemented\n");
}

View File

@ -1,31 +0,0 @@
#pragma once
#include <stdint.h>
#include "../io.h"
#include "../../../ide/ideCommands.h"
#include "../../../ide/sampleIDE.definitions.h"
#include "../../../tty/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
};
namespace ATA_DEVICE{
void Identify(uint16_t, DEVICE_DRIVE);
void Read (uint16_t, DEVICE_DRIVE, uint32_t, uint16_t*);
void Write(uint16_t, DEVICE_DRIVE);
void Soft_Reset(uint8_t ,DEVICE_DRIVE );
};

View File

@ -1,145 +0,0 @@
#include "atapiDevice.h"
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
bool isPacketDevice(){
uint8_t LBAmid = inb(0x174);
uint8_t LBAhi = inb(0x175);
printf(" LBAmid: 0x%x, LBAhi: 0x%x");
return LBAmid == 0x14 && LBAhi == 0xEB;
}
void ATAPI_DEVICE::Identify(uint8_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
*/
// Select the target drive
outb(0x176, 0xA0); // on the secondary bus select the master drive
outb(0x170 + 0x206 , 0x0); // write 0 to the controlport for some reason
outb(0x176, 0xA0);
// read the status port
uint8_t status = inb(0x177);
printf("status after drive select: 0x%x\n",status);
if( status == 0x00){
printf("No drive\n");
return;
}
outb(0x176, 0xA0);
// Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
outb(0x172, 0);
outb(0x173, 0);
outb(0x174, 0);
outb(0x175, 0);
// send the identify command;
printf("command sent!\n");
outb(0x177, 0xA1);
// read the status port
uint8_t status2 = inb(0x177);
if( status2 == 0x00){
printf("No drive\n");
return;
}
printf("Waiting until ready...\n");
while(((status2 & 0x80 == 0x80)
&& (status2 & 0x01) != 0x01)
) status2 = inb(0x177);
if(status2 & 0x01){
printf("Error!");
return;
}
// READ DATA
uint16_t deviceIdentify [256] ={0};
for (int i= 0; i < 256; i++){
uint16_t data;
asm volatile ( "in %1, %0"
: "=a"(data)
: "Nd"(0x170) );
deviceIdentify[i] = data ;
}
printf("Model-label (ASCII hex):\n");
for(int i = 27; i < 47; i++){
printf(" %x ",deviceIdentify[i]);
}
printf("\nSerial number (ASCII hex):\n");
for (int i = 10; i < 19; i++){
printf(" %x ", deviceIdentify[i]);
}
printf("\nFirmware revision (ASCII hex):\n");
for (int i = 23; i < 26; i++){
printf(" %x ", deviceIdentify[i]);
}
printf("\nConfiguration: %x\n", deviceIdentify[0]);
printf("\nData received!\n");
}
void ATAPI_DEVICE::Read(uint8_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
printf("Not implemented");
}
void ATAPI_DEVICE::Write(uint8_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
printf("Not implemented");
}

View File

@ -1,29 +0,0 @@
#pragma once
#include <stdint.h>
#include "../io.h"
#include "../../../ide/ideCommands.h"
#include "../../../ide/sampleIDE.definitions.h"
#include "../../../tty/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
};
namespace ATAPI_DEVICE
{
bool isPacketDevice();
void Identify ( uint8_t, DEVICE_DRIVE );
void Read ( uint8_t, DEVICE_DRIVE );
void Write ( uint8_t, DEVICE_DRIVE );
};

View File

@ -1,38 +0,0 @@
void ReadFromCMOS(unsigned char array[])
{
unsigned char tvalue, index;
for (index = 0; index < 128; index++)
{
asm(
"cli\n\t" // Disable interrupts
"mov al, index\n\t" // Move index address
// since the 0x80 bit of al is not set, NMI is active
"out 0x70,al\n\t" // Copy address to CMOS register
// some kind of real delay here is probably best
"in al,0x71\n\t" // Fetch 1 byte to al
"sti\n\t" // Enable interrupts
"mov tvalue,al\n\t");
array[index] = tvalue;
}
}
void WriteTOCMOS(unsigned char array[])
{
unsigned char index;
for(index = 0; index < 128; index++)
{
unsigned char tvalue = array[index];
asm("cli\n\t" // Clear interrupts
"mov al,index\n\t" // move index address
"out 0x70,al\n\t" // copy address to CMOS register
// some kind of real delay here is probably best
"mov al,tvalue\n\t" // move value to al
"out 0x71,al\n\t" // write 1 byte to CMOS
"sti\n\\t" ); // Enable interrupts
}
}

View File

@ -0,0 +1,136 @@
#include "vesa.h"
VbeInfoBlock* vbeInfo;
vbe_mode_info_structure* VbeModeInfo;
void initVBEDevice(multiboot_info_t* mbt){
print_serial("initVBEDevice");
vbeInfo = (VbeInfoBlock*) mbt->vbe_control_info;
printf_serial("Signature: %s, V0x%x\n", vbeInfo->VbeSignature, vbeInfo->VbeVersion);
VbeModeInfo = (vbe_mode_info_structure*) mbt->vbe_mode_info;
printf_serial("VESA video mode info: Width: %d Height: %d BPP: %d\n", VbeModeInfo->width, VbeModeInfo->height , VbeModeInfo->bpp);
printf_serial("VideoMemory Location: 0x%x \n", VbeModeInfo->framebuffer );
}
void putPixel( int x, int y , uint32_t colour){
// printf_serial("putPixel x: %d, y: %d\n", x, y);
///fb + mbt->framebuffer_pitch * y + 4 * x ,NOTE: this calculation is very important
*(uint32_t*) ( VbeModeInfo->framebuffer + VbeModeInfo->pitch * y + 4 * x ) = colour;
}
void drawLine(int x1, int y1, int x2, int y2, uint32_t colour ){
print_serial("drawline\n");
// See Bresenham's line algorithm
int deltaX = x2 - x1;
int deltaY = y2 - y1;
int D = 2 * deltaY - deltaX;
int y = y1;
for ( int x = x1; x < x2; x++){
putPixel(x,y, colour);
if( D > 0){
y +=1;
D = D - 2 * deltaX;
}
D = D + 2 * deltaY;
}
}
void drawRect ( int x, int y, int width, int height, uint32_t colour ){
print_serial("drawRect\n");
for ( int i = x; i < x + width; i ++)
{
for(int j = y; j < y + height; j++){
putPixel(i,j, colour);
}
}
}
void blueDiagnalLineTest(multiboot_info_t* mbt){
multiboot_uint32_t color;
unsigned i;
void *fb = (void *) (unsigned long) mbt->framebuffer_addr;
switch (mbt->framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
unsigned best_distance, distance;
struct multiboot_color *palette;
palette = (struct multiboot_color *) mbt->framebuffer_palette_addr;
color = 0;
best_distance = 4*256*256;
for (i = 0; i < mbt->framebuffer_palette_num_colors; i++)
{
distance = (0xff - palette[i].blue) * (0xff - palette[i].blue)
+ palette[i].red * palette[i].red
+ palette[i].green * palette[i].green;
if (distance < best_distance)
{
color = i;
best_distance = distance;
}
}
}
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
color = ((1 << mbt->framebuffer_blue_mask_size) - 1)
<< mbt->framebuffer_blue_field_position;
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
color = '\\' | 0x0100;
break;
default:
color = 0xffffffff;
break;
}
for (i = 0; i < mbt->framebuffer_width
&& i < mbt->framebuffer_height; i++)
{
switch (mbt->framebuffer_bpp)
{
case 8:
{
multiboot_uint8_t *pixel = (multiboot_uint8_t*)fb + mbt->framebuffer_pitch * i + i;
*pixel = color;
}
break;
case 15:
case 16:
{
multiboot_uint16_t *pixel
= (multiboot_uint16_t*)fb + mbt->framebuffer_pitch * i + 2 * i;
*pixel = color;
}
break;
case 24:
{
multiboot_uint32_t *pixel
= (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 3 * i;
*pixel = (color & 0xffffff) | (*pixel & 0xff000000);
}
break;
case 32:
{
multiboot_uint32_t *pixel
= (multiboot_uint32_t*)fb + mbt->framebuffer_pitch * i + 4 * i;
*pixel = color;
}
break;
}
}
}

View File

@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
#include "../../bootloader/multiboot.h"
#include "../../serial.h"
struct vbe_mode_info_structure{
uint16_t attributes;
uint8_t window_a;
uint8_t window_b;
uint16_t granularity;
uint16_t window_size;
uint16_t segment_a;
uint16_t segment_b;
uint32_t win_func_ptr;
uint16_t pitch;
uint16_t width;
uint16_t height;
uint8_t w_char;
uint8_t y_char;
uint8_t planes;
uint8_t bpp;
uint8_t banks;
uint8_t memory_model;
uint8_t bank_size;
uint8_t image_pages;
uint8_t reserved0;
uint8_t red_mask;
uint8_t red_position;
uint8_t green_mask;
uint8_t green_position;
uint8_t blue_mask;
uint8_t blue_position;
uint8_t reserved_mask;
uint8_t reserved_position;
uint8_t direct_color_attributes;
uint32_t framebuffer;
uint32_t off_screen_mem_off;
uint16_t off_screen_mem_size;
uint8_t reserved1[206];
}__attribute__((packed));
struct VbeInfoBlock {
char VbeSignature[4];
uint16_t VbeVersion;
uint16_t OemStringPtr;
uint8_t Capabilities;
uint16_t VideoModePtr;
uint16_t TotalMemory;
}__attribute__((packed));
extern VbeInfoBlock* vbeInfo;
extern vbe_mode_info_structure* VbeModeInfo;
void initVBEDevice(multiboot_info_t* mbt);
void blueDiagnalLineTest(multiboot_info_t* mbt);
// Primitive drawing functions
void putPixel( int x, int y , uint32_t colour);
void drawLine(int x1, int y1, int x2, int y2, uint32_t colour );
void drawRect ( int x, int y, int width, int height, uint32_t colour );

View File

@ -1,29 +0,0 @@
#pragma once
#include <stdint.h>
struct SuperBlock {
uint32_t NumberOfInodes;
uint32_t NumberOfBlocks;
uint32_t NumberOfReservedBlocks;
uint32_t NumberOfUnallocatedBlocks;
uint32_t NumberOfUnallocatedInodes;
uint32_t BlockNumberOfSuperBlock;
uint32_t BlockSize;// Something about a shift left
uint32_t FragmentSize;
uint32_t NumberOfBlocksInGroup;
uint32_t NumberOfFragmentsInBlockGroup;
uint32_t NumberOfInodesInBlockGroup;
uint32_t LastMountTime; // POSIX
uint32_t LastWrittenTime; // POSIX
uint16_t TimesMountedSinceCheck;
uint16_t TimesMountedUntilCheck;
uint16_t EXT_SIG ; // 0xef53
uint16_t FS_STATE;
uint16_t ON_ERR;
uint16_t VERSION_MINOR;
uint32_t TimeLastCheck; // POSIX
uint32_t CheckInterval; //POSIX
uint32_t OS_ID; // OS the FS was created with
uint32_t VERSION_MAJOR;
uint16_t UIDReservedBlocks;
uint16_t GIDReservedBlocks;
}__attribute__((packed));

View File

@ -1,21 +0,0 @@
#pragma once
#include <stdint.h>
#include "./ExtendBootRecord.h"
struct BiosParameterBlock {
uint8_t BootLoaderCodeSection [3];
uint8_t OEM_id [8];
uint16_t BytesPerSector ; // I suspect would be 512
uint8_t SectorsPerCluster ;
uint16_t ReservedSectors;
uint8_t NumberOfFileAllocationTables; // Probably equals 2
uint16_t NumberOfDirectoryEntries; // Root directory must contain entire sectors
uint16_t TotalSectorsInLogicalVolume ; // 0 means >65535 sectors in volume , actual count can be found in LargeSectorCount
uint8_t MediaDescriptor ; // Indication the media descriptor type
uint16_t NumberOfSectorsPerFAT;// only in FAT12 / FAT 16
uint16_t NumberOfSectorsPerTrack;
uint16_t NumberOfHeadsOnMedia;
uint32_t NumberOfHiddenSectors;
uint32_t LargeSectorCount;
ExtendedBootRecord_FAT16 ebpb;
}__attribute__((packed));

View File

@ -1,19 +0,0 @@
#pragma once
#include <stdint.h>
struct DirectoryEntry {
uint8_t filename [8];
uint8_t Extension [3];
uint8_t attribute;
uint8_t Reserved;
uint8_t creation;
uint16_t CreationTime;
uint16_t CreationDate;
uint16_t LastAccessDate;
uint16_t ReservedFAT32;
uint16_t LastWriteTime;
uint16_t LastWriteDate;
uint16_t StartingCluster;
uint32_t FilesizeInBytes;
}__attribute__((packed));

View File

@ -1,32 +0,0 @@
#pragma once
#include <stdint.h>
struct ExtendedBootRecord_FAT16{
uint8_t DriveNumber;
uint8_t Reserved;
uint8_t Signature;
const uint32_t VOLUME_ID_SERIAL_NUMBER;
uint8_t volume_label [11];
uint8_t Identifier_string [8];
uint8_t bootCode [448];
uint16_t partitionSignature;
}__attribute__((packed));
struct ExtendedBootRecord_FAT32{
uint32_t SectorsPerFAT;
uint16_t Flags;
const uint16_t FAT_VERSION_NUMBER;
uint32_t rootDirectory_clusterNumber;// Often set to 2;
uint16_t FSInfo_SectorNumber;
uint16_t backup_bpb_sectorNumber;
uint8_t Reserved [12];
uint8_t DriveNumber;
uint8_t Reserved2;
uint8_t Signature; // must be 0x28 or 0x29
uint32_t VOLUME_ID_SERIAL;
uint8_t volume_label[11];
uint8_t SystemIdentifierString [8]; // ALWAYS "FAT32 " but spec says do not trust
uint8_t BootCode [420]; // NICE
uint16_t PartitionSignature; // 0xAA55
}__attribute__((packed));

View File

@ -29,9 +29,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);
@ -51,8 +48,15 @@ void initGDT(){
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
printf("Hello GDT!\n");
LoadGlobalDescriptorTable();
// while (true)
// asm volatile("hlt");
}

View File

@ -1,97 +0,0 @@
#pragma once
#include <stdint.h>
#include "../pci/pciDevice.h"
#include "../tty/kterm.h"
#include "ideCommands.h"
#include "sampleIDE.h"
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
IDEChannelRegisters channels[2];
IDE_DEVICE ide_devices[4];
inline void CheckProgIF(uint8_t ProgIF){
if( IS_BIT_SET(ProgIF, 0) ) // Is the 0th bit set
{
printf ("Primary Channel is in PCI native mode\n");
} else{
printf("Primary Channel is in Compatibility mode\n");
}
if( IS_BIT_SET(ProgIF, 1)){
printf("Bit 0 can be modified\n");
}else{
printf("Bit 0 cannot be modified\n");
}
if( IS_BIT_SET(ProgIF, 2)){
printf("Secondary channel is in PCI native mode\n");
}else{
printf("Secondary channel is in Compatibility mode\n");
}
if( IS_BIT_SET(ProgIF, 3)){
printf("Bit 2 can be modified\n");
}else{
printf("Bit 2 cannot be modified\n");
}
if( IS_BIT_SET(ProgIF , 7)){
printf("This is a bus master IDE Controller\n");
} else{
printf("This controller doesn't support DMA!\n");
}
}
inline void TestIDEController(){
// Do stuff
printf("Testing IDE controllers\n");
// NOTE: Testing done with a hard coded known PCI addres
// Of an intel PIIX3 IDE Controller
int bus = 0;
int device =1 , function = 1;
PCIBusAddress IDEControllerPCIAddress = PCIBusAddress{bus,device, function};
uint8_t ProgIF = GetProgIF(IDEControllerPCIAddress);
printf( "ProgIF: 0x%x\n" ,ProgIF);
//CheckProgIF(ProgIF);
// For this test will just assume all bits are set
// the CheckProgIF can check but on the test machine all bits are set anyways
uint32_t BAR0,BAR1,BAR2,BAR3, BAR4;
BAR0 = ReadBAR(IDEControllerPCIAddress, 0);
BAR1 = ReadBAR(IDEControllerPCIAddress, 1);
BAR2 = ReadBAR(IDEControllerPCIAddress, 2);
BAR3 = ReadBAR(IDEControllerPCIAddress, 3);
BAR4 = ReadBAR(IDEControllerPCIAddress, 4);
// All bars are return 0xffffff for some as of yet mysterious reason!
printf( "BAR 0: 0x%x\n", BAR0);
printf( "BAR 1: 0x%x\n", BAR1);
printf( "BAR 2: 0x%x\n", BAR2);
printf( "BAR 3: 0x%x\n", BAR3);
printf( "BAR 4: 0x%x\n", BAR4);
init_IDE(BAR0, BAR1, BAR2, BAR3, BAR4);
// Read Something from disc
unsigned int maxByteCount = 20 ;
void* MDA_buffer = (void*)0xC0000000;
}

View File

@ -1,86 +0,0 @@
#pragma once
// Commands
#define ATA_CMD_READ_PIO 0x20
#define ATA_CMD_READ_PIO_EXT 0x24
#define ATA_CMD_READ_DMA 0xC8
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_PIO 0x30
#define ATA_CMD_WRITE_PIO_EXT 0x34
#define ATA_CMD_WRITE_DMA 0xCA
#define ATA_CMD_WRITE_DMA_EXT 0x35
#define ATA_CMD_CACHE_FLUSH 0xE7
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
#define ATA_CMD_PACKET 0xA0
#define ATA_CMD_IDENTIFY_PACKET 0xA1
#define ATA_CMD_IDENTIFY 0xEC
#define ATAPI_CMD_READ 0xA8
#define ATAPI_CMD_EJECT 0x1B
#define ATA_IDENT_DEVICETYPE 0
#define ATA_IDENT_CYLINDERS 2
#define ATA_IDENT_HEADS 6
#define ATA_IDENT_SECTORS 12
#define ATA_IDENT_SERIAL 20
#define ATA_IDENT_MODEL 54
#define ATA_IDENT_CAPABILITIES 98
#define ATA_IDENT_FIELDVALID 106
#define ATA_IDENT_MAX_LBA 120
#define ATA_IDENT_COMMANDSETS 164
#define ATA_IDENT_MAX_LBA_EXT 200
#define IDE_ATA 0x00
#define IDE_ATAPI 0x01
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
#define ATA_REG_DATA 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECCOUNT0 0x02
#define ATA_REG_LBA0 0x03
#define ATA_REG_LBA1 0x04
#define ATA_REG_LBA2 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
#define ATA_REG_SECCOUNT1 0x08
#define ATA_REG_LBA3 0x09
#define ATA_REG_LBA4 0x0A
#define ATA_REG_LBA5 0x0B
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ALTSTATUS 0x0C
#define ATA_REG_DEVADDRESS 0x0D
// Channels:
#define ATA_PRIMARY 0x00
#define ATA_SECONDARY 0x01
// Directions:
#define ATA_READ 0x00
#define ATA_WRITE 0x01
// Status
#define ATA_SR_BSY 0x80 // Busy
#define ATA_SR_DRDY 0x40 // Drive ready
#define ATA_SR_DF 0x20 // Drive write fault
#define ATA_SR_DSC 0x10 // Drive seek complete
#define ATA_SR_DRQ 0x08 // Data request ready
#define ATA_SR_CORR 0x04 // Corrected data
#define ATA_SR_IDX 0x02 // Index
#define ATA_SR_ERR 0x01 // Error
// Errors
#define ATA_ER_BBK 0x80 // Bad block
#define ATA_ER_UNC 0x40 // Uncorrectable data
#define ATA_ER_MC 0x20 // Media changed
#define ATA_ER_IDNF 0x10 // ID mark not found
#define ATA_ER_MCR 0x08 // Media change request
#define ATA_ER_ABRT 0x04 // Command aborted
#define ATA_ER_TK0NF 0x02 // Track 0 not found
#define ATA_ER_AMNF 0x01 // No address mark

View File

@ -1,29 +0,0 @@
#pragma once
struct IDEChannelRegisters{
unsigned short base; // I/O Base.
unsigned short ctrl; // Control Base
unsigned short bmide; // Bus Master IDE
unsigned char nIEN; // IEN (no interrupt)
};
struct IDE_DEVICE {
unsigned char Reserved; // 0 (Empty) or 1 (This device exists).
unsigned char Channel; // 0 (Primary Channel) or 1 (Secondary Channel).
unsigned char Drive; // 0 (Master Drive) or 1 (Slave Drive).
unsigned short Type; // 0 ATA, 1:ATAPI
unsigned short Signature; // Drive Signature
unsigned short Capabilities; // Features.
unsigned int CommandSets; // Command Sets Supported.
unsigned int Size; // Size in Sectors (NOTE: Seems unused nowadays as i've only seen the value be zero
unsigned char Model[41]; // Model in string.
} ;
extern IDEChannelRegisters channels[2];
extern IDE_DEVICE ide_devices[4];
extern unsigned char ide_buf[2048];
extern unsigned char ide_irq_invoked;
extern unsigned char atapi_packet[12];

View File

@ -1,242 +0,0 @@
#pragma once
#include <stdint.h>
#include "../tty/kterm.h"
#include "sampleIDE.definitions.h"
#include "ideCommands.h"
void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4);
void DetectDevices();
unsigned char ide_buf[2048] = {0};
unsigned char ide_irq_invoked = 0;
unsigned char atapi_packet[12] = {0xA8,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void wait(int t){
volatile int i,j;
for(i=0;i<t;i++)
for(j=0;j<25000;j++)
asm("NOP");
}
void ide_write(unsigned char channel, unsigned char reg, unsigned char data){
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
if (reg < 0x08)
outb(channels[channel].base + reg - 0x00, data);
else if (reg < 0x0C)
outb(channels[channel].base + reg - 0x06, data);
else if (reg < 0x0E)
outb(channels[channel].ctrl + reg - 0x0A, data);
else if (reg < 0x16)
outb(channels[channel].bmide + reg - 0x0E, data);
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
}
unsigned char ide_read(unsigned char channel, unsigned char reg){
unsigned char result;
if( reg > 0x07 && reg < 0x0C)
ide_write(channel,ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
if( reg < 0x08)
result = inb(channels[channel].base + reg - 0x00);
else if (reg < 0x0C)
result = inb(channels[channel].base + reg - 0x06);
else if (reg < 0x0E)
result = inb(channels[channel].ctrl + reg - 0x0A);
else if (reg < 0x16)
result = inb(channels[channel].bmide + reg - 0x0E);
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
return result;
}
void ide_read_buffer(unsigned char channel, unsigned char reg, unsigned int buffer, unsigned int quads){
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
if (reg < 0x08)
insl(channels[channel].base + reg - 0x00, (void *)buffer, quads);
else if (reg < 0x0C)
insl(channels[channel].base + reg - 0x06, (void *)buffer, quads);
else if (reg < 0x0E)
insl(channels[channel].ctrl + reg - 0x0A, (void *)buffer, quads);
else if (reg < 0x16)
insl(channels[channel].bmide + reg - 0x0E, (void *)buffer, quads);
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
}
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
// (I) Delay 400 nanosecond for BSY to be set:
// -------------------------------------------------
for(int i = 0; i < 4; i++)
ide_read(channel, ATA_REG_ALTSTATUS); // Reading the Alternate Status port wastes 100ns; loop four times.
// (II) Wait for BSY to be cleared:
// -------------------------------------------------
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY)
; // Wait for BSY to be zero.
if (advanced_check) {
unsigned char state = ide_read(channel, ATA_REG_STATUS); // Read Status Register.
// (III) Check For Errors:
// -------------------------------------------------
if (state & ATA_SR_ERR)
return 2; // Error.
// (IV) Check If Device fault:
// -------------------------------------------------
if (state & ATA_SR_DF)
return 1; // Device Fault.
// (V) Check DRQ:
// -------------------------------------------------
// BSY = 0; DF = 0; ERR = 0 so we should check for DRQ now.
if ((state & ATA_SR_DRQ) == 0)
return 3; // DRQ should be set
}
return 0; // No Error.
}
unsigned char ide_print_error(unsigned int drive, unsigned char err) {
if (err == 0)
return err;
printf("IDE:");
if (err == 1) {printf("- Device Fault\n "); err = 19;}
else if (err == 2) {
unsigned char st = ide_read(ide_devices[drive].Channel, ATA_REG_ERROR);
if (st & ATA_ER_AMNF) {printf("- No Address Mark Found\n "); err = 7;}
if (st & ATA_ER_TK0NF) {printf("- No Media or Media Error\n "); err = 3;}
if (st & ATA_ER_ABRT) {printf("- Command Aborted\n "); err = 20;}
if (st & ATA_ER_MCR) {printf("- No Media or Media Error\n "); err = 3;}
if (st & ATA_ER_IDNF) {printf("- ID mark not Found\n "); err = 21;}
if (st & ATA_ER_MC) {printf("- No Media or Media Error\n "); err = 3;}
if (st & ATA_ER_UNC) {printf("- Uncorrectable Data Error\n "); err = 22;}
if (st & ATA_ER_BBK) {printf("- Bad Sectors\n "); err = 13;}
} else if (err == 3) {printf("- Reads Nothing\n "); err = 23;}
else if (err == 4) {printf("- Write Protected\n "); err = 8;}
printf("- [%s %s] %s\n",
(const char *[]){"Primary", "Secondary"}[ide_devices[drive].Channel], // Use the channel as an index into the array
(const char *[]){"Master", "Slave"}[ide_devices[drive].Drive], // Same as above, using the drive
ide_devices[drive].Model);
return err;
}
inline void init_IDE( uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4)
{
Detect_IO_Ports( BAR0, BAR1, BAR2, BAR3, BAR4);
printf("ATA Primary port, base: 0x%x, ctrl: 0x%x\n", channels[ATA_PRIMARY].base , channels[ATA_PRIMARY].ctrl);
printf("ATA Secondary port, base: 0x%x, ctrl: 0x%x\n", channels[ATA_SECONDARY].base , channels[ATA_SECONDARY].ctrl);
// 2- Disable IRQs:
ide_write(ATA_PRIMARY , ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
DetectDevices();
return;
// 4- Print Summary:
for (int i = 0; i < 4; i++)
if (ide_devices[i].Reserved == 1) {
printf(" Found %s Drive %d bytes - %x\n",
(const char *[]){"ATA", "ATAPI"}[ide_devices[i].Type], /* Type */
ide_devices[i].Size / 2, /* Size */
ide_devices[i].Model);
}
}
// 3- Detect ATA-ATAPI Devices:
void DetectDevices(){
int i, j, k, count = 0;
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++) {
unsigned char err = 0, type = IDE_ATA, status;
ide_devices[count].Reserved = 0; // Assuming that no drive here.
// (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive.
wait(1000); // Wait 1ms for drive select to work.
// (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
wait(1000);
// (III) Polling:
if (ide_read(i, ATA_REG_STATUS) == 0) continue; // If Status = 0, No Device.
while(1) {
status = ide_read(i, ATA_REG_STATUS);
if ((status & ATA_SR_ERR)) {err = 1; break;} // If Err, Device is not ATA.
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) break; // Everything is right.
}
// (IV) Probe for ATAPI Devices:
if (err != 0) {
unsigned char cl = ide_read(i, ATA_REG_LBA1);
unsigned char ch = ide_read(i, ATA_REG_LBA2);
if (cl == 0x14 && ch ==0xEB)
type = IDE_ATAPI;
else if (cl == 0x69 && ch == 0x96)
type = IDE_ATAPI;
else
continue; // Unknown Type (may not be a device).
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
wait(1000);
}
// (V) Read Identification Space of the Device:
ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);
// (VI) Read Device Parameters:
ide_devices[count].Reserved = 1;
ide_devices[count].Type = type;
ide_devices[count].Channel = i;
ide_devices[count].Drive = j;
ide_devices[count].Signature = *((unsigned short *)(ide_buf + ATA_IDENT_DEVICETYPE));
ide_devices[count].Capabilities = *((unsigned short *)(ide_buf + ATA_IDENT_CAPABILITIES));
ide_devices[count].CommandSets = *((unsigned int *)(ide_buf + ATA_IDENT_COMMANDSETS));
// (VII) Get Size:
if (ide_devices[count].CommandSets & (1 << 26))
// Device uses 48-Bit Addressing:
ide_devices[count].Size = *((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA_EXT));
else
// Device uses CHS or 28-bit Addressing:
ide_devices[count].Size = *((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA));
// (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
for(k = 0; k < 40; k += 2) {
ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];
ide_devices[count].Model[k + 1] = ide_buf[ATA_IDENT_MODEL + k];}
ide_devices[count].Model[40] = 0; // Terminate String.
count++;
}
}
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
channels[ATA_PRIMARY].base = (BAR0 == 0x1 || BAR0 == 0x0) ? 0x1F0 : BAR0 & (~1);
channels[ATA_PRIMARY ].ctrl = (BAR1 == 0x1 || BAR1 == 0x0) ? 0x3F6 : BAR1 & (~1);
channels[ATA_SECONDARY].base = (BAR2 == 0x1 || BAR2 == 0x0) ? 0x170 : BAR2 & (~1);
channels[ATA_SECONDARY].ctrl = (BAR3 == 0x1 || BAR3 == 0x0) ? 0x376 : BAR3 & (~1);
channels[ATA_PRIMARY ].bmide = (BAR4 & (~1)) + 0; // Bus Master IDE
channels[ATA_SECONDARY].bmide = (BAR4 & (~1)) + 8; // Bus Master IDE
}

View File

@ -1,6 +1,5 @@
#include "idt.h"
#include "../pit.h"
#include "../keyboard/keyboard.h"
//#include "scancodes/set1.h"
IDT_entry idt_table[256];
IDT_ptr idt_ptr;
@ -14,249 +13,78 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
};
void irs_handler (registers regs) {
kterm_writestring("received interrupt!\n");
//printf("(IRS) Interrupt number: %d \r", regs.int_no);
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);
break;
printf("(IRS) Interrupt number: %d \n", regs.int_no);
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);
break;
if( regs.int_no == 13){
printf(" Error code: %d \n", regs.err_code);
case 2:
// NMI Interrupt
printf("#NMI\n");
break;
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);
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);
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);
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);
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);
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);
break;
case 9:
// Coprocessor Segment Overrun
printf("Coprocessor Segment overrun!\n");
break;
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);
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);
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);
break;
case 13:
// General Protection Exception #GP
printf("#GP\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
break;
case 14:
// Page Fault Exception #PF
printf("#PF\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
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);
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);
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);
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);
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);
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);
break;
default:
// PANIC!!!
break;
}
}
void irq_handler (registers regs) {
if ( regs.int_no != 0) {
kterm_writestring("received interrupt!\n");
printf("(IRQ) Interrupt number: %d \n", regs.int_no);
switch (regs.int_no) {
case 0:
pit_tick++;
break;
case 1:
// Keyboard interrupt !!
}
int scan;
int i;/*register*/
if ( regs.int_no == 1 ){
// Keyboard interrupt !!
// Read scancode
scan = inb(0x60);
int scan;
/*register*/int i;
// Send ack message!
i = inb(0x61);
outb(0x61, i|0x80);
outb(0x61, i);
// Read scancode
scan = inb(0x60);
// Send ack message!
i = inb(0x61);
outb(0x61, i|0x80);
outb(0x61, i);
kterm_writestring("A key was pressed/released\n");
printf( "Scancode: %x\n", scan);
// NOTE: check for special scan codes
// e.g. modifiers etc..
if( scan < 0x37){
//printf("Read from IO: 0x%x\n", scan);
keyPress.ScanCode = scan ;
//printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
}
break;
case 12:
// PS2 Mouse interrupt
printf("Mouse event triggered!");
//int event = inb(0x60);
break;
default:
printf("Interrupt happened!");
printf("Received INT: 0x%x\n", regs.int_no);
break;
}
outb(0x20, 0x20); // send end of interrupt to master
outb(0x20, 0x20); // send end of interrupt to master
if ( regs.int_no > 8 && regs.int_no <= 15) {
outb(0xA0, 0x20); // send end of interrupt to slave
}
if ( regs.int_no > 8 && regs.int_no <= 15) {
outb(0xA0, 0x20); // send end of interrupt to slave
}
if( regs.int_no == 13){
printf(" Error code: %d \n", regs.err_code);
if( regs.int_no == 13){
printf(" Error code: %d \n", regs.err_code);
}
}
}
void init_idt(){
// Initialise the IDT pointer
idt_ptr.length = sizeof(IDT_entry) * 255;
idt_ptr.base = (uint32_t)&idt_table;
#ifdef __VERBOSE__
printf("Init IDT\n");
#endif
// TODO: Set everything to zero first
@ -297,15 +125,10 @@ void init_idt(){
//print_serial("Remapping PIC\n");
PIC_remap(0x20, 0x28);
// clear mask for IRQ 12
uint8_t value = inb(0x21) & ~(1<< 12);
outb(0x21, value);
// pic IRQ Table
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); // PS2 Keyboard
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E);
set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
@ -316,7 +139,7 @@ void init_idt(){
set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); // PS2 Mouse
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E);
set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);

View File

@ -2,7 +2,7 @@
#include "stdint.h"
#include "stddef.h"
#include "../drivers/VGA/colors.h"
#include "../vga/colors.h"
#include "../pic/pic.h"
#include "../tty/kterm.h"

View File

@ -12,10 +12,9 @@ unsigned short inw_p(unsigned short ){
// TODO: implement me!
return 0;
}
uint32_t inl( int port ){
unsigned int data;
asm volatile ("inl %w1, %0": "=a" (data): "d" (port));
return data;
unsigned int inl(unsigned short ){
// TODO: implement me!
return 0;
}
unsigned int inl_p(unsigned short ){
// TODO: implement me!
@ -23,7 +22,7 @@ unsigned int inl_p(unsigned short ){
}
void b_p(unsigned char , unsigned short ){
void outb_p(unsigned char , unsigned short ){
}
void outw(unsigned short , unsigned short ){
@ -32,12 +31,9 @@ void outw(unsigned short , unsigned short ){
void outw_p(unsigned short , unsigned short ){
}
void outl(unsigned int , unsigned short ){
void outl( int port , uint32_t data ){
asm volatile ("outl %0, %1" :: "a" (data), "dn"(port));
}
void outl_p(unsigned int , unsigned short ){
}

View File

@ -12,17 +12,21 @@ static inline uint8_t inb(uint16_t port)
unsigned char inb_p(unsigned short port);
unsigned short inw(unsigned short port);
unsigned short inw_p(unsigned short port);
uint32_t inl( int port );
unsigned int inl(unsigned short port);
unsigned int inl_p(unsigned short port);
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
/* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint).
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
* The outb %al, %dx encoding is the only option for all other cases.
* %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */
}
void outb_p(unsigned char value, unsigned short port);
void outw(unsigned short value, unsigned short port);
void outw_p(unsigned short value, unsigned short port);
void outl( int port , uint32_t data );
void outl(unsigned int value, unsigned short port);
void outl_p(unsigned int value, unsigned short port);
void insb(unsigned short port, void *addr,

View File

@ -1,10 +1,51 @@
#include "kernel.h"
#define GB4 524288
#define GB2 262144
extern "C" void kernel_main (void);
extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigned char addr , unsigned char pixelWidth, unsigned pitch );
extern "C" void early_main(unsigned long magic, unsigned long addr){
/** initialize terminal interface */
// kterm_init();
printf("Magic flag 0x%8x\n", magic);
printf("Magic must be 0x%8x\n", MULTIBOOT_BOOTLOADER_MAGIC);
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
printf("Invalid magic number: 0x%8x\n", magic);
return;
}
CheckMBT( (multiboot_info_t *) addr);
multiboot_info_t* mbt = (multiboot_info_t*) addr;
/* Are mmap_* valid? */
if (CHECK_FLAG(mbt->flags, 6)){
PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/);
PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length);
PhysicalMemoryManager_deinitialise_kernel();
extern uint8_t* kernel_begin;
extern uint8_t* kernel_end;
printf("Kernel MemoryMap:\n");
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
}
initGDT();
kernel_main();
}
extern "C" void kernel_main (void) {
printf("call to init serial\n");
init_serial();
extern "C" void wait_until_shutdown(){
while (true){
//Read time indefinetely
read_rtc();
@ -12,280 +53,8 @@
delay(1000);
}
}
extern "C" void kernel_main (void) {
printf("call to init serial\n");
init_serial();
print_serial("Serial port initialized!");
RSDPTR* rsd = FindRSD();
RSDT* rsd_table = getRSDT(rsd);
// Enumerate the PCI bus
PCI_Enumerate();
TestIDEController();
int devNumber = 0 ;
for ( auto device : ide_devices){
if (!device.Reserved)
continue;
printf("Device %d\n" , devNumber);
printf (" Device on Channel: (0x%x) %s\n" ,device.Channel, device.Channel == 0 ? "Primary" : "Secondary");
printf (" Device drive:(0x%x) %s\n" , device.Drive, device.Drive? "Slave" : "Master");
printf (" Device Type:(0x%x) %s\n" , device.Type, device.Type ? "ATAPI" : "ATA");
devNumber ++;
}
enum BUS_PORT {
Primary= 0x1f0,
Secondary = 0x170
};
ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
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);
printf("LBA: %d\n" , LBA);
uint16_t buffer [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, buffer);
MBR* mbr = (MBR*) buffer;
printf("BootSector: 0x%x\n", mbr->ValidBootsector );
for( int i = 0 ; i < 4 ; i ++){
PartitionTableEntry PT = mbr->TableEntries[i];
printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" ,
i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start );
}
// Find the BiosParameter block
uint16_t biosparameterblock[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, biosparameterblock);
BiosParameterBlock* bpb = (BiosParameterBlock*) biosparameterblock;
printf("\nBPB: Bytes per Sector %d\n", bpb->BytesPerSector );
printf("OEM ID: %s\n", bpb->OEM_id);
printf("Bytes per sector: %d\n", bpb->BytesPerSector);
printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster);
printf("Reserved sectors: %d\n", bpb->ReservedSectors);
printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables);
printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries);
printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume);
printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT);
/**
* @brief File Allocation Table
*/
uint32_t FATAddress = mbr->TableEntries[0].LBA_partition_start + bpb->ReservedSectors ;
uint16_t FAT[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT );
// Show data in terminal
for(int i = 0; i < 256; i++ ) {
printf("%x ", FAT[i]);
}
kterm_put('\n');
uint32_t RootDirectoryRegion = FATAddress + ( bpb->NumberOfFileAllocationTables * bpb->NumberOfSectorsPerFAT );
uint32_t DataRegion = RootDirectoryRegion + ((bpb->NumberOfDirectoryEntries * 32) / bpb->BytesPerSector );
uint16_t data2 [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 );
DirectoryEntry* RootDirectory = (DirectoryEntry*) data2;
// List files in root
for(int i= 0; i < bpb->NumberOfDirectoryEntries ; i++ )
{
DirectoryEntry* entry = (DirectoryEntry*)((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry)));
if( entry->filename[0] == (uint8_t) 0x00 )
break; // There are no more entries in this directory or the entry is free
if( entry->attribute & 0x01 == 0x01 || entry->attribute & 0x20 == 0x20)
continue; // Skip listing if hidden or Achieve flag is set
// Print the filename;
for( int n = 0; n < 8; n++ ){
if(entry->filename[n] == 0x20)
break;
kterm_put(entry->filename[n]);
}kterm_put('\n');
for( int n = 0; n < 3; n++){
kterm_put(entry->Extension[n]);
}kterm_put('\n');
printf("Attribute: %x \n" , entry->attribute);
printf("FileSize: %d Bytes\n", entry->FilesizeInBytes);
if( entry->FilesizeInBytes != 0x0 || entry->attribute & 0x8 == 0x0){
printf("Show contents");
printf( "Start cluster of the file: 0x%x\n" , entry->StartingCluster);
printf("IS it only 1 cluster? %s\n" , FAT[i] == 0xFFFF? "Yes": "No" );
uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02 ) * bpb->SectorsPerCluster);
uint16_t dataBlob [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob );
for( int n = 0; n < 256; n++)
{
kterm_put(dataBlob[n] & 0x00ff);
kterm_put(dataBlob[n] >> 8);
}kterm_put('\n');
}
printf("======================\n");
}
wait_until_shutdown();
}
extern "C" void early_main(unsigned long magic, unsigned long addr){
/**
* Initialize terminal interface
* NOTE: This should be done later on , the magic value should be checked first.
*/
kterm_init();
/**
* Check Multiboot magic number
* NOTE: Printf call should not be a thing this early on ...
*/
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
printf("Invalid magic number: 0x%x\n", magic);
return;
}
/**
* Use the address given as an argument as the pointer
* to a Multiboot information structure.
*/
multiboot_info_t* mbt = (multiboot_info_t*) addr;
/**
* Construct our own bootInfo structure
*/
BootInfo bootinfo = {};
/*
If we got a memory map from our bootloader we
should be parsing it to find out the memory regions available.
*/
if (CHECK_FLAG(mbt->flags, 6))
{
/*
Setup Physical memory managment
*/
MemoryInfo meminfo = {};
bootinfo.memory = &meminfo;
mapMultibootMemoryMap(bootinfo.memory , mbt);
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
PhysicalMemory memAlloc = PhysicalMemory{};
memAlloc.setup(bootinfo.memory );
/*
Mark already in use sections
*/
// Mark kernel memory as used
printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", kernel_begin , kernel_end );
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
} else{
printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len );
memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len);
}
}
printf("allocate region: 0x%x, size : 0x%x bytes\n", kernel_begin, kernel_end - kernel_begin );
memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin);
// test alloc_block
uint8_t* memory = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory);
uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory2);
memAlloc.free_block((void*) memory);
uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block();
// memAlloc.free_block((void*) memory);
}
initGDT();
init_idt();
// Enable interrupts
asm volatile("STI");
init_serial();
pit_initialise();
CheckMBT( (multiboot_info_t *) addr);
startSuperVisorTerminal(&bootinfo);
kernel_main();
}

View File

@ -1,43 +1,33 @@
#pragma once
extern "C"
{
extern "C"{
#include "../libc/include/string.h"
}
#include "drivers/VGA/VBE.h"
#include "vga/VBE.h"
#include "tty/kterm.h"
#include "./bootloader/multiboot.h"
#include "bootinfo.h"
#include "memory/memory.h"
#include "memory/memoryinfo.h"
#include "bootcheck.h"
#include "memory/PhysicalMemoryManager.h"
#include "gdt/gdtc.h"
#include "idt/idt.h"
#include "drivers/IO/io.h"
#include "io.h"
#include "time.h"
#include "pit.h"
#include "cpu.h"
#include "serial.h"
#include "drivers/IO/PCI/pci.h"
#include "ide/ide.h"
#include "./drivers/IO/ata/ataDevice.h"
#include "./PartitionTable/MBR/MasterBootRecord.h"
#include "./filesystems/FAT/BiosParameterBlock.h"
#include "./filesystems/FAT/ExtendBootRecord.h"
#include "./filesystems/FAT/DirectoryEntry.h"
#include "drivers/ACPI/rsdp.h"
#include "time.h"
#include "sv-terminal/superVisorTerminal.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
#define PANIC(message) {return;}
#define PANIC(message) { return; }
/* This needs to be moved! */
/**
* simple delay function
**/
void delay(int t){
volatile int i,j;
for(i=0;i<t;i++)
for(j=0;j<25000;j++)
asm("NOP");
}

View File

@ -1,51 +0,0 @@
#include "keyboard.h"
KeyPressInfo keyPress {};
void KeyHandled(){
keyPress.ScanCode= 0x00;
keyPress.PressedModifiers = 0x00;
}
char getASCIIKey(){
char keyPressed;
// Wait until a key is pressed
while(keyPress.ScanCode == 0x00) {
asm volatile ("NOP");
}
// Translate keycode to ascii
// Probably a lookup table might be handy
// Until 0x37
const char* ASCIILookUp =
"\01234567890-=\0\0QWERTYUIOP[]\0\0ASDFGHJKL;\'`\0\\ZXCVBNM,./\0";
uint8_t ASCII_Index = keyPress.ScanCode - 3 ;
//printf("ASCII_INDEX: %x\n", ASCII_Index);
keyPressed = ASCIILookUp[ASCII_Index];
KeyHandled();
return keyPressed;
}
uint8_t getKey(){
// Wait until a key is pressed
while(keyPress.ScanCode == 0x00){
asm volatile ("NOP");
}
if( keyPress.ScanCode > 0x37){
keyPress.ScanCode = 0x00;
return 0;
}
uint8_t ScanCode = keyPress.ScanCode;
// KeyHandled();
return ScanCode ;
}

View File

@ -1,34 +0,0 @@
#pragma once
#include <stdint.h>
#include "../tty/kterm.h"
typedef enum ScanCodeSet{
None = 0,
ScanCodeSet1 = 1,
ScanCodeSet2 = 2,
ScanCodeSet3 = 3,
};
typedef enum Modifiers{
LSHIFT = 1,
RSHIFT = 2,
LCTRL = 3,
RCTRL = 4,
LALT = 5,
RALT = 6
};
struct KeyPressInfo{
uint8_t PressedModifiers;
uint8_t ScanCode;
};
extern KeyPressInfo keyPress;
void KeyHandled();
char getASCIIKey();
uint8_t getKey();

View File

@ -13,26 +13,26 @@ inline void bitmap_unset(uint32_t* map , int index)
map[index/32] &= ~(1 << (index % 32));
}
inline uint32_t bitmap_first_unset( uint32_t* map , int map_size)
inline int bitmap_first_unset( uint32_t* map , int size)
{
for ( int i = 0 ; i < map_size ; i ++ )
uint32_t rem_bits = size % 32;
for(uint32_t i = 0; i < size/32; i++)
{
// a bit or more is set within this byte!
if( (map[i] & 0xFFFFFFFF) > 0 ){
// which bit is set?
for(int j = 0 ; j < 32 ; j++){
if ( (map[i] & (0x00000001 << j)) > 0)
{
printf("Found bit: byte 0x%x , bit 0x%x\n", i , j);
return (i*32)+j;
if(map[i] != 0xFFFFFFFF){
for(int j = 0; j < 32; j++){
if(!(map[i] & (1<< j))){
return (i*32) + j;
}
}
}
}
if(rem_bits){
for(uint32_t j = 0; j < rem_bits; j++){
if(!(map[size/32] & (1 << j ))){
return size + j; // Original author divided size by 32 and then multiplied it by 32 which is a net zero calculation ?!?
}
}
}
return -1;

View File

@ -1,43 +1,47 @@
#include "PageDirectory.h"
void PageDirectory::enable()
{
#include <stdint.h>
void PageDirectory::enable(){
// https://wiki.osdev.org/Setting_Up_Paging
//set each entry to not present
// int i;
// for(i = 0; i < 1024; i++)
// {
// // This sets the following flags to the pages:
// // Supervisor: Only kernel-mode can access them
// // Write Enabled: It can be both read from and written to
// // Not Present: The page table is not present
// this->page_directory[i] = 0x00000002;
// }
int i;
for(i = 0; i < 1024; i++)
{
// This sets the following flags to the pages:
// Supervisor: Only kernel-mode can access them
// Write Enabled: It can be both read from and written to
// Not Present: The page table is not present
this->page_directory[i] = 0x00000002;
}
// // holds the physical address where we want to start mapping these pages to.
// // in this case, we want to map these pages to the very beginning of memory.
// holds the physical address where we want to start mapping these pages to.
// in this case, we want to map these pages to the very beginning of memory.
// //we will fill all 1024 entries in the table, mapping 4 megabytes
// for(unsigned int i = 0; i < 1024; i++)
// {
// // As the address is page aligned, it will always leave 12 bits zeroed.
// // Those bits are used by the attributes ;)
// first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
// }
//we will fill all 1024 entries in the table, mapping 4 megabytes
for(unsigned int i = 0; i < 1024; i++)
{
// As the address is page aligned, it will always leave 12 bits zeroed.
// Those bits are used by the attributes ;)
first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
}
// // attributes: supervisor level, read/write, present
// this->page_directory[0] = ((unsigned int)first_page_table) | 3;
// attributes: supervisor level, read/write, present
this->page_directory[0] = ((unsigned int)first_page_table) | 3;
printf("Enable Paging!\n");
loadPageDirectory(this->page_directory);
enablePaging();
}
void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size )
/*
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
{
from = from & 0xFFFFF000; // Discard the bits we don't want
for (; size > 0; from += 4096, first_pte++)
{
*first_pte = from | 1; // makr page present.
}
}
*/

View File

@ -1,18 +1,17 @@
#pragma once
#include <stdint.h>
#include "./memory.h"
#include "./../tty/kterm.h"
#define KB 1024
extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging();
typedef uintptr_t address_t;
#define KB 1024
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
static volatile address_t pmem_stack[MAX_PAGES];
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging();
struct page_directory_entry {};
struct page_table_entry{};
@ -22,10 +21,8 @@ struct page_table_entry{};
class PageDirectory {
public:
void enable ();
void MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size );
private:
uint32_t page_directory[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
uint32_t first_page_table[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
};

View File

@ -0,0 +1,38 @@
#include "PageFrameAllocator.h"
MemoryInfo memInfo {};
void mapMultibootMemoryMap( multiboot_info_t *mbt){
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
memInfo.memorySizeInBytes += mmap->len;
} else {
memInfo.reservedMemoryInBytes += mmap->len;
}
print_Multiboot_memory_Map(mmap);
}
uint32_t memorySizeInGiB = memInfo.memorySizeInBytes / 1073741824;
printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memInfo.memorySizeInBytes, memorySizeInGiB );
printf("Reserved Memory: 0x%x bytes\n", memInfo.reservedMemoryInBytes );
}
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap){
printf(
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
(unsigned) mmap->size,
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
(unsigned) (mmap->len & 0xffffffff),
(unsigned) mmap->type
);
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "../arch/i386/tty/kterm.h"
#include <stdint.h>
#include "../bootloader/multiboot.h"
struct MemoryInfo{
uint32_t memorySizeInBytes = 0;
uint32_t reservedMemoryInBytes = 0;
};
extern void *kernel_begin;
extern void *kernel_end;
void print_Multiboot_memory_Map(multiboot_memory_map_t*);
void mapMultibootMemoryMap(multiboot_info_t*);

View File

@ -0,0 +1,118 @@
#include "PhysicalMemoryManager.h"
size_t mem_size = 0;
int used_blocks = 0;
size_t max_blocks = 0;
uint32_t* pmmap = 0;
size_t pmmap_size = 0;
void PhysicalMemoryManager_initialise(uint32_t physicalmemorymap_address, size_t size )
{
mem_size = size;
max_blocks = KB_TO_BLOCKS(mem_size);
used_blocks = max_blocks;
pmmap = (uint32_t*) physicalmemorymap_address;
if(max_blocks % BLOCKS_PER_WORD)
pmmap_size++;
memset(pmmap, 0xFF, pmmap_size);
}
void PhysicalMemoryManager_region_initialise(uint32_t base, size_t size)
{
size_t blocks = size /BLOCK_SIZE;
uint32_t align = base / BLOCK_SIZE;
for(size_t i = 0 ; i < blocks; i ++)
{
bitmap_unset(pmmap, align++);
used_blocks--;
}
bitmap_set(pmmap, 0);
}
void PhysicalMemoryManager_region_deinitialise(uint32_t base, size_t size )
{
size_t blocks = size / BLOCK_SIZE;
uint32_t align = base / BLOCK_SIZE;
for(size_t i = 0 ; i < blocks; i++ )
{
bitmap_set(pmmap, align++);
used_blocks++;
}
}
void PhysicalMemoryManager_initialise_available_regions(uint32_t mmap_, uint32_t mmap_end_)
{
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*)mmap_;
multiboot_memory_map_t *mmap_end= (multiboot_memory_map_t*) mmap_end_;
for(int i = 0; mmap < mmap_end ; mmap++, i++)
{
if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE)
{
PhysicalMemoryManager_region_initialise((uint32_t) mmap->addr, (size_t) mmap->len);
}
}
}
void PhysicalMemoryManager_deinitialise_kernel()
{
extern uint8_t kernel_begin;
extern uint8_t kernel_end;
size_t kernel_size = (size_t) &kernel_end - (size_t) &kernel_begin;
uint32_t pmmap_size_aligned = pmmap_size;
if(!IS_ALIGNED(pmmap_size_aligned, BLOCK_SIZE))
{
pmmap_size_aligned = ALIGN(pmmap_size_aligned, BLOCK_SIZE);
}
PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_begin, kernel_size);
PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_end, pmmap_size_aligned);
}
void* PhysicalMemoryManager_allocate_block()
{
if(used_blocks - max_blocks <= 0)
{
return 0;
}
int p_index = bitmap_first_unset(pmmap, p_index );
if(p_index == -1){
return 0;
}
bitmap_set(pmmap, p_index);
used_blocks++;
return (void*) (BLOCK_SIZE * p_index);
}
void PhysicalMemoryManager_free_block(void* p){
if(p==0){
return ;
}
uint32_t p_addr = (uint32_t) p;
int index = p_addr / BLOCK_SIZE;
bitmap_unset(pmmap, index);
used_blocks--;
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "../bootloader/multiboot.h"
#include <stdint.h>
#include <stddef.h>
#include "../../libc/include/mem.h"
#include "../kstructures/bitmap.h"
#define BLOCK_SIZE 4092
#define BLOCKS_PER_WORD 32
#define KB_TO_BLOCKS(x) (((x) * 1024 ) / BLOCK_SIZE)
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
extern void PhysicalMemoryManager_initialise(uint32_t, size_t);
extern void PhysicalMemoryManager_region_initialise(uint32_t, size_t);
extern void PhysicalMemoryManager_region_deinitialise(uint32_t,size_t);
extern void PhysicalMemoryManager_initialise_available_regions(uint32_t, uint32_t);
extern void PhysicalMemoryManager_deinitialise_kernel();
extern void* PhysicalMemoryManager_allocate_block();
extern void PhysicalMemoryManager_free_block(void* p);
extern size_t mem_size;
extern int used_blocks;
extern size_t max_blocks;
extern uint32_t* pmmap;
extern size_t pmmap_size ;

View File

@ -0,0 +1,33 @@
#pragma once
/**
* We'll need something to this effect to allocate memory in the kernel
* this will hopefully someday implement a full slab allocator
**/
enum SlabState {
empty,
partial,
full
};
class CacheSlab {
const int SlabSize = 4000;
void* start = 0x0;
};
class Allocator {
public:
Allocator();
~Allocator();
void* kmalloc( int size );
void kfree (void* address);
private:
CacheSlab** _cache;
};

View File

@ -1,142 +0,0 @@
#include "./memory.h"
uint32_t* memoryBitMap;
/*
*/
void PhysicalMemory::setup( MemoryInfo* memory) {
// calculate the maximum number of blocks
max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
used_blocks = 0;
memoryBitMap = (uint32_t*) 0x00a00000;
printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8));
//Size of memory map
uint32_t memMap_size = (max_blocks / 8 ) ;
printf("Memory Map size: 0x%x\n", memMap_size );
printf("size of int in bytes: 0x%x \n" , sizeof(int));
// Set all places in memory as free
memset(memoryBitMap, 0xFF, memMap_size );
}
// NOTE: this can only give blocks of 4kb at a time!
void* PhysicalMemory::allocate_block() {
uint8_t blocks_available = max_blocks - used_blocks;
// Are there any blocks available?
if( blocks_available <= 0)
{
printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
return 0;
}
// Find 1 free block somewhere
int free_block_index = bitmap_first_unset(memoryBitMap, (max_blocks /8) /*memMap Size*/ );
if(free_block_index == -1)
{
printf("Could not find a good block!\n");
// Could not find a block
return (void*)0xFFFF;
}
if(free_block_index == 0)
printf("Somethings wrong!!!\n");
// Set the block to be used!
bitmap_unset(memoryBitMap, free_block_index);
// Increase the used_block count!
used_blocks++;
printf("used blocks: 0x%x\n", used_blocks);
// return the pointer to the physical address
return (void*) (BLOCK_SIZE * free_block_index);
}
void PhysicalMemory::free_block(void* p) {
// If it is a null pointer we don't need to do anything.
if(p==0) {
return;
}
// calculate the index into the bitmap
int index = ((uint32_t) p) / BLOCK_SIZE;
// set the block to be free
bitmap_set(memoryBitMap, index);
used_blocks--;
printf("used blocks: 0x%x, after free\n", used_blocks);
}
void PhysicalMemory::allocate_region(uint32_t startAddress, uint32_t size) {
// every bit should be 4KiB
// every byte is 8*4KiB = 32KiB
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
int startBlock = (startAddress / 1024) / 4 / 8 ;
// printf("NumberOfBlocksToAllocate: 0x%x\n", NumberOfBlocksToAllocate);
//printf( "start block: 0x%x\n" , startBlock);
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
{
//printf("ALLOCATE BLOCK: 0x%x\n" , startBlock + i );
bitmap_unset(memoryBitMap, startBlock+ i);
used_blocks++;
}
}
void PhysicalMemory::deallocate_region(uint32_t StartAddress , uint32_t size ) {
// NOT IMPLEMENTED YET
}
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
memInfo->TotalMemory += mmap->len;
} else {
memInfo->ReservedMemory += mmap->len;
}
print_Multiboot_memory_Map(mmap);
}
}
/**
* @brief Debug Verbose functions
*
* @param mmap
*/
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
printf(
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
(unsigned) mmap->size,
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
(unsigned) (mmap->len & 0xffffffff),
(unsigned) mmap->type
);
}

View File

@ -1,48 +0,0 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#include "memoryinfo.h"
#include "../bootloader/multiboot.h"
#include "../tty/kterm.h"
#include "../../libc/include/mem.h"
#include "../kstructures/bitmap.h"
#define BLOCK_SIZE 4092
#define BLOCKS_PER_WORD 32 // A word is 16 bit in x86 machines according to my google search results!
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
extern uint32_t kernel_begin;
extern uint32_t kernel_end;
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks);
extern uint32_t* memoryBitMap;
class PhysicalMemory
{
public:
void setup(MemoryInfo* memory);
void destroy();
void free_block(void* ptr);
void* allocate_block();
void allocate_region(uint32_t, uint32_t);
void deallocate_region(uint32_t , uint32_t );
private:
size_t pmmap_size;
size_t max_blocks;
int used_blocks;
};
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt);
/**
* @brief Debug Verbose Functions
*
* @param mmap
*/
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap);

View File

@ -1,20 +0,0 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
struct MemoryArea{
void* StartAddress;
size_t Size;
unsigned int type;
MemoryArea* Next;
}__attribute__((packed));
struct MemoryInfo {
uint32_t TotalMemory;
uint32_t ReservedMemory;
MemoryArea* MemoryRegionList;
}__attribute__((packed));

108
src/kernel/pci.cpp Normal file
View File

@ -0,0 +1,108 @@
#include "pci.h"
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){
uint32_t address;
uint32_t lbus = (uint32_t) bus;
uint32_t lslot = (uint32_t) slot;
uint32_t lfunc = (uint32_t) func;
uint16_t tmp = 0;
/* Create configuration address as per Figure 1 */
address = (uint32_t) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) |((uint32_t) 0x80000000) );
/*write out the address */
outl(CONFIG_ADDRESS, address);
/* read in the data */
/* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/
tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF);
return (tmp);
}
uint16_t CheckVendor (uint8_t bus, uint8_t slot) {
uint16_t vendor, device;
/*
Try and read the first configuration register. Since there ar no
vendors that == 0xFFFF, it must be a non-existent device.
*/
if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) {
device = ConfigReadWord(bus, slot, 0,2);
// Possible read more config values ...
} return (vendor);
}
void checkDevice (uint8_t bus, uint8_t device ) {
uint8_t function = 0;
uint16_t vendorID = CheckVendor(bus, device);
if (vendorID == 0xFFFF) {
return;
}
checkFunction (bus, device, function );
headerType = getHeaderType(bus, device, function );
if( (headerType & 0x80) != 0) {
/* It is a multi-function device, so check remaining functions */
for (function = 1; function < 8; function++){
if (CheckVendor(bus, device)!= 0xFFFF){
checkFunction(bus, device, function );
}
}
}
}
void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){
uint8_t baseClass;
uint8_t subClass;
uint8_t secondaryBus;
baseClass = getBaseClass(bus, device, function);
subClass = getSubClass (bus, device, function );
if ( (baseClass == 0x06) && (subClass == 0x04)){
secondaryBus = getSecondaryBus(bus,device, function);
checkBus(secondaryBus);
}
}
// Brute-force scan
void checkAllBuses (){
uint16_t bus;
uint8_t device;
for(bus = 0; bus < 256; bus++){
for(device = 0; device < 32; device++){
checkDevice(bus,device);
}
}
}
// Recursive scan
void checkBus (uint8_t bus){
uint8_t device;
for(device = 0; device < 32; device ++){
checkDevice(bus,device);
}
}
void checkAllBuses(){
uint8_t function;
uint8_t bus;
headerType = getHeaderType(0,0,0);
if ( (headerType & 0x80) == 0 ){
/* Single PCI host controller */
checkBus(0);
} else{
/* Multiple PCI host controllers */
for (function = 0; function < 8; function++){
if( CheckVendor(0,0) != 0xFFFF) {
break;
}
bus = function;
checkBus(bus);
}
}
}

58
src/kernel/pci.h Normal file
View File

@ -0,0 +1,58 @@
#pragma once
#include <stdint.h>
#include "io.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
/*
CONFIG_ADDRESS
32 bit register
bit 31 Enable bit (Should CONFIG_DATA be translatedc to configuration cycles)
bit 30 - 24 Reserved
bit 23 - 16 Bus Number (Choose a specific PCI BUS)
bit 15 - 11 Device Number (Selects specific device one the pci bus)
bit 10 - 8 Function Number (Selects a specific function in a device)
bit 7 - 0 Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero
*/
/*
PCI Device structure
Register offset bits 31-24 bits 23-16 bits 15-8 bits 7-0
00 00 Device ID <---- Vendor ID <-------
01 04 Status <---- Command <-------
02 08 Class code Sub class Prog IF Revision ID
03 0C BIST Header Type Ltncy Timer Cache line Size
04 10 Base address #0 (BAR0)
05 14 Base address #1 (BAR1)
06 18 Base address #2 (BAR2)
07 1C Base address #3 (BAR3)
08 20 Base address #4 (BAR4)
09 24 Base address #5 (BAR5)
0A 28 Cardbus CIS Pointer
0B 2C Subsystem ID <------ Subsystem Vendor ID <-------
0C 30 Expansion ROM base address
0D 34 Reserved <------- Capabilities Pointer <------
0E 38 Reserved <------- <-------- <--------
0F 3C Max ltncy Min Grant Interrupt PIN Interrupt Line
*/
/*
The idea for now is to support the minimal things necessary to find ATA supported drives
*/
// Lets write some boiler plate configuration code
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
uint16_t CheckVendor (uint8_t bus, uint8_t slot);
void checkDevice (uint8_t bus, uint8_t device );

View File

@ -1,7 +0,0 @@
#include "pciDevice.h"
// NOTE: we would really like to return a pointer
// to the newly created PCIBusAddress struct;
PCIBusAddress const PCIDevice::PCIAddress(){
return PCIBusAddress{bus ,device, function};
}

View File

@ -1,54 +0,0 @@
#pragma once
#include <stdint.h>
/*
* PCI devices API
*/
struct PCIBusAddress{
int bus ;
int device ;
int function;
uint32_t getAddress( ){
return ((uint32_t) 1 << 31) |
((uint32_t) bus << 16) |
((uint32_t) device << 11)|
((uint32_t) function << 8) |
0x0000;
};
};
class PCIDevice {
public :
PCIDevice (PCIBusAddress* , int );
~PCIDevice();
PCIBusAddress const PCIAddress();
inline const char* getDeviceString(){
return "Not implemented"; //GetClassCodeName(deviceclass);
}
inline const char* getVendorString(){
return "Not implemented"; // getVendor(VendorID);
}
inline void setVendorID (uint16_t id) {
this->VendorID = id;
}
private:
int bus;
int device;
int function;
uint16_t VendorID;
uint16_t DeviceID;
uint8_t deviceclass;
uint8_t devicesubclass;
int headerType;
};

View File

@ -1,5 +1,5 @@
#pragma once
#include "../drivers/IO/io.h"
#include "../io.h"
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */

View File

@ -1,54 +0,0 @@
#include "pit.h"
#include "tty/kterm.h"
uint32_t pit_tick = 0;
void pit_initialise()
{
asm volatile("CLI");
#ifdef __VERBOSE__
printf("Init PIT!\n");
#endif
// clear mask for IRQ 0
uint8_t value = inb(0x21) & ~(1<< 0);
outb(0x21, value);
io_wait();
const int freq = 500;
uint32_t divisor = 1193180 / freq;
outb(PIT_COMMAND, 0x36);
uint8_t l = (uint8_t) (divisor & 0xFF);
uint8_t h = (uint8_t) ( (divisor>>8) & 0xff);
outb(PIT_DATA_0, l);
outb(PIT_DATA_0,h);
asm volatile("STI");
}
void get_pit_count()
{
asm volatile ("CLI");
outb(PIT_COMMAND, 0);
uint16_t count = inb(PIT_DATA_0);
count |= inb(PIT_DATA_0) << 8;
printf("PIT count: 0x%x\n", count);
asm volatile("STI");
}
void set_pit_count()
{
}

View File

@ -1,18 +0,0 @@
#pragma once
#include <stdint.h>
#include "drivers/IO/io.h"
#define PIT_DATA_0 0x40
#define PIT_DATA_1 0x41
#define PIT_DATA_2 0x42
#define PIT_COMMAND 0x43
extern uint32_t pit_tick;
void pit_initialise();
void get_pit_count();
void set_pit_count();

View File

@ -1,14 +1,10 @@
#pragma once
#include "tty/kterm.h"
#include "drivers/IO/io.h"
#include "io.h"
#define PORT 0x3f8
static int init_serial() {
#ifdef __VERBOSE__
printf("Init Serial\n");
#endif
inline static int init_serial() {
outb(PORT + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
@ -56,6 +52,68 @@ inline void print_serial(const char* string ){
}
}
inline void printf_serial ( const char *format, ...) {
char **arg = (char **)&format;
int c;
char buf[20];
arg++;
while ((c = *format++) != 0){
if( c != '%')
write_serial(c);
else{
char *p, *p2;
int pad0 = 0, pad = 0;
c = *format++;
if(c =='0'){
pad0 = 1;
c = *format++;
}
if ( c >= '0' && c <= '9'){
pad = c - '0';
c = *format++;
}
switch (c)
{
case 'd':
case 'u':
case 'x':
itoa(buf, c, *((int *) arg++));
p = buf;
goto string;
break;
case 's':
p = *arg++;
if(!p)
p = "(null)";
string:
for (p2 = p; *p2; p2++);
for (; p2 < p + pad; p2++)
write_serial(pad0 ? '0': ' ');
while (*p)
write_serial(*p++);
break;
default:
write_serial(*((int *)arg++));
break;
}
}
}
}
inline void test_serial(){
/** Serial test **/
kterm_writestring("Writing to COM1 serial port:");

View File

@ -1,89 +0,0 @@
#include "superVisorTerminal.h"
void startSuperVisorTerminal(BootInfo* bootinfo)
{
bool isRunning = true;
while (isRunning){
printf("SUPERVISOR:>$ " );
int characterCount = 0;
char command[10] = "";
// NOTE: lets just show a kernel prompt
uint8_t ScanCode = getKey();
while( ScanCode != 0x1C )
{
char character = getASCIIKey();
kterm_put(character );
// wHAT THE HELL
if( characterCount < 10 ){
command[characterCount] = character;
characterCount++;
}
ScanCode = getKey();
}
printf("\n");
KeyHandled();
if ( strncmp("DATE", command , characterCount ) == 0 )
{
read_rtc();
printf("======= Time & Date ==========\n");
printf(" - Date: %02d-%02d-%02d\n",day, month, year);
printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second);
printf(" - Ticks: %09d\n", pit_tick);
}
else if( strncmp ("MEMORY" , command , characterCount) == 0 )
{
// Show memory layout
printf("========= Memory ==========\n");
printf("Kernel MemoryMap:\n");
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
printf("Frames used: 0x%x blocks of 4 KiB\n", 0);
const int bytesInGiB = 1073741824;
int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
int64_t effectiveNumberOfGib = bootinfo->memory->TotalMemory / bytesInGiB;
int64_t GiBs = effectiveNumberOfGib + bytesLeft;
printf("Available Memory: %d bytes, %d GiB\n", bootinfo->memory->TotalMemory, GiBs );
printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory);
//printf("\n\n");
//PrintPhysicalMemoryAllocation( );
}
else if(strncmp("TEST", command, characterCount) == 0)
{
// TEST #DE exception
asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0
}
else if (strncmp("VERSION", command , characterCount) == 0)
{
// Show version information
printf("========= Version ========\n");
printf("Kernel v%d\n", 0);
}
else if(strncmp("CLEAR", command, characterCount) == 0)
{
kterm_init();
printf("|=== BarinkOS ===|\n");
}
else if(strncmp("FAT", command, characterCount) == 0){
isRunning = false;
continue;
}
else
{
printf("Unknown command\n");
}
delay(1000);
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include "../tty/kterm.h"
#include "../time.h"
#include "../pit.h"
#include "../keyboard/keyboard.h"
#include "../memory/memory.h"
#include "../bootinfo.h"
void startSuperVisorTerminal(BootInfo * );

View File

@ -1,111 +0,0 @@
#include "time.h"
// Set by ACPI table parsing code if possible
int century_register = 0x00;
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char day;
unsigned char month;
unsigned int year;
int get_update_in_progress_flag() {
outb(cmos_address, 0x0A);
return (inb(cmos_data) & 0x80);
}
unsigned char get_RTC_register(int reg) {
outb(cmos_address, reg);
return inb(cmos_data);
}
void read_rtc() {
unsigned char century;
unsigned char last_second;
unsigned char last_minute;
unsigned char last_hour;
unsigned char last_day;
unsigned char last_month;
unsigned char last_year;
unsigned char last_century;
unsigned char registerB;
// Note: This uses the "read registers until you get the same values twice in a row" technique
// to avoid getting dodgy/inconsistent values due to RTC updates
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
second = get_RTC_register(0x00);
minute = get_RTC_register(0x02);
hour = get_RTC_register(0x04);
day = get_RTC_register(0x07);
month = get_RTC_register(0x08);
year = get_RTC_register(0x09);
if(century_register != 0) {
century = get_RTC_register(century_register);
} else {
century = 21;
}
do {
last_second = second;
last_minute = minute;
last_hour = hour;
last_day = day;
last_month = month;
last_year = year;
last_century = century;
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
second = get_RTC_register(0x00);
minute = get_RTC_register(0x02);
hour = get_RTC_register(0x04);
day = get_RTC_register(0x07);
month = get_RTC_register(0x08);
year = get_RTC_register(0x09);
if(century_register != 0) {
century = get_RTC_register(century_register);
}
} while( (last_second != second) || (last_minute != minute) || (last_hour != hour) ||
(last_day != day) || (last_month != month) || (last_year != year) ||
(last_century != century) );
registerB = get_RTC_register(0x0B);
// Convert BCD to binary values if necessary
if (!(registerB & 0x04)) {
second = (second & 0x0F) + ((second / 16) * 10);
minute = (minute & 0x0F) + ((minute / 16) * 10);
hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
day = (day & 0x0F) + ((day / 16) * 10);
month = (month & 0x0F) + ((month / 16) * 10);
year = (year & 0x0F) + ((year / 16) * 10);
if(century_register != 0) {
century = (century & 0x0F) + ((century / 16) * 10);
}
}
// Convert 12 hour clock to 24 hour clock if necessary
if (!(registerB & 0x02) && (hour & 0x80)) {
hour = ((hour & 0x7F) + 12) % 24;
}
// Calculate the full (4-digit) year
if(century_register != 0) {
year += century * 100;
} else {
year += (CURRENT_YEAR / 100) * 100;
if(year < CURRENT_YEAR) year += 100;
}
}
void delay(int t){
volatile int i,j;
for(i=0;i<t;i++)
for(j=0;j<25000;j++)
asm("NOP");
}

View File

@ -1,15 +1,14 @@
#pragma once
#include "drivers/IO/io.h"
#define CURRENT_YEAR 2021
#define CURRENT_YEAR 2021 // Change this each year!
int century_register = 0x00; // Set by ACPI table parsing code if possible
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char day;
unsigned char month;
unsigned int year;
extern int century_register;
extern unsigned char second;
extern unsigned char minute;
extern unsigned char hour;
extern unsigned char day;
extern unsigned char month;
extern unsigned int year;
enum {
@ -17,7 +16,138 @@ enum {
cmos_data = 0x71
};
int get_update_in_progress_flag();
unsigned char get_RTC_register();
void read_rtc();
void delay(int t);
int get_update_in_progress_flag() {
outb(cmos_address, 0x0A);
return (inb(cmos_data) & 0x80);
}
unsigned char get_RTC_register(int reg) {
outb(cmos_address, reg);
return inb(cmos_data);
}
void read_rtc() {
unsigned char century;
unsigned char last_second;
unsigned char last_minute;
unsigned char last_hour;
unsigned char last_day;
unsigned char last_month;
unsigned char last_year;
unsigned char last_century;
unsigned char registerB;
// Note: This uses the "read registers until you get the same values twice in a row" technique
// to avoid getting dodgy/inconsistent values due to RTC updates
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
second = get_RTC_register(0x00);
minute = get_RTC_register(0x02);
hour = get_RTC_register(0x04);
day = get_RTC_register(0x07);
month = get_RTC_register(0x08);
year = get_RTC_register(0x09);
if(century_register != 0) {
century = get_RTC_register(century_register);
} else {
century = 21;
}
do {
last_second = second;
last_minute = minute;
last_hour = hour;
last_day = day;
last_month = month;
last_year = year;
last_century = century;
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
second = get_RTC_register(0x00);
minute = get_RTC_register(0x02);
hour = get_RTC_register(0x04);
day = get_RTC_register(0x07);
month = get_RTC_register(0x08);
year = get_RTC_register(0x09);
if(century_register != 0) {
century = get_RTC_register(century_register);
}
} while( (last_second != second) || (last_minute != minute) || (last_hour != hour) ||
(last_day != day) || (last_month != month) || (last_year != year) ||
(last_century != century) );
registerB = get_RTC_register(0x0B);
// Convert BCD to binary values if necessary
if (!(registerB & 0x04)) {
second = (second & 0x0F) + ((second / 16) * 10);
minute = (minute & 0x0F) + ((minute / 16) * 10);
hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
day = (day & 0x0F) + ((day / 16) * 10);
month = (month & 0x0F) + ((month / 16) * 10);
year = (year & 0x0F) + ((year / 16) * 10);
if(century_register != 0) {
century = (century & 0x0F) + ((century / 16) * 10);
}
}
// Convert 12 hour clock to 24 hour clock if necessary
if (!(registerB & 0x02) && (hour & 0x80)) {
hour = ((hour & 0x7F) + 12) % 24;
}
// Calculate the full (4-digit) year
if(century_register != 0) {
year += century * 100;
} else {
year += (CURRENT_YEAR / 100) * 100;
if(year < CURRENT_YEAR) year += 100;
}
}
/*
void ReadFromCMOS(unsigned char array[])
{
unsigned char tvalue, index;
for (index = 0; index < 128; index++)
{
asm(
"cli\n\t" // Disable interrupts
"mov al, index\n\t" // Move index address
// since the 0x80 bit of al is not set, NMI is active
"out 0x70,al\n\t" // Copy address to CMOS register
// some kind of real delay here is probably best
"in al,0x71\n\t" // Fetch 1 byte to al
"sti\n\t" // Enable interrupts
"mov tvalue,al\n\t");
array[index] = tvalue;
}
}
*/
/*
void WriteTOCMOS(unsigned char array[])
{
unsigned char index;
for(index = 0; index < 128; index++)
{
unsigned char tvalue = array[index];
asm("cli\n\t" // Clear interrupts
"mov al,index\n\t" // move index address
"out 0x70,al\n\t" // copy address to CMOS register
// some kind of real delay here is probably best
"mov al,tvalue\n\t" // move value to al
"out 0x71,al\n\t" // write 1 byte to CMOS
"sti\n\\t" ); // Enable interrupts
}
}
*/

View File

@ -1,4 +1,5 @@
#include "kterm.h"
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
@ -136,7 +137,7 @@ void kterm_writestring(const char* data ){
}
static void itoa (char *buf, int base, int d) {
void itoa (char *buf, int base, int d) {
char *p = buf;
char *p1, *p2;
unsigned long ud = d;
@ -172,15 +173,8 @@ static void itoa (char *buf, int base, int d) {
}
/**
* @brief For now this will not only write to VGA memory but also write to serial
*
* @param format
* @param ...
*/
void printf ( const char *format, ...) {
return;
char **arg = (char **)&format;
int c;
char buf[20];

View File

@ -4,8 +4,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "../drivers/VGA/colors.h"
#include "../drivers/IO/io.h"
#include "../vga/colors.h"
#include "../io.h"
extern "C"{
#include "./../../libc/include/string.h"
@ -33,10 +33,9 @@ uint16_t get_cursor_position();
int get_cursor_x (uint16_t cursor_pos);
int get_cursor_y (uint16_t cursor_pos);
extern "C" void itoa (char *buf, int base, int d);
void printf ( const char *format, ...);
//static void itoa (char *buf, int base, int d);
#define KernelTag "[Kernel]: "
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\

View File

@ -1,9 +0,0 @@
#pragma once
class File {
public:
virtual const File* Open () const ; // TODO: figure out a proper return value
virtual const char* Read() const;
virtual void Write();
};

View File

@ -1,50 +0,0 @@
#include "VFS.h"
/*
* TODO: Implement this!!
*
*/
void VirtualFileSystem::Initialize(FS* root)
{
root = root;
}
void VirtualFileSystem::Open(const char* path)
{
/*
What does this mean?
1. Parse the path string
2. Traverse the graph (Finding the correct Node)
3. Create some kind of open file pointer thingy
*/
}
void VirtualFileSystem::Read()
{
// NOTE: we need some way to know what file we wish to read from
}
void VirtualFileSystem::Write()
{
// NOTE: we need some way to know what file we wish to write to
}
void VirtualFileSystem::Mount(const char* path, FS* FileSystem)
{
/*
What does this mean?
1. Parse the path string
2. Add a node to our internal graph
*/
}
void VirtualFileSystem::UnMount(FS* FileSystem)
{
/*
What does this mean?
1. Parse the path string
2. Remve a node to our internal graph
*/
}

View File

@ -1,29 +0,0 @@
#pragma once
class VirtualFileSystem{
public:
void Initialize( FS* root);
void Open (const char* path);
void Read();
void Write();
void Mount(const char* path,FS* FileSystem);
void UnMount(FS* FileSystem);
private:
FS* root;
};
struct FS
{
const char* name ;
int DeviceID;
int ManufacturerID;
FS* next;
char**(Read)();
void*(Write)();
void*(Open)();
};

View File

@ -1,30 +1,8 @@
#pragma once
// NOTE: These should not be inline
inline 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;
int* data = (int*)ptr+ i;
*data = value;
}
return ptr;
}
inline int memcmp( const void* ptr1, const void* ptr2, size_t num)
{
const unsigned char * cs = (const unsigned char*) ptr1;
const unsigned char * ct = (const unsigned char*) ptr2;
for (int i = 0 ; i < num ; i++, cs++, ct++ ){
if( *cs < *ct){
return -1;
} else if( *cs > *ct){
return 1;
}
}
return 0;
}

View File

@ -7,20 +7,3 @@ size_t strlen(const char* str) {
}
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;
}

View File

@ -1,6 +1,3 @@
#pragma once
#include <stddef.h>
size_t strlen(const char* str);
int strncmp ( const char* str1, const char* str2, size_t num );

21
todo.md
View File

@ -1,21 +0,0 @@
# TODO list
![Todo image](https://camo.githubusercontent.com/c43d969d9d071c8342e9a69cdd6acb433c541f431127738974ce22290c46f2b8/68747470733a2f2f692e696d6775722e636f6d2f4f764d5a4273392e6a7067)
This list keeps me focused and organised so I don't forget what
needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember
to do on a more in depth level.
## --
[ ] Setup paging \
[ ] HELP command
[ ] Setup a proper HEAP \
[ ] Setup a proper Stack \
[ ] Setup KMalloc and KFree \
[ ] Merge Functioning Feature branches into sandboxKernelDev \
[ ] Remove merged feature branches \
[ ] Merge sandboxKernelDev with dev \
[ ] Remove sandboxKernelDev branch \
[ ] Implement proper virtual filesystem