Compare commits
10 Commits
BasicGraph
...
0f730d3f4e
Author | SHA1 | Date | |
---|---|---|---|
0f730d3f4e | |||
bd256f2639 | |||
9dc7a05da1 | |||
59bcc17668 | |||
5f50f8c013 | |||
595a7d5163 | |||
e84d196b00 | |||
f71a3a8ed6 | |||
63ea825e2e | |||
a094f510d3 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,4 +1,3 @@
|
|||||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
*.svg filter=lfs diff=lfs merge=lfs -text
|
*.svg filter=lfs diff=lfs merge=lfs -text
|
||||||
demodisk.img filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,8 +1 @@
|
|||||||
build
|
build
|
||||||
CON
|
|
||||||
.vscode
|
|
||||||
isodir/
|
|
||||||
root/
|
|
||||||
*.iso
|
|
||||||
*.img
|
|
||||||
|
|
||||||
|
16
.vscode/c_cpp_properties.json
vendored
Normal file
16
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "gnu17",
|
||||||
|
"cppStandard": "gnu++14",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
62
Makefile
62
Makefile
@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
|
|||||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||||
|
|
||||||
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
|
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o
|
||||||
|
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
@ -21,27 +21,14 @@ INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ)
|
|||||||
|
|
||||||
all: clean build
|
all: clean build
|
||||||
|
|
||||||
build: build_kernel iso
|
build: build_kernel run
|
||||||
|
|
||||||
|
run:
|
||||||
|
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std
|
||||||
clean_iso:
|
|
||||||
if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi
|
|
||||||
if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi
|
|
||||||
|
|
||||||
iso: clean_iso clean build
|
|
||||||
mkdir -p root/boot/grub
|
|
||||||
cp build/myos.bin root/boot/myos.bin
|
|
||||||
cp src/grub.cfg root/boot/grub/grub.cfg
|
|
||||||
grub-mkrescue -o build/barinkOS.iso root
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo # -monitor stdio
|
|
||||||
test_iso:
|
|
||||||
$(EMULATOR) -cdrom build/barinkOS.iso -serial mon:stdio -vga std -display gtk -m 2G -cpu core2duo
|
|
||||||
|
|
||||||
build_kernel: $(OBJ_LINK_LIST)
|
build_kernel: $(OBJ_LINK_LIST)
|
||||||
$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
|
|
||||||
|
$(CC) -T $(SRC_DIR)/kernel/arch/i386/linker.ld -o $(BUILD_DIR)/myos.bin \
|
||||||
-ffreestanding -O2 -nostdlib $(OBJ_LINK_LIST) -lgcc
|
-ffreestanding -O2 -nostdlib $(OBJ_LINK_LIST) -lgcc
|
||||||
|
|
||||||
build_x86_64:
|
build_x86_64:
|
||||||
@ -52,47 +39,28 @@ clean:
|
|||||||
rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
|
rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.o:
|
$(BUILD_DIR)/kernel.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti -fpermissive
|
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/kterm.o:
|
$(BUILD_DIR)/kterm.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CC) -c $(SRC_DIR)/kernel/arch/i386/tty/kterm.c -o $(BUILD_DIR)/kterm.o $(CFLAGS) -std=gnu99
|
||||||
|
|
||||||
$(BUILD_DIR)/boot.o:
|
$(BUILD_DIR)/boot.o:
|
||||||
$(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o
|
$(AS) $(SRC_DIR)/kernel/arch/i386/boot.s -o $(BUILD_DIR)/boot.o
|
||||||
|
|
||||||
$(BUILD_DIR)/crti.o:
|
$(BUILD_DIR)/crti.o:
|
||||||
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
|
$(AS) $(SRC_DIR)/kernel/arch/i386/crti.s -o $(BUILD_DIR)/crti.o
|
||||||
|
|
||||||
$(BUILD_DIR)/crtn.o:
|
$(BUILD_DIR)/crtn.o:
|
||||||
$(AS) $(SRC_DIR)/kernel/crtn.s -o $(BUILD_DIR)/crtn.o
|
$(AS) $(SRC_DIR)/kernel/arch/i386/crtn.s -o $(BUILD_DIR)/crtn.o
|
||||||
|
|
||||||
$(BUILD_DIR)/io.o:
|
$(BUILD_DIR)/io.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/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:
|
$(BUILD_DIR)/MMU.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/idt.o:
|
$(BUILD_DIR)/idt.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/gdtc.o:
|
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
|
|
||||||
|
|
||||||
|
|
||||||
$(BUILD_DIR)/pic.o:
|
$(BUILD_DIR)/pic.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
$(BUILD_DIR)/string.o:
|
|
||||||
$(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
|
|
||||||
|
|
||||||
$(BUILD_DIR)/PhysicalMemoryManager.o:
|
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
|
|
||||||
|
|
||||||
$(BUILD_DIR)/vesa.o:
|
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/vesa/vesa.cpp -o $(BUILD_DIR)/vesa.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)/cursor.o:
|
|
||||||
$(CPP) -c $(SRC_DIR)/gui/cursor.cpp -o $(BUILD_DIR)/cursor.o $(CFLAGS) -fno-exceptions -fno-rtti
|
|
||||||
|
16
README.md
16
README.md
@ -6,24 +6,22 @@
|
|||||||
|
|
||||||
________________________
|
________________________
|
||||||
### Screenshot(s)
|
### Screenshot(s)
|
||||||
 \
|
|
||||||
It may not look like much but I am proud of it! We are in graphics mode.
|
|
||||||
|
|
||||||
 \
|
 \
|
||||||
The first scrolling boot screen. 😲
|
The first scrolling boot screen. 😲
|
||||||
|
|
||||||
|
|
||||||
 \
|
<img src="screenshots/WIP_interruptHandling.png"></img>
|
||||||
W.I.P - Working on interrupt handling
|
W.I.P - Working on interrupt handling
|
||||||
|
|
||||||
|
|
||||||
 \
|
|
||||||
Multiboot information can be read by the kernel.
|
|
||||||
________________________
|
________________________
|
||||||
|
|
||||||
### The goal
|
### The goal
|
||||||
Writing a hobby operating system to better understand the basic building blocks of any operating system.
|
Writing a hobby operating system to better understand the basic building blocks of any operating system.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
________________________
|
________________________
|
||||||
### Operating System Technical specs/details
|
### Operating System Technical specs/details
|
||||||
The operating system can print strings to the
|
The operating system can print strings to the
|
||||||
@ -31,8 +29,8 @@ screen. The terminal/screen has scrolling so the latest messages are visible on
|
|||||||
|
|
||||||
________________________
|
________________________
|
||||||
### Planning
|
### Planning
|
||||||
[See TODO](todo.md) \
|
[See TODO](TODO.md)
|
||||||
[See Features](features.md)
|
|
||||||
________________________
|
________________________
|
||||||
### Docs
|
### Docs
|
||||||
[Intro](docs/Intro.md) \
|
[Intro](docs/Intro.md) \
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
<input type="checkbox" checked/> Setup Cross-Compiler \
|
<input type="checkbox" checked/> Setup Cross-Compiler \
|
||||||
<input type="checkbox" checked/> Multiboot to kernel \
|
<input type="checkbox" checked/> Multiboot to kernel \
|
||||||
<input type="checkbox" checked/> Printing string to the screen \
|
<input type="checkbox" checked/> Printing string to the screen \
|
||||||
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
|
<input type="checkbox" /> Printing values/numbers to the screen (a.k.k itoa) \
|
||||||
<input type="checkbox" checked/> Extend Multiboot implementation \
|
<input type="checkbox" /> Extend Multiboot implementation \
|
||||||
<input type="checkbox" checked/> Output to serial port \
|
<input type="checkbox" checked/> Output to serial port \
|
||||||
<input type="checkbox" checked/> Move to protected mode \
|
<input type="checkbox" /> Move to protected mode \
|
||||||
<input type="checkbox" checked/> Enabel CMOS clock \
|
<input type="checkbox" /> Enabel CMOS clock \
|
||||||
<input type="checkbox" /> Time measurement (PIC &| PIT) \
|
<input type="checkbox" /> Time measurement (PIC &| PIT) \
|
||||||
<input type="checkbox" /> Detect CPU speed \
|
<input type="checkbox" /> Detect CPU speed \
|
||||||
<input type="checkbox" checked/> Interrupt / exception system (API) \
|
<input type="checkbox" /> Interrupt / exception system (API) \
|
||||||
|
|
||||||
<input type="checkbox" checked/> Plan your memory map (virtual, and physical) : decide where you want the data to be. \
|
<input type="checkbox" /> 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" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
|
||||||
<input type="checkbox" /> Enable SIMD Extensions (SSE)
|
<input type="checkbox" /> Enable SIMD Extensions (SSE)
|
||||||
|
|
||||||
@ -23,13 +23,13 @@
|
|||||||
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
|
<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" /> ATAPI support \
|
||||||
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
|
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
|
||||||
<input type="checkbox" checked/> Memory Management (MMU)
|
<input type="checkbox" /> Memory Management (MMU)\
|
||||||
<input type="checkbox" /> Preemptive multi tasking \
|
<input type="checkbox" /> Preemptive multi tasking
|
||||||
<input type="checkbox" /> Processes \
|
<input type="checkbox" /> Processes
|
||||||
<input type="checkbox" /> Threads
|
<input type="checkbox" /> Threads
|
||||||
<input type="checkbox" /> Scheduling (SRV2 Unix OR Priority Based Round Robin) \
|
<input type="checkbox" /> Scheduling (SRV2 Unix OR Priority Based Round Robin) \
|
||||||
<input type="checkbox" /> System V ABI compliance (partially) \
|
<input type="checkbox" /> System V ABI compliance (partially)
|
||||||
<input type="checkbox" /> POSIX compliance (partially) \
|
<input type="checkbox" /> POSIX compliance (partially)
|
||||||
<input type="checkbox" /> RPC - for interprocess communication \
|
<input type="checkbox" /> RPC - for interprocess communication \
|
||||||
<input type="checkbox" /> Sync primitives - Semaphores, Mutexes, spinlocks et al. \
|
<input type="checkbox" /> Sync primitives - Semaphores, Mutexes, spinlocks et al. \
|
||||||
<input type="checkbox" /> Basic Terminal \
|
<input type="checkbox" /> Basic Terminal \
|
||||||
@ -37,4 +37,4 @@
|
|||||||
<input type="checkbox" /> Basic Window server/client \
|
<input type="checkbox" /> Basic Window server/client \
|
||||||
## Support for more filesystems if I like the challenge in writing these ...
|
## Support for more filesystems if I like the challenge in writing these ...
|
||||||
<input type="checkbox" /> FAT Filesystem \
|
<input type="checkbox" /> FAT Filesystem \
|
||||||
<input type="checkbox" /> EXT2 Filesystem
|
<input type="checkbox" /> EXT2 Filesystem \
|
BIN
screenshots/BarinkOS_VBE_GRAPHICS.png
(Stored with Git LFS)
BIN
screenshots/BarinkOS_VBE_GRAPHICS.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 16 KiB |
BIN
screenshots/multiboot.png
(Stored with Git LFS)
BIN
screenshots/multiboot.png
(Stored with Git LFS)
Binary file not shown.
@ -1,3 +0,0 @@
|
|||||||
menuentry "BarinkOS"{
|
|
||||||
multiboot /boot/myos.bin
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
class Graphics {
|
|
||||||
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
class Widget{
|
|
||||||
virtual void draw();
|
|
||||||
|
|
||||||
};
|
|
@ -1,17 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#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,
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,33 +0,0 @@
|
|||||||
#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 );
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
#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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
@ -1,10 +1,9 @@
|
|||||||
#include "PageDirectory.h"
|
#include "MMU.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PageDirectory::enable(){
|
void MMU::enable(){
|
||||||
// https://wiki.osdev.org/Setting_Up_Paging
|
|
||||||
//set each entry to not present
|
//set each entry to not present
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 1024; i++)
|
for(i = 0; i < 1024; i++)
|
||||||
@ -35,13 +34,8 @@ void PageDirectory::enable(){
|
|||||||
enablePaging();
|
enablePaging();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
|
uint32_t MMU::readTableEntry(int entry){
|
||||||
{
|
return this->page_directory[entry];
|
||||||
from = from & 0xFFFFF000; // Discard the bits we don't want
|
|
||||||
for (; size > 0; from += 4096, first_pte++)
|
|
||||||
{
|
|
||||||
*first_pte = from | 1; // makr page present.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
15
src/kernel/MMU.h
Normal file
15
src/kernel/MMU.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern "C" void loadPageDirectory (long unsigned int* addr );
|
||||||
|
extern "C" void enablePaging();
|
||||||
|
|
||||||
|
class MMU {
|
||||||
|
public:
|
||||||
|
void enable ();
|
||||||
|
uint32_t readTableEntry(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||||
|
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
|
||||||
|
};
|
566
src/kernel/arch/i386/boot.s
Normal file
566
src/kernel/arch/i386/boot.s
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interupt handlers
|
||||||
|
*/
|
||||||
|
# NOTE: I have no clue how I should use these macros.
|
||||||
|
# Have tried to use them in a myriad of ways, none would actually work
|
||||||
|
.macro irs_NoErrCode code:req
|
||||||
|
.globl irs\code
|
||||||
|
irs\code:
|
||||||
|
cli
|
||||||
|
pushb $0
|
||||||
|
pushb \code
|
||||||
|
jmp irs_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro irs_ErrCode code
|
||||||
|
.globl irs\code
|
||||||
|
irs\code:
|
||||||
|
cli
|
||||||
|
pushb \code
|
||||||
|
jmp irs_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.globl irs0
|
||||||
|
irs0:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $0
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs1
|
||||||
|
irs1:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $1
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs2
|
||||||
|
irs2:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $2
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs3
|
||||||
|
irs3:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $3
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs4
|
||||||
|
irs4:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $4
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs5
|
||||||
|
irs5:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $5
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs6
|
||||||
|
irs6:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $6
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs7
|
||||||
|
irs7:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $7
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs8
|
||||||
|
irs8:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $8
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs9
|
||||||
|
irs9:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $9
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs10
|
||||||
|
irs10:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $10
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs11
|
||||||
|
irs11:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $11
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs12
|
||||||
|
irs12:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $12
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs13
|
||||||
|
irs13:
|
||||||
|
cli
|
||||||
|
push $13
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs14
|
||||||
|
irs14:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $14
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs15
|
||||||
|
irs15:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $15
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs16
|
||||||
|
irs16:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $16
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs17
|
||||||
|
irs17:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $17
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs18
|
||||||
|
irs18:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $18
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs19
|
||||||
|
irs19:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $19
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs20
|
||||||
|
irs20:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $20
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs21
|
||||||
|
irs21:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $21
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs22
|
||||||
|
irs22:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $22
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs23
|
||||||
|
irs23:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $23
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs24
|
||||||
|
irs24:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $24
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs25
|
||||||
|
irs25:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $25
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs26
|
||||||
|
irs26:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $26
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs27
|
||||||
|
irs27:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $27
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs28
|
||||||
|
irs28:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $28
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs29
|
||||||
|
irs29:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $29
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs30
|
||||||
|
irs30:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $30
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
.globl irs31
|
||||||
|
irs31:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $31
|
||||||
|
jmp irs_common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.globl irq0
|
||||||
|
irq0:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $0
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq1
|
||||||
|
irq1:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $1
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq2
|
||||||
|
irq2:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $2
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq3
|
||||||
|
irq3:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $3
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq4
|
||||||
|
irq4:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $4
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq5
|
||||||
|
irq5:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $5
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq6
|
||||||
|
irq6:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $6
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq7
|
||||||
|
irq7:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $7
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq8
|
||||||
|
irq8:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $8
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq9
|
||||||
|
irq9:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $9
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq10
|
||||||
|
irq10:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $10
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq11
|
||||||
|
irq11:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $11
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
|
||||||
|
.globl irq12
|
||||||
|
irq12:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $12
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq13
|
||||||
|
irq13:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $13
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq14
|
||||||
|
irq14:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $14
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
.globl irq15
|
||||||
|
irq15:
|
||||||
|
cli
|
||||||
|
push $0
|
||||||
|
push $15
|
||||||
|
jmp irq_common
|
||||||
|
|
||||||
|
irq_common:
|
||||||
|
pusha
|
||||||
|
|
||||||
|
mov %ds, %ax
|
||||||
|
push %eax
|
||||||
|
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
|
||||||
|
call irq_handler
|
||||||
|
|
||||||
|
pop %eax
|
||||||
|
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
|
||||||
|
popa
|
||||||
|
add $8, %esp # cleans push error and irs code
|
||||||
|
sti
|
||||||
|
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
|
|
||||||
|
irs_common:
|
||||||
|
pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
||||||
|
|
||||||
|
|
||||||
|
mov %ds, %ax
|
||||||
|
push %eax
|
||||||
|
|
||||||
|
/* load the kernel data segment descriptor*/
|
||||||
|
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
|
||||||
|
call irs_handler
|
||||||
|
|
||||||
|
pop %eax
|
||||||
|
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
|
||||||
|
popa
|
||||||
|
add $8, %esp # cleans push error and irs code
|
||||||
|
sti
|
||||||
|
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
|
.globl idt_flush
|
||||||
|
idt_flush:
|
||||||
|
mov 4(%esp), %eax
|
||||||
|
lidt (%eax)
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl enablePaging
|
||||||
|
enablePaging:
|
||||||
|
push %ebp
|
||||||
|
mov %esp, %ebp
|
||||||
|
mov %cr0, %eax
|
||||||
|
or $0x80000000, %eax
|
||||||
|
mov %eax, %cr0
|
||||||
|
mov %ebp, %esp
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl loadPageDirectory
|
||||||
|
loadPageDirectory:
|
||||||
|
push %ebp
|
||||||
|
mov %esp, %ebp
|
||||||
|
mov 8(%esp), %eax
|
||||||
|
mov %eax, %cr3
|
||||||
|
mov %ebp, %esp
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
.type _start, @function
|
||||||
|
_start:
|
||||||
|
/*Setup the stack pointer to point to the beginning of our stack */
|
||||||
|
/* I believe its a hight 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
|
||||||
|
load_gdt:
|
||||||
|
lgdt gdt
|
||||||
|
|
||||||
|
# set the segment selecters
|
||||||
|
|
||||||
|
movw $0x10, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
movw %ax, %ss
|
||||||
|
ljmp $0x08, $flush
|
||||||
|
|
||||||
|
flush:
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Tell processor to use our gdt*/
|
||||||
|
gdt:
|
||||||
|
.word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons
|
||||||
|
.int gdt_start # linear address of our GDT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.att_syntax
|
||||||
|
|
||||||
|
|
||||||
|
.size _start, . - _start
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the GDT
|
||||||
|
*/
|
||||||
|
.section .data
|
||||||
|
gdt_start:
|
||||||
|
gdt_null:
|
||||||
|
.long 0x0
|
||||||
|
.long 0x0
|
||||||
|
|
||||||
|
gdt_kcode:
|
||||||
|
.word 0xFFFF # limit
|
||||||
|
.word 0x0 # base
|
||||||
|
.byte 0x0 # base
|
||||||
|
.byte 0b10011010 # 1st flags | type flags
|
||||||
|
.byte 0b11001111 # 2nd flags | limit
|
||||||
|
.byte 0x0 # base
|
||||||
|
|
||||||
|
gdt_kdata:
|
||||||
|
.word 0xFFFF # limit
|
||||||
|
.word 0x0 # base
|
||||||
|
.byte 0x0 # base
|
||||||
|
.byte 0b10010010 # 1st flags | type flags
|
||||||
|
.byte 0b11001111 # 2nd flags | limit
|
||||||
|
.byte 0x0 # base
|
||||||
|
gdt_end:
|
29
src/kernel/arch/i386/gdt/gdtc.cpp
Normal file
29
src/kernel/arch/i386/gdt/gdtc.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "gdtc.h"
|
||||||
|
|
||||||
|
|
||||||
|
gdtEntry_t gdt[3];
|
||||||
|
|
||||||
|
|
||||||
|
void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
|
||||||
|
uint8_t gran){
|
||||||
|
gdt[num].lBase = (base & 0xFFFF);
|
||||||
|
gdt[num].mBase = (base >> 16) & 0xFF;
|
||||||
|
gdt[num].hBase = (base >> 24) & 0xFF;
|
||||||
|
|
||||||
|
gdt[num].lLimit = (limit & 0xFFFF);
|
||||||
|
gdt[num].granularity = ((limit >> 16) & 0x0F);
|
||||||
|
|
||||||
|
gdt[num].granularity |= (gran & 0xF0);
|
||||||
|
gdt[num].access = access;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupGdt(){
|
||||||
|
gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1;
|
||||||
|
gdtPointer.base = &gdt;
|
||||||
|
|
||||||
|
gdtSetGate(0, 0, 0, 0, 0);
|
||||||
|
gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||||
|
gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||||
|
|
||||||
|
loadGdt();
|
||||||
|
}
|
20
src/kernel/arch/i386/gdt/gdtc.h
Normal file
20
src/kernel/arch/i386/gdt/gdtc.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
extern "c"{
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t lLimit;
|
||||||
|
uint16_t lBase;
|
||||||
|
uint8_t mBase;
|
||||||
|
uint8_t access;
|
||||||
|
uint8_t granularity;
|
||||||
|
uint8_t hBase;
|
||||||
|
} gdtEntry_t;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} gdtPointer;
|
||||||
|
|
||||||
|
extern void loadGdt();
|
||||||
|
void setupGdt();
|
||||||
|
}
|
@ -24,9 +24,6 @@ void irs_handler (registers regs) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +41,7 @@ void irq_handler (registers regs) {
|
|||||||
// Keyboard interrupt !!
|
// Keyboard interrupt !!
|
||||||
|
|
||||||
int scan;
|
int scan;
|
||||||
/*register*/int i;
|
register int i;
|
||||||
|
|
||||||
// Read scancode
|
// Read scancode
|
||||||
|
|
@ -5,7 +5,10 @@
|
|||||||
#include "../vga/colors.h"
|
#include "../vga/colors.h"
|
||||||
#include "../pic/pic.h"
|
#include "../pic/pic.h"
|
||||||
|
|
||||||
#include "../tty/kterm.h"
|
extern "C"{
|
||||||
|
#include "../tty/kterm.h"
|
||||||
|
}
|
||||||
|
#define AS_KERNEL() ( kterm_writestring("[KERNEL]:"))
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
@ -6,11 +6,10 @@ ENTRY(_start)
|
|||||||
kernel image. */
|
kernel image. */
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||||
loaded at by the bootloader. */
|
loaded at by the bootloader. */
|
||||||
. = 1M;
|
. = 1M;
|
||||||
kernel_begin = .;
|
|
||||||
/* First put the multiboot header, as it is required to be put very early
|
/* First put the multiboot header, as it is required to be put very early
|
||||||
early in the image or the bootloader won't recognize the file format.
|
early in the image or the bootloader won't recognize the file format.
|
||||||
Next we'll put the .text section. */
|
Next we'll put the .text section. */
|
||||||
@ -41,7 +40,4 @@ SECTIONS
|
|||||||
|
|
||||||
/* The compiler may produce other sections, by default it will put them in
|
/* The compiler may produce other sections, by default it will put them in
|
||||||
a segment with the same name. Simply add stuff here as needed. */
|
a segment with the same name. Simply add stuff here as needed. */
|
||||||
|
|
||||||
kernel_end = .;
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../io.h"
|
#include "../../../io.h"
|
||||||
|
|
||||||
#define PIC1 0x20 /* IO base address for master PIC */
|
#define PIC1 0x20 /* IO base address for master PIC */
|
||||||
#define PIC2 0xA0 /* IO base address for slave PIC */
|
#define PIC2 0xA0 /* IO base address for slave PIC */
|
||||||
@ -49,7 +49,7 @@ void PIC_sendEOI (unsigned char irq);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//static uint16_t __pic_get_irq_reg(int ocw3);
|
static uint16_t __pic_get_irq_reg(int ocw3);
|
||||||
uint16_t pic_get_irr(void);
|
uint16_t pic_get_irr(void);
|
||||||
uint16_t pic_get_isr(void);
|
uint16_t pic_get_isr(void);
|
||||||
|
|
@ -1,5 +1,4 @@
|
|||||||
#include "kterm.h"
|
#include "kterm.h"
|
||||||
|
|
||||||
static const size_t VGA_WIDTH = 80;
|
static const size_t VGA_WIDTH = 80;
|
||||||
static const size_t VGA_HEIGHT = 25;
|
static const size_t VGA_HEIGHT = 25;
|
||||||
|
|
||||||
@ -47,48 +46,6 @@ void kterm_putat (char c, uint8_t color, size_t x, size_t y ) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){
|
|
||||||
outb(0x3D4, 0x0A);
|
|
||||||
outb(0x3D5, (inb(0x3D5) & 0xC0) | start_cursor);
|
|
||||||
|
|
||||||
outb(0x3D4, 0x0B);
|
|
||||||
outb(0x3D5, (inb(0x3D5) & 0xE0) | end_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_cursor()
|
|
||||||
{
|
|
||||||
outb(0x3D4, 0x0A);
|
|
||||||
outb(0x3D5, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void update_cursor(int x, int y){
|
|
||||||
uint16_t pos = y * VGA_WIDTH + x;
|
|
||||||
|
|
||||||
outb(0x3D4, 0x0F);
|
|
||||||
outb(0x3D5, (uint8_t) (pos & 0xFF));
|
|
||||||
outb(0x3D4, 0x0E);
|
|
||||||
outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get_cursor_position(){
|
|
||||||
uint16_t pos = 0;
|
|
||||||
outb(0x3D4, 0x0F);
|
|
||||||
pos |= inb(0x3D5);
|
|
||||||
outb(0x3D4, 0x0E);
|
|
||||||
pos |= ((uint16_t) inb(0x3D5)) << 8;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_cursor_x (uint16_t cursor_pos) {
|
|
||||||
return cursor_pos % VGA_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_cursor_y (uint16_t cursor_pos ) {
|
|
||||||
return cursor_pos / VGA_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With the help from:
|
* With the help from:
|
||||||
@ -106,7 +63,6 @@ void kterm_scrollup(){
|
|||||||
|
|
||||||
void kterm_put (char c) {
|
void kterm_put (char c) {
|
||||||
if(++kterm_column == VGA_WIDTH || c == '\n' ) {
|
if(++kterm_column == VGA_WIDTH || c == '\n' ) {
|
||||||
update_cursor(kterm_column , kterm_row);
|
|
||||||
kterm_column = 0;
|
kterm_column = 0;
|
||||||
if(kterm_row == VGA_HEIGHT-1 ) {
|
if(kterm_row == VGA_HEIGHT-1 ) {
|
||||||
kterm_scrollup();
|
kterm_scrollup();
|
||||||
@ -137,7 +93,7 @@ void kterm_writestring(const char* data ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void itoa (char *buf, int base, int d) {
|
static void itoa (char *buf, int base, int d) {
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
char *p1, *p2;
|
char *p1, *p2;
|
||||||
unsigned long ud = d;
|
unsigned long ud = d;
|
||||||
@ -174,7 +130,7 @@ void itoa (char *buf, int base, int d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void printf ( const char *format, ...) {
|
void printf ( const char *format, ...) {
|
||||||
return;
|
|
||||||
char **arg = (char **)&format;
|
char **arg = (char **)&format;
|
||||||
int c;
|
int c;
|
||||||
char buf[20];
|
char buf[20];
|
@ -5,19 +5,12 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "../vga/colors.h"
|
#include "../vga/colors.h"
|
||||||
#include "../io.h"
|
|
||||||
|
|
||||||
extern "C"{
|
|
||||||
#include "./../../libc/include/string.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
void kterm_init();
|
void kterm_init();
|
||||||
|
|
||||||
/* Kernel terminal - Colour functions*/
|
|
||||||
void kterm_resetcolor();
|
void kterm_resetcolor();
|
||||||
void kterm_setcolor(uint8_t);
|
void kterm_setcolor(uint8_t);
|
||||||
|
|
||||||
/* Kernel terminal - Printing function */
|
|
||||||
void kterm_putat(char, uint8_t, size_t, size_t);
|
void kterm_putat(char, uint8_t, size_t, size_t);
|
||||||
void kterm_put(char);
|
void kterm_put(char);
|
||||||
void kterm_write(const char*, size_t);
|
void kterm_write(const char*, size_t);
|
||||||
@ -25,17 +18,9 @@ void kterm_writestring(const char*);
|
|||||||
void kterm_scrollup();
|
void kterm_scrollup();
|
||||||
|
|
||||||
|
|
||||||
/* Kernel terminal - Cursor functions */
|
|
||||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor );
|
|
||||||
void disable_cursor();
|
|
||||||
void update_cursor(int x, int y);
|
|
||||||
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, ...);
|
void printf ( const char *format, ...);
|
||||||
|
|
||||||
|
static void itoa (char *buf, int base, int d);
|
||||||
|
|
||||||
#define KernelTag "[Kernel]: "
|
#define KernelTag "[Kernel]: "
|
||||||
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
@ -1,108 +0,0 @@
|
|||||||
#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;
|
|
||||||
|
|
||||||
/* Print out the flags */
|
|
||||||
printf("flags = 0x%8x\n", (unsigned) mbi->flags);
|
|
||||||
|
|
||||||
/* Are mem_* valid? */
|
|
||||||
if ( CHECK_FLAG(mbi->flags,0)){
|
|
||||||
printf("mem_lower = %uKB, mem_upper = %uKB\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* is boot device valid ? */
|
|
||||||
if (CHECK_FLAG (mbi->flags, 1)){
|
|
||||||
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* is the command line passed? */
|
|
||||||
if (CHECK_FLAG ( mbi->flags,2)){
|
|
||||||
printf("cmdline = %s\n", (char *) mbi->cmdline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Are mods_* valid? */
|
|
||||||
if(CHECK_FLAG ( mbi->flags, 3)){
|
|
||||||
multiboot_module_t *mod;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
#include <cpuid.h> // NOTE: Only available in GCC
|
|
||||||
// NOT currently usefull!
|
|
||||||
/* static int get_model(){
|
|
||||||
int ebx, unused;
|
|
||||||
__cpuid(0, unused, ebx, unused, unused);
|
|
||||||
return ebx;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CPUID_FEAT_EDX_APIC = 1 << 9
|
|
||||||
};
|
|
||||||
static int check_apic (){
|
|
||||||
unsigned int eax, unused, edx;
|
|
||||||
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
|
||||||
return edx & CPUID_FEAT_EDX_APIC;
|
|
||||||
}
|
|
||||||
*/
|
|
@ -1,17 +0,0 @@
|
|||||||
#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
|
|
@ -1,136 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
#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 );
|
|
@ -1,19 +0,0 @@
|
|||||||
.global LoadGlobalDescriptorTable
|
|
||||||
|
|
||||||
LoadGlobalDescriptorTable:
|
|
||||||
lgdt gdtDescriptor
|
|
||||||
|
|
||||||
movw $16, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
movw %ax, %ss
|
|
||||||
|
|
||||||
jmp $8,$flush
|
|
||||||
|
|
||||||
flush:
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
#include "gdtc.h"
|
|
||||||
#include "../tty/kterm.h"
|
|
||||||
|
|
||||||
#define NULL_SEGMENT 0
|
|
||||||
#define KERNEL_CODE_SEGMENT 1
|
|
||||||
#define KERNEL_DATA_SEGMENT 2
|
|
||||||
#define USER_CODE_SEGMENT 3
|
|
||||||
#define USER_DATA_SEGMENT 4
|
|
||||||
|
|
||||||
SegmentDescriptor GlobalDescriptorTable[5];
|
|
||||||
GlobalDescriptorTableDescriptor gdtDescriptor;
|
|
||||||
|
|
||||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){
|
|
||||||
GlobalDescriptorTable[which].base_low = (base & 0xFFFF );
|
|
||||||
GlobalDescriptorTable[which].base_middle = (base >> 6) & 0xFF;
|
|
||||||
GlobalDescriptorTable[which].base_high = (base >> 24) & 0xFF;
|
|
||||||
|
|
||||||
GlobalDescriptorTable[which].limit_low = (limit & 0xFFFF);
|
|
||||||
GlobalDescriptorTable[which].granularity = ((limit >> 16) & 0x0F);
|
|
||||||
|
|
||||||
GlobalDescriptorTable[which].granularity |= (granularity & 0xF0);
|
|
||||||
GlobalDescriptorTable[which].access = access;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void initGDT(){
|
|
||||||
|
|
||||||
// NULL segment
|
|
||||||
add_descriptor(NULL_SEGMENT, 0,0,0,0);
|
|
||||||
|
|
||||||
// Kernel Code Segment
|
|
||||||
add_descriptor(KERNEL_CODE_SEGMENT, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
|
||||||
|
|
||||||
// Kernel Data Segment
|
|
||||||
add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
|
||||||
|
|
||||||
// User Code Segment
|
|
||||||
// TODO:
|
|
||||||
|
|
||||||
// User Data Segement
|
|
||||||
// TODO:
|
|
||||||
|
|
||||||
// init Gdt Descriptor
|
|
||||||
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
|
|
||||||
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
|
|
||||||
|
|
||||||
printf("Hello GDT!\n");
|
|
||||||
|
|
||||||
|
|
||||||
LoadGlobalDescriptorTable();
|
|
||||||
|
|
||||||
// while (true)
|
|
||||||
// asm volatile("hlt");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct SegmentDescriptor {
|
|
||||||
unsigned short limit_low;
|
|
||||||
unsigned short base_low;
|
|
||||||
unsigned char base_middle;
|
|
||||||
unsigned char access;
|
|
||||||
unsigned char granularity;
|
|
||||||
unsigned char base_high;
|
|
||||||
}__attribute__((packed));
|
|
||||||
|
|
||||||
|
|
||||||
struct GlobalDescriptorTableDescriptor{
|
|
||||||
unsigned short limit;
|
|
||||||
unsigned int base;
|
|
||||||
}__attribute__((packed));
|
|
||||||
|
|
||||||
extern SegmentDescriptor GlobalDescriptorTable[];
|
|
||||||
extern GlobalDescriptorTableDescriptor gdtDescriptor;
|
|
||||||
|
|
||||||
|
|
||||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity );
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void LoadGlobalDescriptorTable();
|
|
||||||
void initGDT();
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
.globl idt_flush
|
|
||||||
idt_flush:
|
|
||||||
mov 4(%esp), %eax
|
|
||||||
lidt (%eax)
|
|
||||||
ret
|
|
@ -1,24 +1,19 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
unsigned char inb_p(unsigned short ){
|
unsigned char inb_p(unsigned short ){
|
||||||
// TODO: implement me!
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
unsigned short inw(unsigned short ){
|
unsigned short inw(unsigned short ){
|
||||||
// TODO: implement me!
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
unsigned short inw_p(unsigned short ){
|
unsigned short inw_p(unsigned short ){
|
||||||
// TODO: implement me!
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
unsigned int inl(unsigned short ){
|
unsigned int inl(unsigned short ){
|
||||||
// TODO: implement me!
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
unsigned int inl_p(unsigned short ){
|
unsigned int inl_p(unsigned short ){
|
||||||
// TODO: implement me!
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
.globl irq0
|
|
||||||
irq0:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $0
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq1
|
|
||||||
irq1:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $1
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq2
|
|
||||||
irq2:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $2
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq3
|
|
||||||
irq3:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $3
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq4
|
|
||||||
irq4:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $4
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq5
|
|
||||||
irq5:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $5
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq6
|
|
||||||
irq6:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $6
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq7
|
|
||||||
irq7:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $7
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq8
|
|
||||||
irq8:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $8
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq9
|
|
||||||
irq9:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $9
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq10
|
|
||||||
irq10:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $10
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq11
|
|
||||||
irq11:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $11
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
|
|
||||||
.globl irq12
|
|
||||||
irq12:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $12
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq13
|
|
||||||
irq13:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $13
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq14
|
|
||||||
irq14:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $14
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
.globl irq15
|
|
||||||
irq15:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $15
|
|
||||||
jmp irq_common
|
|
||||||
|
|
||||||
irq_common:
|
|
||||||
pusha
|
|
||||||
|
|
||||||
mov %ds, %ax
|
|
||||||
push %eax
|
|
||||||
|
|
||||||
mov $0x10, %ax
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
|
|
||||||
call irq_handler
|
|
||||||
|
|
||||||
pop %eax
|
|
||||||
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
|
|
||||||
popa
|
|
||||||
add $8, %esp # cleans push error and irs code
|
|
||||||
sti
|
|
||||||
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
|
@ -1,256 +0,0 @@
|
|||||||
/*
|
|
||||||
* Interupt handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
.globl irs0
|
|
||||||
irs0:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $0
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs1
|
|
||||||
irs1:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $1
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs2
|
|
||||||
irs2:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $2
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs3
|
|
||||||
irs3:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $3
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs4
|
|
||||||
irs4:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $4
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs5
|
|
||||||
irs5:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $5
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs6
|
|
||||||
irs6:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $6
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs7
|
|
||||||
irs7:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $7
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs8
|
|
||||||
irs8:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $8
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs9
|
|
||||||
irs9:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $9
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs10
|
|
||||||
irs10:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $10
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs11
|
|
||||||
irs11:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $11
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs12
|
|
||||||
irs12:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $12
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs13
|
|
||||||
irs13:
|
|
||||||
cli
|
|
||||||
push $13
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs14
|
|
||||||
irs14:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $14
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs15
|
|
||||||
irs15:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $15
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs16
|
|
||||||
irs16:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $16
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs17
|
|
||||||
irs17:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $17
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs18
|
|
||||||
irs18:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $18
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs19
|
|
||||||
irs19:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $19
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs20
|
|
||||||
irs20:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $20
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs21
|
|
||||||
irs21:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $21
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs22
|
|
||||||
irs22:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $22
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs23
|
|
||||||
irs23:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $23
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs24
|
|
||||||
irs24:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $24
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs25
|
|
||||||
irs25:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $25
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs26
|
|
||||||
irs26:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $26
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs27
|
|
||||||
irs27:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $27
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs28
|
|
||||||
irs28:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $28
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs29
|
|
||||||
irs29:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $29
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs30
|
|
||||||
irs30:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $30
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
.globl irs31
|
|
||||||
irs31:
|
|
||||||
cli
|
|
||||||
push $0
|
|
||||||
push $31
|
|
||||||
jmp irs_common
|
|
||||||
|
|
||||||
|
|
||||||
irs_common:
|
|
||||||
pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
|
||||||
|
|
||||||
|
|
||||||
mov %ds, %ax
|
|
||||||
push %eax
|
|
||||||
|
|
||||||
/* load the kernel data segment descriptor*/
|
|
||||||
|
|
||||||
mov $0x10, %ax
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
|
|
||||||
call irs_handler
|
|
||||||
|
|
||||||
pop %eax
|
|
||||||
|
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
|
|
||||||
popa
|
|
||||||
add $8, %esp # cleans push error and irs code
|
|
||||||
sti
|
|
||||||
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
|
@ -1,51 +1,230 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#define GB4 524288
|
/**
|
||||||
#define GB2 262144
|
* simple delay function
|
||||||
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 );
|
void delay(int t){
|
||||||
|
volatile int i,j;
|
||||||
|
for(i=0;i<t;i++)
|
||||||
|
for(j=0;j<25000;j++)
|
||||||
|
asm("NOP");
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
public:
|
||||||
|
Test();
|
||||||
|
void printMe();
|
||||||
|
~Test();
|
||||||
|
};
|
||||||
|
|
||||||
|
Test::Test(){
|
||||||
|
kterm_writestring("Create a test object\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
void Test::printMe(){
|
||||||
|
kterm_writestring("testObject.printMe()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Test::~Test(){
|
||||||
|
kterm_writestring("Destroy testObject! Bye bye\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PORT 0x3f8
|
||||||
|
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
|
||||||
|
outb(PORT + 1, 0x00); // (hi byte)
|
||||||
|
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||||
|
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||||
|
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||||
|
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||||
|
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||||
|
|
||||||
|
// Check if serial is faulty (i.e: not same byte as sent)
|
||||||
|
if(inb(PORT + 0) != 0xAE) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If serial is not faulty set it in normal operation mode
|
||||||
|
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
||||||
|
outb(PORT + 4, 0x0F);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_transmit_empty() {
|
||||||
|
return inb(PORT + 5) & 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_serial(char a) {
|
||||||
|
while (is_transmit_empty() == 0);
|
||||||
|
|
||||||
|
outb(PORT,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_received() {
|
||||||
|
return inb(PORT + 5) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char read_serial() {
|
||||||
|
while (serial_received() == 0);
|
||||||
|
|
||||||
|
return inb(PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_serial(const char* string ){
|
||||||
|
for(size_t i = 0; i < strlen(string); i ++){
|
||||||
|
write_serial(string[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_serial(){
|
||||||
|
/** Serial test **/
|
||||||
|
kterm_writestring("Writing to COM1 serial port:");
|
||||||
|
init_serial();
|
||||||
|
write_serial('A');
|
||||||
|
write_serial('B');
|
||||||
|
write_serial('C');
|
||||||
|
write_serial('D');
|
||||||
|
write_serial('E');
|
||||||
|
|
||||||
|
char Character_received = read_serial();
|
||||||
|
kterm_writestring("\n");
|
||||||
|
kterm_writestring("received from COM 1: \n");
|
||||||
|
kterm_put(Character_received);
|
||||||
|
|
||||||
|
kterm_writestring("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void early_main(unsigned long magic, unsigned long addr){
|
||||||
|
|
||||||
extern "C" void early_main(unsigned long magic, unsigned long addr){
|
|
||||||
/** initialize terminal interface */
|
/** initialize terminal interface */
|
||||||
// kterm_init();
|
kterm_init();
|
||||||
|
|
||||||
|
multiboot_info_t *mbi;
|
||||||
|
|
||||||
printf("Magic flag 0x%8x\n", magic);
|
|
||||||
printf("Magic must be 0x%8x\n", MULTIBOOT_BOOTLOADER_MAGIC);
|
|
||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||||
printf("Invalid magic number: 0x%8x\n", magic);
|
printf("Invalid magic number: 0x%x\n", (unsigned) magic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckMBT( (multiboot_info_t *) addr);
|
/* Set MBI to the addresss of the multiboot information structure*/
|
||||||
|
mbi = (multiboot_info_t *) addr;
|
||||||
|
|
||||||
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
/* Print out the flags */
|
||||||
|
printf("flags = 0x%x\n", (unsigned) mbi->flags);
|
||||||
|
|
||||||
|
/* Are mem_* valid? */
|
||||||
|
if ( CHECK_FLAG(mbi->flags,0)){
|
||||||
|
printf("mem_lower = %uKB, mem_upper = %uKB\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is boot device valid ? */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 1)){
|
||||||
|
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is the command line passed? */
|
||||||
|
if (CHECK_FLAG ( mbi->flags,2)){
|
||||||
|
printf("cmdline = %s\n", (char *) mbi->cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are mods_* valid? */
|
||||||
|
if(CHECK_FLAG ( mbi->flags, 3)){
|
||||||
|
multiboot_module_t *mod;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// AAAAAH memory map, Yes please!
|
||||||
/* Are mmap_* valid? */
|
/* Are mmap_* valid? */
|
||||||
if (CHECK_FLAG(mbt->flags, 6)){
|
if (CHECK_FLAG(mbi->flags, 6)){
|
||||||
PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/);
|
multiboot_memory_map_t *mmap;
|
||||||
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("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
||||||
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
(unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
|
||||||
}
|
|
||||||
|
|
||||||
initGDT();
|
for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr;
|
||||||
|
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
|
||||||
|
mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||||
kernel_main();
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void kernel_main (void) {
|
}
|
||||||
|
|
||||||
|
/* Draw diagonal blue line */
|
||||||
|
if (CHECK_FLAG (mbi->flags, 12)){
|
||||||
|
printf("Can draw!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_main (void) {
|
||||||
|
|
||||||
|
|
||||||
printf("call to init serial\n");
|
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
|
|
||||||
|
/** Setup the MMU **/
|
||||||
|
//kterm_writestring("Starting MMU...\n");
|
||||||
|
//auto mmu = MMU();
|
||||||
|
//mmu.enable();
|
||||||
|
//kterm_writestring("MMU enabled!\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** test interrupt handlers **/
|
||||||
|
//asm volatile ("int $0x03");
|
||||||
|
|
||||||
|
//asm volatile ("int $0x04");
|
||||||
|
|
||||||
while (true){
|
while (true){
|
||||||
//Read time indefinetely
|
//Read time indefinetely
|
||||||
read_rtc();
|
read_rtc();
|
||||||
@ -54,7 +233,13 @@ extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigne
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Lets start using the serial port for debugging .. **/
|
||||||
|
// Hopefully once we go into realmode or do something that
|
||||||
|
// cause the screen to go black.. this serial comms part will give
|
||||||
|
// some situational awareness
|
||||||
|
//Serial serialbus = Serial::init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,33 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
extern "C"{
|
extern "C" {
|
||||||
#include "../libc/include/string.h"
|
#include "../libc/include/string.h"
|
||||||
|
#include "arch/i386/tty/kterm.h"
|
||||||
}
|
}
|
||||||
#include "vga/VBE.h"
|
|
||||||
#include "tty/kterm.h"
|
|
||||||
|
|
||||||
#include "./bootloader/multiboot.h"
|
|
||||||
#include "bootcheck.h"
|
|
||||||
#include "memory/PhysicalMemoryManager.h"
|
|
||||||
|
|
||||||
#include "gdt/gdtc.h"
|
|
||||||
#include "idt/idt.h"
|
|
||||||
|
|
||||||
|
#include "multiboot.h"
|
||||||
|
#include "arch/i386/idt/idt.h"
|
||||||
|
#include "MMU.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "cpu.h"
|
|
||||||
#include "serial.h"
|
|
||||||
|
|
||||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
|
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
|
||||||
#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");
|
|
||||||
}
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
inline void bitmap_set( uint32_t* map , int index )
|
|
||||||
{
|
|
||||||
map[index/32] |= (1 << (index % 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void bitmap_unset(uint32_t* map , int index)
|
|
||||||
{
|
|
||||||
map[index/32] &= ~(1 << (index % 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int bitmap_first_unset( uint32_t* map , int size)
|
|
||||||
{
|
|
||||||
uint32_t rem_bits = size % 32;
|
|
||||||
for(uint32_t i = 0; i < size/32; i++)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
struct page_directory_entry {};
|
|
||||||
struct page_table_entry{};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PageDirectory {
|
|
||||||
public:
|
|
||||||
void enable ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
|
||||||
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
#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
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#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*);
|
|
@ -1,118 +0,0 @@
|
|||||||
#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--;
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
#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 ;
|
|
@ -1,20 +0,0 @@
|
|||||||
.globl enablePaging
|
|
||||||
enablePaging:
|
|
||||||
push %ebp
|
|
||||||
mov %esp, %ebp
|
|
||||||
mov %cr0, %eax
|
|
||||||
or $0x80000000, %eax
|
|
||||||
mov %eax, %cr0
|
|
||||||
mov %ebp, %esp
|
|
||||||
pop %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.globl loadPageDirectory
|
|
||||||
loadPageDirectory:
|
|
||||||
push %ebp
|
|
||||||
mov %esp, %ebp
|
|
||||||
mov 8(%esp), %eax
|
|
||||||
mov %eax, %cr3
|
|
||||||
mov %ebp, %esp
|
|
||||||
pop %ebp
|
|
||||||
ret
|
|
@ -1,108 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
#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 );
|
|
@ -1,133 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tty/kterm.h"
|
|
||||||
#include "io.h"
|
|
||||||
|
|
||||||
#define PORT 0x3f8
|
|
||||||
|
|
||||||
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
|
|
||||||
outb(PORT + 1, 0x00); // (hi byte)
|
|
||||||
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
|
||||||
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
|
||||||
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
|
||||||
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
|
||||||
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
|
||||||
|
|
||||||
// Check if serial is faulty (i.e: not same byte as sent)
|
|
||||||
if(inb(PORT + 0) != 0xAE) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If serial is not faulty set it in normal operation mode
|
|
||||||
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
|
||||||
outb(PORT + 4, 0x0F);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int is_transmit_empty() {
|
|
||||||
return inb(PORT + 5) & 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void write_serial(char a) {
|
|
||||||
while (is_transmit_empty() == 0);
|
|
||||||
|
|
||||||
outb(PORT,a);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int serial_received() {
|
|
||||||
return inb(PORT + 5) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char read_serial() {
|
|
||||||
while (serial_received() == 0);
|
|
||||||
|
|
||||||
return inb(PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void print_serial(const char* string ){
|
|
||||||
for(size_t i = 0; i < strlen(string); i ++){
|
|
||||||
write_serial(string[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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:");
|
|
||||||
init_serial();
|
|
||||||
write_serial('A');
|
|
||||||
write_serial('B');
|
|
||||||
write_serial('C');
|
|
||||||
write_serial('D');
|
|
||||||
write_serial('E');
|
|
||||||
|
|
||||||
char Character_received = read_serial();
|
|
||||||
kterm_writestring("\n");
|
|
||||||
kterm_writestring("received from COM 1: \n");
|
|
||||||
kterm_put(Character_received);
|
|
||||||
|
|
||||||
kterm_writestring("\n");
|
|
||||||
}
|
|
@ -49,8 +49,6 @@ void read_rtc() {
|
|||||||
year = get_RTC_register(0x09);
|
year = get_RTC_register(0x09);
|
||||||
if(century_register != 0) {
|
if(century_register != 0) {
|
||||||
century = get_RTC_register(century_register);
|
century = get_RTC_register(century_register);
|
||||||
} else {
|
|
||||||
century = 21;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -143,7 +141,7 @@ void WriteTOCMOS(unsigned char array[])
|
|||||||
asm("cli\n\t" // Clear interrupts
|
asm("cli\n\t" // Clear interrupts
|
||||||
"mov al,index\n\t" // move index address
|
"mov al,index\n\t" // move index address
|
||||||
"out 0x70,al\n\t" // copy address to CMOS register
|
"out 0x70,al\n\t" // copy address to CMOS register
|
||||||
// some kind of real delay here is probably best
|
/* some kind of real delay here is probably best
|
||||||
"mov al,tvalue\n\t" // move value to al
|
"mov al,tvalue\n\t" // move value to al
|
||||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||||
"sti\n\\t" ); // Enable interrupts
|
"sti\n\\t" ); // Enable interrupts
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
|
||||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
|
||||||
|
|
||||||
/* VBE index values*/
|
|
||||||
#define VBE_DISPI_INDEX_ID 0x0
|
|
||||||
#define VBE_DISPI_INDEX_XRES 0x1
|
|
||||||
#define VBE_DISPI_INDEX_YRES 0x2
|
|
||||||
#define VBE_DISPI_INDEX_BPP 0x3
|
|
||||||
#define VBE_DISPI_INDEX_ENABLE 0x4
|
|
||||||
#define VBE_DISPI_INDEX_BANK 0x5
|
|
||||||
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
|
|
||||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
|
|
||||||
#define VBE_DISPI_INDEX_X_OFFSET 0x8
|
|
||||||
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
|
|
||||||
|
|
||||||
/* BGA Version */
|
|
||||||
#define VBE_DISPI_ID5 0xB0C5
|
|
||||||
#define VBE_DISPI_ID4 0xB0C3
|
|
||||||
#define VBE_DISPI_ID3 0xB0C2
|
|
||||||
#define VBE_DISPI_ID2 0xB0C1
|
|
||||||
#define VBE_DISPI_ID1 0xB0C0
|
|
||||||
|
|
||||||
|
|
||||||
/* BGA BIT DEPTH */
|
|
||||||
#define VBE_DISPI_BPP_4 0x04
|
|
||||||
#define VBE_DISPI_BPP_8 0x08
|
|
||||||
#define VBE_DISPI_BPP_15 0x0F
|
|
||||||
#define VBE_DISPI_BPP_16 0x10
|
|
||||||
#define VBE_DISPI_BPP_24 0x18
|
|
||||||
#define VBE_DISPI_BPP_32 0x20
|
|
||||||
|
|
||||||
|
|
||||||
/*unsigned short BGAReadRegister(unsigned short IndexValue){
|
|
||||||
// outpw(VBE_DISPI_IOPORT_INDEX, IndexValue);
|
|
||||||
// return inpw (VBE_DISPI_IOPORT_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
int BGAIsAvailable (){
|
|
||||||
return (BGAReadRegister(VBE_DISPI_INDEX_ID) == VBE_DISPI_ID5);
|
|
||||||
}*/
|
|
@ -1,8 +0,0 @@
|
|||||||
inline void* memset (void* ptr, int value, size_t num){
|
|
||||||
for( int i = 0; i < num; i++ )
|
|
||||||
{
|
|
||||||
int* data = (int*)ptr+ i;
|
|
||||||
*data = value;
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#include "string.h"
|
|
||||||
|
|
||||||
size_t strlen(const char* str) {
|
|
||||||
size_t len = 0;
|
|
||||||
while(str[len]){
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
@ -1,3 +1,8 @@
|
|||||||
#pragma once
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
size_t strlen(const char* str);
|
size_t strlen(const char* str){
|
||||||
|
size_t len = 0;
|
||||||
|
while(str[len]){
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
Reference in New Issue
Block a user