Compare commits
26 Commits
BasicGraph
...
13e9beea79
Author | SHA1 | Date | |
---|---|---|---|
13e9beea79 | |||
9893a0bd17 | |||
a70ae5ca31 | |||
15443601a6 | |||
c90e90bd84 | |||
a5e7fdd07e | |||
59ba41f3d2 | |||
5051b8903c | |||
0f0fc9f252 | |||
e70f56a005 | |||
560dd64e64 | |||
9436e6e033 | |||
d280aa0584 | |||
7d6c823d79 | |||
bbfea39c23 | |||
3b3e2597a1 | |||
0b0e37b762 | |||
388ac8e7f9 | |||
9172da075a | |||
23c68d9863 | |||
b4cff3e667 | |||
7330b81a10 | |||
97606dbf71 | |||
7496299761 | |||
0d8ef065e0 | |||
88cc1d75bb |
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,4 +5,6 @@ isodir/
|
||||
root/
|
||||
*.iso
|
||||
*.img
|
||||
*.sym
|
||||
|
||||
|
||||
|
69
Makefile
69
Makefile
@ -3,11 +3,11 @@ EMULATOR = qemu-system-i386
|
||||
AS = ${HOME}/opt/cross/bin/i686-elf-as
|
||||
CC = ${HOME}/opt/cross/bin/i686-elf-gcc
|
||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||
CFLAGS = -ffreestanding -Og -ggdb -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)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o
|
||||
|
||||
SRC_DIR = src
|
||||
SRC_DIR = source
|
||||
BUILD_DIR = build
|
||||
|
||||
CRTBEGIN_OBJ = $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
||||
@ -23,8 +23,6 @@ all: clean build
|
||||
|
||||
build: build_kernel iso
|
||||
|
||||
|
||||
|
||||
clean_iso:
|
||||
if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi
|
||||
if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi
|
||||
@ -32,17 +30,19 @@ clean_iso:
|
||||
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
|
||||
cp source/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
|
||||
run: all
|
||||
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo
|
||||
|
||||
debug: all
|
||||
objcopy --only-keep-debug build/myos.bin kernel.sym
|
||||
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int
|
||||
|
||||
build_kernel: $(OBJ_LINK_LIST)
|
||||
$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
|
||||
-ffreestanding -O2 -nostdlib $(OBJ_LINK_LIST) -lgcc
|
||||
-ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc
|
||||
|
||||
build_x86_64:
|
||||
$(AS) $(SRC_DIR)/cgc/x86_64/crti.s -o $(BUILD_DIR)/crti_64.o
|
||||
@ -52,13 +52,13 @@ clean:
|
||||
rm -f $(BUILD_DIR)/myos.bin $(INTERNAL_OBJS)
|
||||
|
||||
$(BUILD_DIR)/kernel.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti -fpermissive
|
||||
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/kterm.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
$(CPP) -c $(SRC_DIR)/kernel/terminal/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/boot.o:
|
||||
$(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o
|
||||
$(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o
|
||||
|
||||
$(BUILD_DIR)/crti.o:
|
||||
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
|
||||
@ -69,30 +69,43 @@ $(BUILD_DIR)/crtn.o:
|
||||
$(BUILD_DIR)/io.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/PageDirectory.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/idt.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
$(CPP) -c $(SRC_DIR)/kernel/interrupts/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/gdtc.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
$(CPP) -c $(SRC_DIR)/kernel/memory/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
$(BUILD_DIR)/pic.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/string.o:
|
||||
$(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
|
||||
$(CC) -c $(SRC_DIR)/kernel/lib/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)/pit.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp -o $(BUILD_DIR)/pit.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
|
||||
$(BUILD_DIR)/keyboard.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/ps-2/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
$(BUILD_DIR)/time.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/time.cpp -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/sv-terminal.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/supervisorterminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/memory.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/paging.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/prekernel.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/prekernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/cpu.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
11
README.md
11
README.md
@ -6,9 +6,6 @@
|
||||
|
||||
________________________
|
||||
### Screenshot(s)
|
||||
 \
|
||||
It may not look like much but I am proud of it! We are in graphics mode.
|
||||
|
||||
 \
|
||||
The first scrolling boot screen. 😲
|
||||
|
||||
@ -19,10 +16,16 @@ W.I.P - Working on interrupt handling
|
||||
|
||||
 \
|
||||
Multiboot information can be read by the kernel.
|
||||
|
||||
 \
|
||||
Enabled paging and am getting page faults!
|
||||
|
||||
|
||||
________________________
|
||||
|
||||
### 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.Initially I'd like for my
|
||||
operating system to be able to run bash.
|
||||
|
||||
________________________
|
||||
### Operating System Technical specs/details
|
||||
|
37
features.md
37
features.md
@ -1,29 +1,30 @@
|
||||
# TODO list
|
||||
## Start planning
|
||||
## Basics
|
||||
<input type="checkbox" checked/> Setup Cross-Compiler \
|
||||
<input type="checkbox" checked/> Multiboot to kernel \
|
||||
<input type="checkbox" checked/> Printing string to the screen \
|
||||
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
|
||||
<input type="checkbox" checked/> Printing values/numbers to the screen \
|
||||
<input type="checkbox" checked/> Basic Terminal \
|
||||
<input type="checkbox" checked/> Extend Multiboot implementation \
|
||||
<input type="checkbox" checked/> Output to serial port \
|
||||
<input type="checkbox" checked/> Move to protected mode \
|
||||
<input type="checkbox" checked/> Enabel CMOS clock \
|
||||
<input type="checkbox" /> Time measurement (PIC &| PIT) \
|
||||
<input type="checkbox" checked/> Time measurement (PIC &| PIT) \
|
||||
<input type="checkbox" /> Detect CPU speed \
|
||||
<input type="checkbox" checked/> 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" checked/> PCI support \
|
||||
<input type="checkbox" checked/> ATA PIO Mode support \
|
||||
<input type="checkbox" checked/> FAT Filesystem \
|
||||
<input type="checkbox" /> Virtual filesystem \
|
||||
<input type="checkbox" checked/> Keyboard support ( P/S2 Keyboard) \
|
||||
<input type="checkbox" checked/> Physical memory management \
|
||||
<input type="checkbox" /> Paging \
|
||||
<input type="checkbox" /> Virtual memory management \
|
||||
<input type="checkbox" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
|
||||
<input type="checkbox" /> Enable SIMD Extensions (SSE)
|
||||
|
||||
## Other features I am thinking of:
|
||||
<input type="checkbox" /> PCI support \
|
||||
<input type="checkbox" /> ATA PIO Mode support \
|
||||
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
|
||||
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
|
||||
<input type="checkbox" /> ATAPI support \
|
||||
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
|
||||
<input type="checkbox" checked/> Memory Management (MMU)
|
||||
<input type="checkbox" /> Hardware Management system
|
||||
|
||||
<input type="checkbox" /> Preemptive multi tasking \
|
||||
<input type="checkbox" /> Processes \
|
||||
<input type="checkbox" /> Threads
|
||||
@ -32,9 +33,11 @@
|
||||
<input type="checkbox" /> POSIX compliance (partially) \
|
||||
<input type="checkbox" /> RPC - for interprocess communication \
|
||||
<input type="checkbox" /> Sync primitives - Semaphores, Mutexes, spinlocks et al. \
|
||||
<input type="checkbox" /> Basic Terminal \
|
||||
<input type="checkbox" /> Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \
|
||||
|
||||
<input type="checkbox" /> ACPI support \
|
||||
<input type="checkbox" /> ATAPI support \
|
||||
|
||||
## Optional
|
||||
<input type="checkbox" /> Basic Window server/client \
|
||||
## Support for more filesystems if I like the challenge in writing these ...
|
||||
<input type="checkbox" /> FAT Filesystem \
|
||||
<input type="checkbox" /> EXT2 Filesystem
|
||||
<input type="checkbox" /> USTAR Filesystem \
|
||||
|
BIN
images/BarinkOS.png
(Stored with Git LFS)
BIN
images/BarinkOS.png
(Stored with Git LFS)
Binary file not shown.
BIN
images/BarinkOS_logo(standard).svg
(Stored with Git LFS)
BIN
images/BarinkOS_logo(standard).svg
(Stored with Git LFS)
Binary file not shown.
BIN
images/BarinkOS_logo.svg
(Stored with Git LFS)
BIN
images/BarinkOS_logo.svg
(Stored with Git LFS)
Binary file not shown.
BIN
screenshots/BarinkOS_VBE_GRAPHICS.png
(Stored with Git LFS)
BIN
screenshots/BarinkOS_VBE_GRAPHICS.png
(Stored with Git LFS)
Binary file not shown.
BIN
screenshots/PageFault.png
(Stored with Git LFS)
Normal file
BIN
screenshots/PageFault.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
screenshots/must frustrating bug ever.png
(Stored with Git LFS)
Normal file
BIN
screenshots/must frustrating bug ever.png
(Stored with Git LFS)
Normal file
Binary file not shown.
3
scripts/dev-setup/install.sh
Normal file
3
scripts/dev-setup/install.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
cmake -DLLVM_ENABLE_PROJECTS="clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ../llvm
|
5
scripts/hooks/pre-commit.hook.sh
Normal file
5
scripts/hooks/pre-commit.hook.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Run clang-tidy
|
||||
|
9
source/grub.cfg
Normal file
9
source/grub.cfg
Normal file
@ -0,0 +1,9 @@
|
||||
menuentry "BarinkOS" {
|
||||
multiboot /boot/myos.bin
|
||||
}
|
||||
|
||||
menuentry "BarinkOS Tests" {
|
||||
multiboot /boot/myos.bin
|
||||
}
|
||||
|
||||
|
40
source/kernel/bitmap.h
Normal file
40
source/kernel/bitmap.h
Normal file
@ -0,0 +1,40 @@
|
||||
#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 uint32_t bitmap_first_unset( uint32_t* map , int map_size)
|
||||
{
|
||||
for ( int i = 0 ; i < map_size ; i ++ )
|
||||
{
|
||||
// a bit or more is set within this byte!
|
||||
if( (map[i] & 0xFFFFFFFF) > 0 ){
|
||||
|
||||
// which bit is set?
|
||||
for(int j = 0 ; j < 32 ; j++){
|
||||
if ( (map[i] & (0x00000001 << j)) > 0)
|
||||
{
|
||||
printf("Found bit: byte 0x%x , bit 0x%x\n", i , j);
|
||||
return (i*32)+j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
112
source/kernel/boot/boot.s
Normal file
112
source/kernel/boot/boot.s
Normal file
@ -0,0 +1,112 @@
|
||||
.include "./source/kernel/boot/multiboot.s"
|
||||
/*
|
||||
* Allocate initial stack
|
||||
*/
|
||||
.section .bootstrap_stack, "aw", @nobits
|
||||
stack_bottom:
|
||||
.skip 16384 # 16 KiB
|
||||
stack_top:
|
||||
|
||||
/*
|
||||
* Preallocate a couple pages to get us bootstrapped
|
||||
* Being carefull to not use any address the bootloader might
|
||||
* be using for its multiboot structures
|
||||
*/
|
||||
.section .bss, "aw", @nobits
|
||||
.align 4096
|
||||
.globl boot_page_directory
|
||||
boot_page_directory:
|
||||
.skip 4096
|
||||
.globl boot_page_table
|
||||
boot_page_table:
|
||||
.skip 4096
|
||||
.globl multiboot_page_table
|
||||
multiboot_page_table:
|
||||
.skip 4096
|
||||
# More page tables may be required
|
||||
|
||||
# Entry point
|
||||
.section .multiboot.text, "a"
|
||||
.global _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
|
||||
/* push the pointer to the Multiboot information structure*/
|
||||
pushl %ebx
|
||||
|
||||
/* push the magic value */
|
||||
pushl %eax
|
||||
call prekernelSetup
|
||||
|
||||
# Get physical address of the boot_page_table
|
||||
movl $(boot_page_table - 0xC0000000), %edi
|
||||
# Map address 0
|
||||
movl $0, %esi
|
||||
1:
|
||||
cmpl $(_kernel_end - 0xC0000000), %esi
|
||||
jge 3f
|
||||
|
||||
# Map physical address as "present and writable"
|
||||
movl %esi, %edx
|
||||
orl $0x003, %edx
|
||||
movl %edx, (%edi)
|
||||
|
||||
2: # Size of page is 4096 bytes
|
||||
addl $4096, %esi
|
||||
# Size of entries in boot_page_table is 4 bytes
|
||||
addl $4, %edi
|
||||
# Loop to the next entry if we haven't finished.
|
||||
loop 1b
|
||||
|
||||
3: # Map VGA video memory to 0xC03FF00 as "present, writable"
|
||||
movl $(0x000B8000 | 0x003), boot_page_table - 0xC0000000 + 1023 * 4
|
||||
|
||||
# Map the page table to both virtual addresss 0x00000000 and 0xC0000000
|
||||
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
|
||||
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
|
||||
|
||||
# Set cr3 to the address of the boot_page_directory
|
||||
movl $(boot_page_directory - 0xC0000000), %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# Enable paging and the write-protect bit
|
||||
movl %cr0, %ecx
|
||||
orl $0x80010000, %ecx
|
||||
movl %ecx, %cr0
|
||||
|
||||
# Jump to higher half with an absolute jump
|
||||
lea 4f, %ecx
|
||||
jmp *%ecx
|
||||
|
||||
.section .text
|
||||
4:
|
||||
# At this point, paging is fully set up and enabled
|
||||
isPaging:
|
||||
# Unmap the identity mapping as it is now unnecessary
|
||||
movl $0, boot_page_directory + 0
|
||||
|
||||
# Reload cr3 to force tlb flush
|
||||
movl %cr3, %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/*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
|
||||
|
||||
call early_main
|
||||
|
||||
cli
|
||||
1: hlt
|
||||
jmp 1b
|
||||
|
||||
|
||||
.include "./source/kernel/memory/gdt/gdt.s"
|
||||
.include "./source/kernel/irs_table.s"
|
||||
.include "./source/kernel/irq_table.s"
|
||||
.include "./source/kernel/interrupts/idt/idt.s"
|
||||
|
||||
|
15
source/kernel/boot/multiboot.s
Normal file
15
source/kernel/boot/multiboot.s
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.data, "aw"
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
39
source/kernel/cpu.cpp
Normal file
39
source/kernel/cpu.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
uint32_t GetEFLAGS()
|
||||
{
|
||||
uint32_t EFLAGS = 0;
|
||||
asm volatile ("pushfl;" "movl 4(%%esp), %%edx" : "=d"(EFLAGS));
|
||||
return EFLAGS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetCR0()
|
||||
{
|
||||
uint32_t cr0_value;
|
||||
asm volatile ("movl %%cr0, %%edx" : "=d"(cr0_value));
|
||||
return cr0_value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetCR2(){
|
||||
uint32_t cr2_value;
|
||||
__asm__ volatile("movl %%cr2, %%edx": "=d"(cr2_value));
|
||||
return cr2_value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetCR3(){
|
||||
uint32_t cr3_value;
|
||||
__asm__ volatile("movl %%cr3, %%edx": "=d"(cr3_value));
|
||||
return cr3_value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetCR4(){
|
||||
uint32_t cr4_value;
|
||||
__asm__ volatile("movl %%cr4, %%edx": "=d"(cr4_value));
|
||||
return cr4_value;
|
||||
}
|
74
source/kernel/cpu.h
Normal file
74
source/kernel/cpu.h
Normal file
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
Based on Intel specifications.
|
||||
|
||||
C++ interface for the cpu.s assembly file.
|
||||
|
||||
©Nigel Barink - 2022
|
||||
*/
|
||||
|
||||
/*
|
||||
* EFLAGS FUNCTIONS
|
||||
*/
|
||||
|
||||
uint32_t GetEFLAGS();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CONTROL_REGISTER_0 FUNCTIONS
|
||||
*/
|
||||
uint32_t GetCR0();
|
||||
|
||||
/*
|
||||
struct CR0_Register {
|
||||
uint8_t PE :1; // Protection Mode Enabled 0
|
||||
uint8_t MP :1; // Monitor co-processor 1
|
||||
uint8_t EM :1; // Emulation 2
|
||||
uint8_t TS :1; // Task switched 3
|
||||
uint8_t ET :1; // Extension Type 4
|
||||
uint8_t NE :1; // Numeric error 5
|
||||
uint16_t Reserved :10; // 6,7,8,9,10,11,12,13,14,15
|
||||
uint8_t WP :1; // Write Protect 16
|
||||
uint8_t Reserved :1; // 17
|
||||
uint8_t AM :1; // Alligment Task 18
|
||||
uint16_t Reserved :10; // 19,20,21,22,23,24,25,26,27,28
|
||||
uint8_t NW :1; // Not-write through 29
|
||||
uint8_t CD :1; // Cache disable 30
|
||||
uint8_t PG :1; // Paging 31
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
#define GET_PE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x1)
|
||||
#define GET_MP_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x2)
|
||||
#define GET_EM_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x3)
|
||||
#define GET_TS_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x4)
|
||||
#define GET_ET_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x5)
|
||||
#define GET_NE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x6)
|
||||
|
||||
|
||||
#define GET_PG_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0>>31)
|
||||
|
||||
/*
|
||||
* CONTROL_REGISTER_4 FUNCTIONS
|
||||
*/
|
||||
|
||||
uint32_t GetCR4();
|
||||
|
||||
#define GET_PSE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x4)
|
||||
#define GET_PAE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x5)
|
||||
|
||||
/*
|
||||
* CONTROL_REGISTER_2 FUNCTIONS
|
||||
*/
|
||||
|
||||
uint32_t GetCR2();
|
||||
|
||||
/*
|
||||
* CONTROL_REGISTER_3 FUNCTIONS
|
||||
*/
|
||||
|
||||
uint32_t GetCR3();
|
9
source/kernel/definitions.h
Normal file
9
source/kernel/definitions.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Kernel definitions
|
||||
*/
|
||||
|
||||
#define __DEBUG__ false
|
||||
#define KERNEL_VERSION 0
|
||||
|
||||
#define ARCHITECTURE "I386"
|
38
source/kernel/drivers/cmos/cmos.cpp
Normal file
38
source/kernel/drivers/cmos/cmos.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
void ReadFromCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char tvalue, index;
|
||||
|
||||
for (index = 0; index < 128; index++)
|
||||
{
|
||||
asm(
|
||||
"cli\n\t" // Disable interrupts
|
||||
"mov al, index\n\t" // Move index address
|
||||
// since the 0x80 bit of al is not set, NMI is active
|
||||
"out 0x70,al\n\t" // Copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"in al,0x71\n\t" // Fetch 1 byte to al
|
||||
"sti\n\t" // Enable interrupts
|
||||
"mov tvalue,al\n\t");
|
||||
|
||||
array[index] = tvalue;
|
||||
}
|
||||
}
|
||||
|
||||
void WriteTOCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char index;
|
||||
|
||||
for(index = 0; index < 128; index++)
|
||||
{
|
||||
unsigned char tvalue = array[index];
|
||||
|
||||
asm("cli\n\t" // Clear interrupts
|
||||
"mov al,index\n\t" // move index address
|
||||
"out 0x70,al\n\t" // copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"mov al,tvalue\n\t" // move value to al
|
||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||
"sti\n\\t" ); // Enable interrupts
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "../io.h"
|
||||
#include "../../io.h"
|
||||
|
||||
#define PIC1 0x20 /* IO base address for master PIC */
|
||||
#define PIC2 0xA0 /* IO base address for slave PIC */
|
54
source/kernel/drivers/pit/pit.cpp
Normal file
54
source/kernel/drivers/pit/pit.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "pit.h"
|
||||
|
||||
uint32_t pit_tick = 0;
|
||||
|
||||
|
||||
void pit_initialise()
|
||||
{
|
||||
asm volatile("CLI");
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init PIT!\n");
|
||||
#endif
|
||||
// clear mask for IRQ 0
|
||||
uint8_t value = inb(0x21) & ~(1<< 0);
|
||||
outb(0x21, value);
|
||||
|
||||
io_wait();
|
||||
|
||||
const int freq = 500;
|
||||
|
||||
uint32_t divisor = 1193180 / freq;
|
||||
|
||||
outb(PIT_COMMAND, 0x36);
|
||||
|
||||
uint8_t l = (uint8_t) (divisor & 0xFF);
|
||||
uint8_t h = (uint8_t) ( (divisor>>8) & 0xff);
|
||||
|
||||
outb(PIT_DATA_0, l);
|
||||
outb(PIT_DATA_0,h);
|
||||
|
||||
|
||||
asm volatile("STI");
|
||||
}
|
||||
|
||||
|
||||
void get_pit_count()
|
||||
{
|
||||
asm volatile ("CLI");
|
||||
|
||||
outb(PIT_COMMAND, 0);
|
||||
uint16_t count = inb(PIT_DATA_0);
|
||||
count |= inb(PIT_DATA_0) << 8;
|
||||
|
||||
printf("PIT count: 0x%x\n", count);
|
||||
|
||||
asm volatile("STI");
|
||||
|
||||
}
|
||||
|
||||
void set_pit_count()
|
||||
{
|
||||
|
||||
}
|
||||
|
19
source/kernel/drivers/pit/pit.h
Normal file
19
source/kernel/drivers/pit/pit.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "../../io.h"
|
||||
#include "../../terminal/kterm.h"
|
||||
#define PIT_DATA_0 0x40
|
||||
#define PIT_DATA_1 0x41
|
||||
#define PIT_DATA_2 0x42
|
||||
#define PIT_COMMAND 0x43
|
||||
|
||||
|
||||
extern uint32_t pit_tick;
|
||||
|
||||
|
||||
void pit_initialise();
|
||||
|
||||
|
||||
void get_pit_count();
|
||||
|
||||
void set_pit_count();
|
51
source/kernel/drivers/ps-2/keyboard.cpp
Normal file
51
source/kernel/drivers/ps-2/keyboard.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "keyboard.h"
|
||||
|
||||
KeyPressInfo keyPress {};
|
||||
|
||||
void KeyHandled(){
|
||||
keyPress.ScanCode= 0x00;
|
||||
keyPress.PressedModifiers = 0x00;
|
||||
}
|
||||
|
||||
|
||||
char getASCIIKey(){
|
||||
char keyPressed;
|
||||
// Wait until a key is pressed
|
||||
while(keyPress.ScanCode == 0x00) {
|
||||
asm volatile ("NOP");
|
||||
}
|
||||
|
||||
|
||||
// Translate keycode to ascii
|
||||
// Probably a lookup table might be handy
|
||||
// Until 0x37
|
||||
const char* ASCIILookUp =
|
||||
"\01234567890-=\0\0QWERTYUIOP[]\0\0ASDFGHJKL;\'`\0\\ZXCVBNM,./\0";
|
||||
|
||||
uint8_t ASCII_Index = keyPress.ScanCode - 3 ;
|
||||
//printf("ASCII_INDEX: %x\n", ASCII_Index);
|
||||
keyPressed = ASCIILookUp[ASCII_Index];
|
||||
|
||||
KeyHandled();
|
||||
|
||||
return keyPressed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t getKey(){
|
||||
// Wait until a key is pressed
|
||||
while(keyPress.ScanCode == 0x00){
|
||||
asm volatile ("NOP");
|
||||
}
|
||||
|
||||
if( keyPress.ScanCode > 0x37){
|
||||
keyPress.ScanCode = 0x00;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ScanCode = keyPress.ScanCode;
|
||||
// KeyHandled();
|
||||
|
||||
return ScanCode ;
|
||||
}
|
34
source/kernel/drivers/ps-2/keyboard.h
Normal file
34
source/kernel/drivers/ps-2/keyboard.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "../../terminal/kterm.h"
|
||||
enum ScanCodeSet {
|
||||
None = 0,
|
||||
ScanCodeSet1 = 1,
|
||||
ScanCodeSet2 = 2,
|
||||
ScanCodeSet3 = 3,
|
||||
};
|
||||
|
||||
enum Modifiers {
|
||||
LSHIFT = 1,
|
||||
RSHIFT = 2,
|
||||
|
||||
LCTRL = 3,
|
||||
RCTRL = 4,
|
||||
|
||||
LALT = 5,
|
||||
RALT = 6
|
||||
};
|
||||
|
||||
struct KeyPressInfo{
|
||||
uint8_t PressedModifiers;
|
||||
uint8_t ScanCode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern KeyPressInfo keyPress;
|
||||
|
||||
void KeyHandled();
|
||||
|
||||
char getASCIIKey();
|
||||
uint8_t getKey();
|
0
source/kernel/filesystem/FAT/FAT16.cpp
Normal file
0
source/kernel/filesystem/FAT/FAT16.cpp
Normal file
8
source/kernel/filesystem/FAT/FAT16.h
Normal file
8
source/kernel/filesystem/FAT/FAT16.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "../../vfs/File.h"
|
||||
|
||||
|
||||
class FAT16 : File {
|
||||
public:
|
||||
|
||||
};
|
395
source/kernel/interrupts/idt/idt.cpp
Normal file
395
source/kernel/interrupts/idt/idt.cpp
Normal file
@ -0,0 +1,395 @@
|
||||
#include "idt.h"
|
||||
#include "../../drivers/pit/pit.h"
|
||||
#include "../../drivers/ps-2/keyboard.h"
|
||||
#include "../../cpu.h"
|
||||
IDT_entry idt_table[256];
|
||||
IDT_ptr idt_ptr;
|
||||
|
||||
|
||||
void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
|
||||
idt_table[num].offset_1 = base & 0xFFFF;
|
||||
idt_table[num].selector = sel;
|
||||
idt_table[num].zero = 0;
|
||||
idt_table[num].type_attr = flags;
|
||||
idt_table[num].offset_2 = (base >> 16) & 0xFFFF;
|
||||
|
||||
};
|
||||
|
||||
void irs_handler (registers regs) {
|
||||
uint32_t FaultingAddress;
|
||||
//printf("(IRS) Interrupt number: %d \r", regs.int_no);
|
||||
switch (regs.int_no)
|
||||
{
|
||||
case 0:
|
||||
// Divide Error #DE
|
||||
printf("#DE\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Debug Exception #DB
|
||||
printf("#DB\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// NMI Interrupt
|
||||
printf("#NMI\n");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Breakpoint Exception #BP
|
||||
printf("#BP\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Overflow Exception #OF
|
||||
printf("#OF\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// BOUND Range Exceeded Exception #BR
|
||||
printf("#BR\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// Invalid OpCode Exception #UD
|
||||
printf("#UD\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// Device Not Available Exception #NM
|
||||
printf("#NM\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// Double Fault Exception #DF
|
||||
printf("#DF\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// Coprocessor Segment Overrun
|
||||
printf("Coprocessor Segment overrun!\n");
|
||||
break;
|
||||
|
||||
case 10:
|
||||
// Invalid TSS Exception #TS
|
||||
printf("#TS\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
// Segment Not Present #NP
|
||||
printf("#NP\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
// Stack Fault Exception #SS
|
||||
printf("#SS\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
// General Protection Exception #GP
|
||||
printf("#GP\n");
|
||||
|
||||
printf("Accessing memory caused a general protectuion exception.\n");
|
||||
|
||||
printf("Fault due to entry at index: %d", (regs.err_code >> 3 & 0xFFF ) );
|
||||
|
||||
if(regs.err_code & 0x3 >> 1 == 0 ){
|
||||
printf("* Index references GDT");
|
||||
}
|
||||
if(regs.err_code & 0x3 >> 1 == 1 ){
|
||||
printf("* Index references IDT");
|
||||
}
|
||||
|
||||
if(regs.err_code & 0x3 >> 1 == 2 ){
|
||||
printf("* Index references LDT");
|
||||
}
|
||||
|
||||
if(regs.err_code & 0x3 >> 1 == 4 ){
|
||||
printf("* Index references IDT");
|
||||
}
|
||||
|
||||
if( regs.err_code & 0x1)
|
||||
{
|
||||
printf("* Originated externally!");
|
||||
}
|
||||
|
||||
__asm__("cli;" "1: hlt;" "jmp 1b;");
|
||||
|
||||
break;
|
||||
|
||||
case 14:
|
||||
// Page Fault Exception #PF
|
||||
printf("#PF\n");
|
||||
|
||||
FaultingAddress = GetCR2();
|
||||
printf("Accessing the linear address 0x%x resulted in a page fault!\n\n", FaultingAddress);
|
||||
|
||||
// Error code of 32 bits are on the stack
|
||||
// CR2 register contains the 32-bit linear virtual address that generated the exception
|
||||
// See Intel Software Developers manual Volume 3A Part 1 page 236 for more info
|
||||
#define PF_ERR_PRESENT_BIT 0x1
|
||||
#define PF_ERR_WRITE_BIT 0x2
|
||||
#define PF_ERR_USER_BIT 0x3
|
||||
#define PF_ERR_RESERVERD_WRITE_BIT 0x4
|
||||
#define PF_ERR_INSTRUCTION_FETCH_BIT 0x5
|
||||
#define PF_ERR_PROTECTION_KEY_BIT 0x6
|
||||
#define PF_ERR_SHADOW_STACK_BIT 0x7
|
||||
#define PF_ERR_SOFTWARE_GUARD_EXTENSION_BIT 0xE
|
||||
|
||||
printf("REASON: \n\n");
|
||||
|
||||
|
||||
if (regs.err_code & PF_ERR_PRESENT_BIT ){
|
||||
printf("* Page protection violation!\n");
|
||||
} else{
|
||||
printf("* Page not-present!\n");
|
||||
}
|
||||
|
||||
if(regs.err_code & PF_ERR_WRITE_BIT){
|
||||
printf("* Write access violation!\n");
|
||||
} else{
|
||||
printf("* Read access violation!\n");
|
||||
}
|
||||
|
||||
if(regs.err_code & PF_ERR_USER_BIT){
|
||||
printf("* Violation from user-space (CPL=3)\n");
|
||||
}
|
||||
|
||||
if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
|
||||
printf("* Caused by an instruction fetch. \n");
|
||||
}
|
||||
|
||||
/*
|
||||
Check the error code to figure out what happened here
|
||||
*/
|
||||
__asm__("cli;" "1: hlt;" "jmp 1b;");
|
||||
|
||||
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// x87 FPU Floating-point Error #MF
|
||||
printf("#MF\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 17:
|
||||
// Alignment Check Exception #AC
|
||||
printf("#AC\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
// Machine-Check Exception #MC
|
||||
printf("#MC\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 19:
|
||||
// SIMD Floating-point Exception #XM
|
||||
printf("#XM\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// Virtualization Exception #VE
|
||||
printf("#VE\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
// Control Protection Exception #CP
|
||||
printf("#CP\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
default:
|
||||
// PANIC!!!
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void irq_handler (registers regs) {
|
||||
|
||||
|
||||
|
||||
switch (regs.int_no) {
|
||||
case 0:
|
||||
pit_tick++;
|
||||
break;
|
||||
case 1:
|
||||
// Keyboard interrupt !!
|
||||
|
||||
int scan;
|
||||
int i;/*register*/
|
||||
|
||||
// Read scancode
|
||||
scan = inb(0x60);
|
||||
|
||||
// Send ack message!
|
||||
i = inb(0x61);
|
||||
outb(0x61, i|0x80);
|
||||
outb(0x61, i);
|
||||
|
||||
// NOTE: check for special scan codes
|
||||
// e.g. modifiers etc..
|
||||
if( scan < 0x37){
|
||||
//printf("Read from IO: 0x%x\n", scan);
|
||||
keyPress.ScanCode = scan ;
|
||||
//printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
|
||||
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case 12:
|
||||
// PS2 Mouse interrupt
|
||||
printf("Mouse event triggered!");
|
||||
//int event = inb(0x60);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Interrupt happened!");
|
||||
printf("Received INT: 0x%x\n", regs.int_no);
|
||||
break;
|
||||
}
|
||||
|
||||
outb(0x20, 0x20); // send end of interrupt to master
|
||||
|
||||
if ( regs.int_no > 8 && regs.int_no <= 15) {
|
||||
outb(0xA0, 0x20); // send end of interrupt to slave
|
||||
}
|
||||
|
||||
|
||||
if( regs.int_no == 13){
|
||||
printf(" Error code: %d \n", regs.err_code);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void init_idt(){
|
||||
// Initialise the IDT pointer
|
||||
idt_ptr.length = sizeof(IDT_entry) * 255;
|
||||
idt_ptr.base = (uint32_t)&idt_table;
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init IDT\n");
|
||||
#endif
|
||||
|
||||
// TODO: Set everything to zero first
|
||||
|
||||
set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F);
|
||||
set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E);
|
||||
set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E);
|
||||
set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E);
|
||||
set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E);
|
||||
set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E);
|
||||
set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E);
|
||||
set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E);
|
||||
set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E);
|
||||
set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E);
|
||||
set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E);
|
||||
set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E);
|
||||
set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E);
|
||||
set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E);
|
||||
set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E);
|
||||
set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E);
|
||||
set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E);
|
||||
set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E);
|
||||
set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E);
|
||||
set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E);
|
||||
set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E);
|
||||
set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E);
|
||||
set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E);
|
||||
set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E);
|
||||
set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E);
|
||||
set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E);
|
||||
set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E);
|
||||
set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E);
|
||||
set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E);
|
||||
set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E);
|
||||
set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
|
||||
set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
|
||||
|
||||
|
||||
//print_serial("Remapping PIC\n");
|
||||
PIC_remap(0x20, 0x28);
|
||||
|
||||
// clear mask for IRQ 12
|
||||
uint8_t value = inb(0x21) & ~(1<< 12);
|
||||
outb(0x21, value);
|
||||
|
||||
|
||||
|
||||
// pic IRQ Table
|
||||
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
|
||||
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); // PS2 Keyboard
|
||||
set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
|
||||
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
|
||||
set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
|
||||
set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E);
|
||||
set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E);
|
||||
set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E);
|
||||
set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E);
|
||||
set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
|
||||
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
||||
set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
|
||||
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); // PS2 Mouse
|
||||
set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
|
||||
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
|
||||
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
|
||||
|
||||
|
||||
idt_flush((uint32_t)&idt_ptr);
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stddef.h"
|
||||
#include "../vga/colors.h"
|
||||
#include "../pic/pic.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "../../drivers/vga/colors.h"
|
||||
#include "../../drivers/pic/pic.h"
|
||||
|
||||
#include "../tty/kterm.h"
|
||||
#include "../../terminal/kterm.h"
|
||||
|
||||
|
||||
extern "C" {
|
@ -22,7 +22,7 @@ unsigned int inl_p(unsigned short ){
|
||||
}
|
||||
|
||||
|
||||
void outb_p(unsigned char , unsigned short ){
|
||||
void b_p(unsigned char , unsigned short ){
|
||||
|
||||
}
|
||||
void outw(unsigned short , unsigned short ){
|
122
source/kernel/kernel.cpp
Normal file
122
source/kernel/kernel.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include "kernel.h"
|
||||
extern "C" void early_main()
|
||||
{
|
||||
kterm_init();
|
||||
initGDT();
|
||||
|
||||
|
||||
init_serial();
|
||||
print_serial("Hello Higher half kernel!\n");
|
||||
|
||||
init_idt();
|
||||
// Enable interrupts
|
||||
asm volatile("STI");
|
||||
|
||||
/*
|
||||
* Show a little banner for cuteness
|
||||
*/
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
printf("Kernel End Addr: 0x%x\n" , &kernel_end );
|
||||
|
||||
uint32_t PageDirectoryEntryIndex = ((uint32_t)&kernel_end + KERNEL_BASE_ADDR ) >> 22 ;
|
||||
|
||||
uint32_t PageTableEntryIndex = (((uint32_t)&kernel_end + KERNEL_BASE_ADDR) >> 12) & 0x1FFF;
|
||||
|
||||
printf("Kernel End PDE: %d, PTE: %d\n" , PageDirectoryEntryIndex, PageTableEntryIndex);
|
||||
|
||||
uint32_t BootInfoStruct = BootInfoBlock_pptr + 0xC0000000;
|
||||
printf("Addr BootInfostruct: 0x%x\n", BootInfoStruct);
|
||||
|
||||
uint32_t PageDirectoryEntryIndex2 = (BootInfoStruct ) >> 2 ;
|
||||
|
||||
uint32_t PageTableEntryIndex2 = (BootInfoStruct >> 12) & 0x1FFF;
|
||||
|
||||
printf("PDE: 0x%x, PTE: 0x%x\n", PageDirectoryEntryIndex2 , PageTableEntryIndex2 );
|
||||
|
||||
BootInfoBlock* BootInfo = (BootInfoBlock*) ( BootInfoBlock_pptr + 0xC0000000 );
|
||||
|
||||
|
||||
printf("Size of BootInfoBlock: %d bytes\n", sizeof(BootInfoBlock));
|
||||
printf("Bootloader information:\n");
|
||||
if( BootInfo->ValidELFHeader )
|
||||
{
|
||||
printf("- Valid ELF Header is available!\n");
|
||||
}
|
||||
|
||||
if(BootInfo->EnabledVBE)
|
||||
{
|
||||
printf("- VBE graphics mode is available!\n");
|
||||
}
|
||||
|
||||
if(BootInfo->ValidSymbolTable)
|
||||
{
|
||||
printf("- Valid Symbol Table available at 0x%x.\n Tab Size: %d, str Size: %d\n", BootInfo->SymbolTableAddr, BootInfo->SymbolTabSize, BootInfo->SymbolStrSize);
|
||||
}
|
||||
|
||||
if(BootInfo->PhysicalMemoryMapAvailable)
|
||||
{
|
||||
printf("- Physical Memory Map available!\n");
|
||||
printf("MemoryInfoheap size : %d bytes\n", BootInfo->map_size);
|
||||
// Print the memory regions
|
||||
MemoryInfoBlock* currentBlock = (MemoryInfoBlock*) ((uint32_t)BootInfo->MemoryMap + KERNEL_BASE_ADDR) ;
|
||||
|
||||
printf( "Starting address: 0x%x\n", currentBlock);
|
||||
while( (uint32_t)currentBlock->next != 0x0 )
|
||||
{
|
||||
printf("CurrentBlock: 0x%x \n", (uint32_t ) currentBlock );
|
||||
if(IS_AVAILABLE_MEM(currentBlock->type)){
|
||||
//printf("AVAILABLE RAM\n");
|
||||
}
|
||||
else if(IS_ACPI_MEM(currentBlock->type)){
|
||||
//printf("ACPI MEMORY\n");
|
||||
}
|
||||
else if(IS_RESERVED_MEM(currentBlock->type)){
|
||||
// printf("RESERVED MEMORY\n");
|
||||
}
|
||||
else if(IS_NVS_MEMORY(currentBlock->type)){
|
||||
// printf("NVS MEMORY \n");
|
||||
}
|
||||
else if(IS_BADRAM_MEMORY(currentBlock->type)){
|
||||
// printf("BADRAM MEMORY \n");
|
||||
}
|
||||
else {
|
||||
// printf("(TYPE 0x%x )TYPE NOT SPECIFIED\n", currentBlock->type);
|
||||
}
|
||||
|
||||
currentBlock = (MemoryInfoBlock*) ((uint32_t)currentBlock->next + KERNEL_BASE_ADDR );
|
||||
|
||||
}
|
||||
|
||||
printf("Starting physical memory management setup\n");
|
||||
// Setup PhysicalMemoryManagement
|
||||
SetupPhysicalMemoryManager(BootInfo);
|
||||
|
||||
}
|
||||
printf("Enable Protected mode and jump to kernel main\n");
|
||||
asm volatile("mov %cr0, %eax ");
|
||||
asm volatile("or $1, %eax");
|
||||
asm volatile("mov %eax, %cr0"); // re-enable protected mode ?
|
||||
kernel_main();
|
||||
|
||||
}
|
||||
|
||||
void PhysicalMemoryAllocatorTest(){
|
||||
#ifdef UNIT_TESTS
|
||||
// Small test!
|
||||
void* block = allocate_block();
|
||||
void* block2 = allocate_block();
|
||||
printf("Allocated addresss 1: 0x%x 2: 0x%x\n", (uint32_t)block ,(uint32_t)block2);
|
||||
free_block(block);
|
||||
free_block(block2);
|
||||
void* block3 = allocate_block();
|
||||
printf("Allocated addresss 3: 0x%x\n", (uint32_t)block3);
|
||||
free_block(block3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern "C" void kernel_main () {
|
||||
pit_initialise();
|
||||
|
||||
startSuperVisorTerminal();
|
||||
}
|
38
source/kernel/kernel.h
Normal file
38
source/kernel/kernel.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
extern "C"
|
||||
{
|
||||
#include "lib/string.h"
|
||||
}
|
||||
#include "definitions.h"
|
||||
|
||||
#include "drivers/vga/VBE.h"
|
||||
#include "terminal/kterm.h"
|
||||
|
||||
#include "memory/PhysicalMemoryManager.h"
|
||||
#include "memory/VirtualMemoryManager.h"
|
||||
|
||||
#include "memory/gdt/gdtc.h"
|
||||
#include "interrupts/idt/idt.h"
|
||||
|
||||
#include "drivers/pit/pit.h"
|
||||
#include "io.h"
|
||||
#include "cpu.h"
|
||||
#include "serial.h"
|
||||
|
||||
#include "time.h"
|
||||
#include "supervisorterminal/superVisorTerminal.h"
|
||||
#include "prekernel/bootstructure.h"
|
||||
|
||||
#define CHECK_FLAG(flag, bit) ( flag & (1 << bit ))
|
||||
#define PANIC(message) {return;}
|
||||
|
||||
void map_multiboot_info_structure(unsigned long addr);
|
||||
|
||||
extern "C" void kernel_main ();
|
||||
|
||||
|
||||
extern "C" uint32_t boot_page_directory;
|
||||
extern "C" uint32_t multiboot_page_table;
|
||||
|
||||
|
||||
const uint32_t KERNEL_BASE_ADDR = 0xC0000000;
|
@ -1,8 +1,8 @@
|
||||
inline void* memset (void* ptr, int value, size_t num){
|
||||
for( int i = 0; i < num; i++ )
|
||||
{
|
||||
int* data = (int*)ptr+ i;
|
||||
*data = value;
|
||||
unsigned char* data = (unsigned char*)ptr+ i;
|
||||
*data = (unsigned char)value;
|
||||
}
|
||||
return ptr;
|
||||
}
|
28
source/kernel/lib/string.c
Normal file
28
source/kernel/lib/string.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "string.h"
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
while(str[len]){
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int strncmp ( const char* str1, const char* str2, size_t num ){
|
||||
for( int i = 0; i < num ; i++){
|
||||
|
||||
if( str1[i] < str2[i]){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( str1[i] > str2[i] ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
size_t strlen(const char* str);
|
||||
|
||||
|
||||
int strncmp ( const char* str1, const char* str2, size_t num );
|
46
source/kernel/linker.ld
Normal file
46
source/kernel/linker.ld
Normal file
@ -0,0 +1,46 @@
|
||||
ENTRY(_start)
|
||||
|
||||
/* Tell where the various sections of the object files will be put in the final
|
||||
kernel image. */
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00100000; /* place code at 1MB mark*/
|
||||
|
||||
_kernel_start = .;
|
||||
kernel_begin = .; /* For legacy reasons */
|
||||
|
||||
|
||||
.multiboot.data : {
|
||||
*(.multiboot.data)
|
||||
}
|
||||
|
||||
.multiboot.text : {
|
||||
*(multiboot.text)
|
||||
*prekernel.o(.text)
|
||||
}
|
||||
|
||||
. += 0xC0000000; /* Addresses in the following code need to be above the 3Gb mark */
|
||||
|
||||
|
||||
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.bootstrap_stack)
|
||||
}
|
||||
_kernel_end = .;
|
||||
kernel_end = .; /* For legacy reasons */
|
||||
}
|
||||
|
52
source/kernel/memory/KernelHeap.cpp
Normal file
52
source/kernel/memory/KernelHeap.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "KernelHeap.h"
|
||||
|
||||
// Size of heap meta data is 5 bytes
|
||||
struct heap_block{
|
||||
uint8_t Used;
|
||||
uint32_t Size;
|
||||
}
|
||||
|
||||
uint32_t heap_size;
|
||||
heap_block* start ;
|
||||
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
printf("Received request for %d bytes of memory", size);
|
||||
heap_block* current = start;
|
||||
|
||||
// look for a free block
|
||||
while(current < start + heap_size)
|
||||
{
|
||||
if(current->size >= size && current->Used == false )
|
||||
{
|
||||
// We found a spot
|
||||
// Set the spot to in-use
|
||||
current->Used = false;
|
||||
// return the free address
|
||||
// NOTE: added an offset from the initial address to accomodate for
|
||||
// meta-data.
|
||||
return current + sizeof(heap_block);
|
||||
|
||||
}
|
||||
|
||||
current += current->Size + sizeof(heap_block);
|
||||
}
|
||||
|
||||
// If we are here we need more memory so we should
|
||||
// probably ask the VMM for more
|
||||
// TODO: ask for more memory | Extend kernel heap
|
||||
|
||||
}
|
||||
|
||||
void free(void* addr)
|
||||
{
|
||||
// clear the free boolean that corresponds to this adddress
|
||||
// This should be fairly simple
|
||||
heap_block* allocatedBlock = addr - sizeof(heap_block);
|
||||
allocate_block->Used = false;
|
||||
}
|
||||
|
||||
void initHeap()
|
||||
{
|
||||
|
||||
}
|
9
source/kernel/memory/KernelHeap.h
Normal file
9
source/kernel/memory/KernelHeap.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void initHeap();
|
||||
|
||||
void* malloc (size_t size );
|
||||
void free(void* addr);
|
||||
|
143
source/kernel/memory/PhysicalMemoryManager.cpp
Normal file
143
source/kernel/memory/PhysicalMemoryManager.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include "./PhysicalMemoryManager.h"
|
||||
|
||||
PhysicalMemoryManagerInfoBlock* PMMInfoBlock;
|
||||
extern uint32_t* boot_page_directory;
|
||||
extern uint32_t* boot_page_table;
|
||||
|
||||
const uint32_t KERNEL_OFFSET = 0xC0000000;
|
||||
void SetupPhysicalMemoryManager( BootInfoBlock* Bootinfo) {
|
||||
// NOTE: Physical memory map will override the boot info for now!
|
||||
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) (&BootInfoBlock_pptr + KERNEL_OFFSET );
|
||||
printf("Setting up physical memory infoblock (0x%x) \n", (uint32_t)&PMMInfoBlock);
|
||||
/*
|
||||
Every byte contains 8 pages
|
||||
A page is 4096 kib
|
||||
Every block (1 bit) represent an page
|
||||
*/
|
||||
|
||||
// Calculate the maximum number of blocks
|
||||
printf("Maxblocks at address(0x%x)\n" , (uint32_t)&(PMMInfoBlock->max_blocks));
|
||||
|
||||
int maximum_blocks = (uint32_t)Bootinfo->MemorySize / BLOCK_SIZE / 8;
|
||||
printf("Set bitmap block maximum: %d\n", maximum_blocks);
|
||||
PMMInfoBlock->max_blocks = maximum_blocks;
|
||||
|
||||
printf("Set used blocks to zero\n");
|
||||
PMMInfoBlock->used_blocks = 0;
|
||||
|
||||
printf("Determine memory bit map address");
|
||||
// put the map after the gdt
|
||||
PMMInfoBlock->memoryBitMap = (uint32_t*) ( 0xC010b100) ;
|
||||
|
||||
printf("Maximum num blocks: %d \n",PMMInfoBlock->max_blocks);
|
||||
//Size of memory map
|
||||
uint32_t memMap_size = PMMInfoBlock->max_blocks / 8;
|
||||
printf("Memory map size: %d\n", memMap_size);
|
||||
printf("Address of memory map 0x%x\n", PMMInfoBlock->memoryBitMap);
|
||||
// Set all places in memory as free
|
||||
memset(PMMInfoBlock->memoryBitMap, 0xFF, memMap_size );
|
||||
|
||||
// Loop over memory map and allocate physical locations
|
||||
// that are already in use
|
||||
MemoryInfoBlock* currentBlock = (MemoryInfoBlock*) ((uint32_t)Bootinfo->MemoryMap + KERNEL_OFFSET) ;
|
||||
printf("Starting address: 0x%x\n", currentBlock);
|
||||
while( (uint32_t) currentBlock->next != 0x0)
|
||||
{
|
||||
if(IS_AVAILABLE_MEM(currentBlock->type)){
|
||||
printf("skip!\n");
|
||||
} else {
|
||||
printf("allocate region 0x%x of size 0x%x\n" , currentBlock->Base_addr, currentBlock->Memory_Size);
|
||||
allocate_region((uint32_t) currentBlock->Base_addr, currentBlock->Memory_Size);
|
||||
}
|
||||
|
||||
currentBlock = (MemoryInfoBlock*) ((uint32_t)currentBlock->next + KERNEL_OFFSET );
|
||||
}
|
||||
|
||||
uint32_t kernel_size = ((uint32_t)&kernel_end - (uint32_t)&kernel_begin ) - KERNEL_OFFSET;
|
||||
|
||||
printf("kernel size in memory: 0x%x\n", kernel_size);
|
||||
allocate_region((uint32_t)&kernel_begin, kernel_size);
|
||||
|
||||
printf("allocate BIOS region\n");
|
||||
allocate_region (0x0000000, 0x00100000);
|
||||
}
|
||||
|
||||
// NOTE: This can only give blocks of 4kb at a time!
|
||||
// We might at some point want to allocate multiple blocks at once.
|
||||
void* allocate_block() {
|
||||
uint8_t blocks_available = PMMInfoBlock->max_blocks - PMMInfoBlock->used_blocks;
|
||||
// Are there any blocks available?
|
||||
if( blocks_available <= 0)
|
||||
{
|
||||
printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find 1 free block somewhere
|
||||
int free_block_index = bitmap_first_unset(PMMInfoBlock->memoryBitMap, PMMInfoBlock->max_blocks / 8 );
|
||||
|
||||
if(free_block_index == -1)
|
||||
{
|
||||
printf("Could not find a good block!\n");
|
||||
// Could not find a block
|
||||
return (void*)0xFFFF;
|
||||
}
|
||||
|
||||
if(free_block_index == 0)
|
||||
printf("Somethings wrong!!!\n");
|
||||
|
||||
// Set the block to be used!
|
||||
bitmap_unset(PMMInfoBlock->memoryBitMap, free_block_index);
|
||||
// Increase the used_block count!
|
||||
PMMInfoBlock->used_blocks++;
|
||||
printf("used blocks: 0x%x\n", PMMInfoBlock->used_blocks);
|
||||
// return the pointer to the physical address
|
||||
return (void*) (BLOCK_SIZE * free_block_index);
|
||||
}
|
||||
|
||||
void free_block(void* p) {
|
||||
// If it is a null pointer we don't need to do anything.
|
||||
if(p==0) {
|
||||
return;
|
||||
}
|
||||
// calculate the index into the bitmap
|
||||
int index = ((uint32_t) p) / BLOCK_SIZE;
|
||||
|
||||
// set the block to be free
|
||||
bitmap_set(PMMInfoBlock->memoryBitMap, index);
|
||||
PMMInfoBlock->used_blocks--;
|
||||
printf("used blocks: 0x%x, after free\n", PMMInfoBlock->used_blocks);
|
||||
|
||||
}
|
||||
|
||||
void allocate_region(uint32_t startAddress, uint32_t size) {
|
||||
// every bit should be 4KiB
|
||||
// every byte is 8*4KiB = 32KiB
|
||||
|
||||
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
|
||||
int startBlock = (startAddress / 1024) / 4 / 8 ;
|
||||
|
||||
|
||||
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
|
||||
{
|
||||
bitmap_unset(PMMInfoBlock->memoryBitMap, startBlock+ i);
|
||||
PMMInfoBlock->used_blocks++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void deallocate_region(uint32_t StartAddress , uint32_t size ) {
|
||||
// reverse of what happened in allocate_region
|
||||
|
||||
int NumberOfBlocks = (size / 1024) / 4 / 8 + 1;
|
||||
int startBlock = (StartAddress / 1024) / 4 / 8;
|
||||
|
||||
for(int i = 0; i < NumberOfBlocks; i++)
|
||||
{
|
||||
bitmap_set(PMMInfoBlock->memoryBitMap, startBlock + i);
|
||||
PMMInfoBlock->used_blocks --;
|
||||
}
|
||||
}
|
||||
|
||||
|
26
source/kernel/memory/PhysicalMemoryManager.h
Normal file
26
source/kernel/memory/PhysicalMemoryManager.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include "../prekernel/bootstructure.h"
|
||||
#include "../terminal/kterm.h"
|
||||
#include "../lib/mem.h"
|
||||
#include "../bitmap.h"
|
||||
|
||||
// Asumming i386 for now!
|
||||
#define BLOCK_SIZE 4092
|
||||
|
||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
|
||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||
|
||||
struct PhysicalMemoryManagerInfoBlock
|
||||
{
|
||||
uint32_t* memoryBitMap;
|
||||
uint32_t pmmap_size;
|
||||
uint32_t max_blocks;
|
||||
int used_blocks;
|
||||
};
|
||||
|
||||
void SetupPhysicalMemoryManager(BootInfoBlock* memory);
|
||||
void free_block(void* ptr);
|
||||
void* allocate_block();
|
||||
void allocate_region(uint32_t, uint32_t);
|
||||
void deallocate_region(uint32_t , uint32_t );
|
73
source/kernel/memory/VirtualMemoryManager.cpp
Normal file
73
source/kernel/memory/VirtualMemoryManager.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "VirtualMemoryManager.h"
|
||||
extern uint32_t boot_page_directory[1024] ;
|
||||
extern uint32_t boot_page_table[1024];
|
||||
void AllocatePage(uint32_t vaddr)
|
||||
{
|
||||
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
|
||||
|
||||
// allocate a page at virtual address
|
||||
int PageDirectoryEntryIndex = vaddr >> 22;
|
||||
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
|
||||
|
||||
printf("Allocation happening at PDE: %d PTE: %d\n", PageDirectoryEntryIndex, PageTableEntryIndex);
|
||||
|
||||
// check if the page directory entry is marked as present
|
||||
if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) {
|
||||
|
||||
uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000 + 0xC0000000);
|
||||
|
||||
// check if the page table entry is marked as present
|
||||
if ( page_table[PageTableEntryIndex] & 0x1 )
|
||||
{
|
||||
// Map the entry to a physical page
|
||||
page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
|
||||
} else{
|
||||
// mark page as present
|
||||
page_table[PageTableEntryIndex] = 0x3;
|
||||
}
|
||||
|
||||
} else {
|
||||
// mark the page table as present and allocate a physical block for it
|
||||
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FreePage(uint32_t vaddr )
|
||||
{
|
||||
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
|
||||
|
||||
// allocate a page at virtual address
|
||||
int PageDirectoryEntryIndex = vaddr >> 22;
|
||||
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
|
||||
|
||||
uint32_t* pageTable = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000 + 0xC0000000);
|
||||
|
||||
|
||||
void* physicalAddressToFree = (void*)(pageTable[PageTableEntryIndex] & 0xFFFFE000 + 0xC0000000);
|
||||
free_block(physicalAddressToFree);
|
||||
|
||||
pageTable[PageTableEntryIndex] = 0x0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Map ( uint32_t vaddr, uint32_t paddr)
|
||||
{
|
||||
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
|
||||
|
||||
// allocate a page at virtual address
|
||||
int PageDirectoryEntryIndex = vaddr >> 22;
|
||||
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
|
||||
}
|
||||
|
||||
void Unmap(uint32_t vaddr)
|
||||
{
|
||||
// NOTE: I will implement lazy unmapping for now
|
||||
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
|
||||
|
||||
// allocate a page at virtual address
|
||||
int PageDirectoryEntryIndex = vaddr >> 22;
|
||||
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
|
||||
}
|
10
source/kernel/memory/VirtualMemoryManager.h
Normal file
10
source/kernel/memory/VirtualMemoryManager.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "PhysicalMemoryManager.h"
|
||||
#include "../terminal/kterm.h"
|
||||
#include "../cpu.h"
|
||||
|
||||
void AllocatePage(uint32_t v_addr );
|
||||
void FreePage(uint32_t v_addr);
|
||||
|
||||
void Map(uint32_t p_addr, uint32_t v_addr);
|
||||
void Unmap (uint32_t v_addr);
|
@ -1,5 +1,5 @@
|
||||
#include "gdtc.h"
|
||||
#include "../tty/kterm.h"
|
||||
#include "../../terminal/kterm.h"
|
||||
|
||||
#define NULL_SEGMENT 0
|
||||
#define KERNEL_CODE_SEGMENT 1
|
||||
@ -29,6 +29,9 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
|
||||
|
||||
void initGDT(){
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init GDT!\n");
|
||||
#endif
|
||||
// NULL segment
|
||||
add_descriptor(NULL_SEGMENT, 0,0,0,0);
|
||||
|
||||
@ -48,15 +51,8 @@ void initGDT(){
|
||||
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
|
||||
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
|
||||
|
||||
printf("Hello GDT!\n");
|
||||
|
||||
printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable));
|
||||
|
||||
LoadGlobalDescriptorTable();
|
||||
|
||||
// while (true)
|
||||
// asm volatile("hlt");
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
45
source/kernel/prekernel/bootstructure.h
Normal file
45
source/kernel/prekernel/bootstructure.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" const uint32_t kernel_begin;
|
||||
extern "C" const uint32_t kernel_end;
|
||||
|
||||
#define IS_AVAILABLE_MEM(MEM_TYPE) MEM_TYPE & 0x1
|
||||
#define IS_ACPI_MEM(MEM_TYPE) MEM_TYPE & 0x2
|
||||
#define IS_RESERVED_MEM(MEM_TYPE) MEM_TYPE & 0x4
|
||||
#define IS_NVS_MEMORY(MEM_TYPE) MEM_TYPE & 0x8
|
||||
#define IS_BADRAM_MEMORY(MEM_TYPE) MEM_TYPE & 0x10
|
||||
|
||||
struct MemoryInfoBlock {
|
||||
uint32_t Base_addr ;
|
||||
uint32_t Memory_Size;
|
||||
MemoryInfoBlock* next;
|
||||
uint8_t type;
|
||||
|
||||
};
|
||||
struct BootInfoBlock {
|
||||
bool MapIsInvalid;
|
||||
uint32_t bootDeviceID ;
|
||||
|
||||
uint32_t GrubModuleCount;
|
||||
|
||||
bool ValidSymbolTable;
|
||||
uint32_t SymbolTableAddr;
|
||||
uint32_t SymbolTabSize;
|
||||
uint32_t SymbolStrSize;
|
||||
|
||||
bool ValidELFHeader;
|
||||
|
||||
bool EnabledVBE;
|
||||
|
||||
bool PhysicalMemoryMapAvailable;
|
||||
MemoryInfoBlock* MemoryMap;
|
||||
uint32_t map_size;
|
||||
uint32_t MemorySize ;
|
||||
|
||||
};
|
||||
|
||||
// TODO Put the BootInfoBlock 1MB above the kernel.
|
||||
const uint32_t BootInfoBlock_pptr = (uint32_t)&kernel_end - 0xC0000000 + 0x1;
|
||||
const uint32_t MemoryMapHeap_pptr = BootInfoBlock_pptr + sizeof(BootInfoBlock);
|
120
source/kernel/prekernel/prekernel.cpp
Normal file
120
source/kernel/prekernel/prekernel.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "multiboot.h"
|
||||
#include "bootstructure.h"
|
||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
|
||||
|
||||
|
||||
extern "C" void prekernelSetup ( unsigned long magic, multiboot_info_t* mbi) {
|
||||
|
||||
// Create the bootInfoBlock at its location
|
||||
BootInfoBlock* BIB = (BootInfoBlock*) BootInfoBlock_pptr;
|
||||
|
||||
/*
|
||||
* Check Multiboot magic number
|
||||
*/
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
|
||||
{
|
||||
BIB->MapIsInvalid = true;
|
||||
// crash
|
||||
return;
|
||||
} else{
|
||||
BIB->MapIsInvalid = false;
|
||||
}
|
||||
|
||||
/* is boot device valid ? */
|
||||
if (CHECK_FLAG (mbi->flags, 1))
|
||||
{
|
||||
BIB->bootDeviceID = mbi->boot_device;
|
||||
} else{
|
||||
BIB->bootDeviceID = 0x11111111;
|
||||
}
|
||||
|
||||
/* Are mods_* valid? */
|
||||
if(CHECK_FLAG ( mbi->flags, 3)){
|
||||
multiboot_module_t *mod;
|
||||
uint32_t i;
|
||||
|
||||
BIB->GrubModuleCount = mbi->mods_count;
|
||||
|
||||
|
||||
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Is the symbol table of a.out valid? */
|
||||
if (CHECK_FLAG(mbi->flags, 4))
|
||||
{
|
||||
BIB->ValidSymbolTable = true;
|
||||
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
|
||||
|
||||
} else{
|
||||
BIB->ValidSymbolTable = false;
|
||||
}
|
||||
|
||||
/* Is the section header table of ELF valid? */
|
||||
if (CHECK_FLAG(mbi->flags, 5))
|
||||
{
|
||||
BIB->ValidELFHeader = true;
|
||||
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
|
||||
|
||||
}else{
|
||||
BIB->ValidELFHeader = false;
|
||||
}
|
||||
/*
|
||||
If we got a memory map from our bootloader we
|
||||
should be parsing it to find out the memory regions available.
|
||||
*/
|
||||
if (CHECK_FLAG(mbi->flags, 6))
|
||||
{
|
||||
BIB->PhysicalMemoryMapAvailable = true;
|
||||
BIB->MemoryMap = (MemoryInfoBlock*) MemoryMapHeap_pptr;
|
||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) (mbi->mmap_addr) ;
|
||||
auto MemoryMapEnd = mbi->mmap_addr + mbi->mmap_length;
|
||||
|
||||
auto CurrentInfoBlock = BIB->MemoryMap;
|
||||
|
||||
uint32_t RAM_size = 0;
|
||||
|
||||
while((unsigned long) mmap < MemoryMapEnd){
|
||||
BIB->map_size += sizeof(MemoryInfoBlock);
|
||||
CurrentInfoBlock->Base_addr = mmap->addr;
|
||||
CurrentInfoBlock->Memory_Size = mmap->len;
|
||||
|
||||
|
||||
if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||
CurrentInfoBlock->type |= 0x1;
|
||||
RAM_size += mmap->len;
|
||||
if(mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE)
|
||||
CurrentInfoBlock->type |= 0x2;
|
||||
if(mmap->type == MULTIBOOT_MEMORY_RESERVED)
|
||||
CurrentInfoBlock->type |= 0x4;
|
||||
if(mmap->type == MULTIBOOT_MEMORY_NVS)
|
||||
CurrentInfoBlock->type |= 0x8;
|
||||
if(mmap->type == MULTIBOOT_MEMORY_BADRAM)
|
||||
CurrentInfoBlock->type |= 0x10;
|
||||
|
||||
|
||||
// continue to the next block
|
||||
mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size));
|
||||
|
||||
CurrentInfoBlock->next = (MemoryInfoBlock*) ((uint32_t)CurrentInfoBlock) + sizeof(MemoryInfoBlock);
|
||||
CurrentInfoBlock = CurrentInfoBlock->next;
|
||||
|
||||
}
|
||||
|
||||
CurrentInfoBlock->next = (MemoryInfoBlock*) 0x0;
|
||||
BIB->MemorySize = RAM_size;
|
||||
} else
|
||||
{
|
||||
BIB->PhysicalMemoryMapAvailable = false;
|
||||
}
|
||||
|
||||
/* Draw diagonal blue line */
|
||||
if (CHECK_FLAG (mbi->flags, 12)){
|
||||
BIB->EnabledVBE = true;
|
||||
} else{
|
||||
BIB->EnabledVBE;
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
#pragma once
|
||||
#include "tty/kterm.h"
|
||||
|
||||
#include "terminal/kterm.h"
|
||||
#include "io.h"
|
||||
|
||||
#define PORT 0x3f8
|
||||
static int init_serial() {
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init Serial\n");
|
||||
#endif
|
||||
|
||||
inline static int init_serial() {
|
||||
outb(PORT + 1, 0x00); // Disable all interrupts
|
||||
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||
@ -26,95 +30,33 @@ inline static int init_serial() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int is_transmit_empty() {
|
||||
int is_transmit_empty() {
|
||||
return inb(PORT + 5) & 0x20;
|
||||
}
|
||||
|
||||
inline void write_serial(char a) {
|
||||
void write_serial(char a) {
|
||||
while (is_transmit_empty() == 0);
|
||||
|
||||
outb(PORT,a);
|
||||
}
|
||||
|
||||
inline int serial_received() {
|
||||
int serial_received() {
|
||||
return inb(PORT + 5) & 1;
|
||||
}
|
||||
|
||||
inline char read_serial() {
|
||||
char read_serial() {
|
||||
while (serial_received() == 0);
|
||||
|
||||
return inb(PORT);
|
||||
}
|
||||
|
||||
inline void print_serial(const char* string ){
|
||||
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(){
|
||||
void test_serial(){
|
||||
/** Serial test **/
|
||||
kterm_writestring("Writing to COM1 serial port:");
|
||||
init_serial();
|
72
source/kernel/supervisorterminal/superVisorTerminal.cpp
Normal file
72
source/kernel/supervisorterminal/superVisorTerminal.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "superVisorTerminal.h"
|
||||
|
||||
void startSuperVisorTerminal(){
|
||||
while (true){
|
||||
|
||||
printf("SUPERVISOR:>$ " );
|
||||
int characterCount = 0;
|
||||
char command[10] = "";
|
||||
|
||||
// NOTE: lets just show a kernel prompt
|
||||
uint8_t ScanCode = getKey();
|
||||
while( ScanCode != 0x1C )
|
||||
{
|
||||
char character = getASCIIKey();
|
||||
kterm_put(character );
|
||||
// wHAT THE HELL
|
||||
|
||||
if( characterCount < 10 ){
|
||||
command[characterCount] = character;
|
||||
characterCount++;
|
||||
}
|
||||
|
||||
ScanCode = getKey();
|
||||
}
|
||||
printf("\n");
|
||||
KeyHandled();
|
||||
|
||||
|
||||
if ( strncmp("DATE", command , characterCount ) == 0 )
|
||||
{
|
||||
read_rtc();
|
||||
printf("======= Time & Date ==========\n");
|
||||
printf(" - Date: %02d-%02d-%02d\n",day, month, year);
|
||||
printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second);
|
||||
printf(" - Ticks: %09d\n", pit_tick);
|
||||
}
|
||||
else if( strncmp ("MEMORY" , command , characterCount) == 0 )
|
||||
{
|
||||
// Show memory layout
|
||||
printf("========= Memory ==========\n");
|
||||
printf("Not Available!\n");
|
||||
printf("Kernel MemoryMap:\n");
|
||||
printf("Frames used: -- \n");
|
||||
printf("Available Memory:-- \n");
|
||||
printf("Reserved Memory: -- bytes\n");
|
||||
}
|
||||
else if(strncmp("TEST", command, characterCount) == 0)
|
||||
{
|
||||
// TEST #DE exception
|
||||
asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0
|
||||
}
|
||||
else if (strncmp("VERSION", command , characterCount) == 0)
|
||||
{
|
||||
// Show version information
|
||||
printf("========= Version ========\n");
|
||||
printf("Kernel v%d\n", 0);
|
||||
|
||||
}
|
||||
else if(strncmp("CLEAR", command, characterCount) == 0)
|
||||
{
|
||||
kterm_init();
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
}
|
8
source/kernel/supervisorterminal/superVisorTerminal.h
Normal file
8
source/kernel/supervisorterminal/superVisorTerminal.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "../terminal/kterm.h"
|
||||
#include "../time.h"
|
||||
#include "../drivers/pit/pit.h"
|
||||
#include "../drivers/ps-2/keyboard.h"
|
||||
#include "../memory/PhysicalMemoryManager.h"
|
||||
|
||||
void startSuperVisorTerminal();
|
@ -21,7 +21,8 @@ void kterm_init () {
|
||||
kterm_row = 0;
|
||||
kterm_column = 0;
|
||||
kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
|
||||
kterm_buffer = (uint16_t*) 0xB8000;
|
||||
kterm_buffer = (uint16_t*) 0xC03FF000;
|
||||
|
||||
for (size_t y = 0; y < VGA_HEIGHT; y++ ){
|
||||
for( size_t x = 0; x < VGA_WIDTH; x++){
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
@ -31,7 +32,6 @@ void kterm_init () {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void kterm_resetcolor(){
|
||||
kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
|
||||
}
|
||||
@ -42,9 +42,7 @@ void kterm_setcolor(uint8_t color){
|
||||
|
||||
void kterm_putat (char c, uint8_t color, size_t x, size_t y ) {
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
|
||||
kterm_buffer[index] = vga_entry(c, color);
|
||||
|
||||
}
|
||||
|
||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){
|
||||
@ -137,7 +135,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 *p1, *p2;
|
||||
unsigned long ud = d;
|
||||
@ -174,7 +172,7 @@ void itoa (char *buf, int base, int d) {
|
||||
}
|
||||
|
||||
void printf ( const char *format, ...) {
|
||||
return;
|
||||
|
||||
char **arg = (char **)&format;
|
||||
int c;
|
||||
char buf[20];
|
@ -1,14 +1,13 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../vga/colors.h"
|
||||
#include "../drivers/vga/colors.h"
|
||||
#include "../io.h"
|
||||
|
||||
extern "C"{
|
||||
#include "./../../libc/include/string.h"
|
||||
#include "../lib/string.h"
|
||||
}
|
||||
|
||||
void kterm_init();
|
||||
@ -33,9 +32,10 @@ uint16_t get_cursor_position();
|
||||
int get_cursor_x (uint16_t cursor_pos);
|
||||
int get_cursor_y (uint16_t cursor_pos);
|
||||
|
||||
extern "C" void itoa (char *buf, int base, int d);
|
||||
|
||||
void printf ( const char *format, ...);
|
||||
|
||||
//static void itoa (char *buf, int base, int d);
|
||||
|
||||
#define KernelTag "[Kernel]: "
|
||||
#define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
|
@ -1,7 +1,7 @@
|
||||
#define CURRENT_YEAR 2021 // Change this each year!
|
||||
|
||||
int century_register = 0x00; // Set by ACPI table parsing code if possible
|
||||
#include "time.h"
|
||||
|
||||
// Set by ACPI table parsing code if possible
|
||||
int century_register = 0x00;
|
||||
unsigned char second;
|
||||
unsigned char minute;
|
||||
unsigned char hour;
|
||||
@ -10,12 +10,6 @@ unsigned char month;
|
||||
unsigned int year;
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
cmos_address = 0x70,
|
||||
cmos_data = 0x71
|
||||
};
|
||||
|
||||
int get_update_in_progress_flag() {
|
||||
outb(cmos_address, 0x0A);
|
||||
return (inb(cmos_data) & 0x80);
|
||||
@ -109,45 +103,9 @@ void read_rtc() {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void ReadFromCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char tvalue, index;
|
||||
|
||||
for (index = 0; index < 128; index++)
|
||||
{
|
||||
asm(
|
||||
"cli\n\t" // Disable interrupts
|
||||
"mov al, index\n\t" // Move index address
|
||||
// since the 0x80 bit of al is not set, NMI is active
|
||||
"out 0x70,al\n\t" // Copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"in al,0x71\n\t" // Fetch 1 byte to al
|
||||
"sti\n\t" // Enable interrupts
|
||||
"mov tvalue,al\n\t");
|
||||
|
||||
array[index] = tvalue;
|
||||
void delay(int t){
|
||||
volatile int i,j;
|
||||
for(i=0;i<t;i++)
|
||||
for(j=0;j<25000;j++)
|
||||
asm("NOP");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
void WriteTOCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char index;
|
||||
|
||||
for(index = 0; index < 128; index++)
|
||||
{
|
||||
unsigned char tvalue = array[index];
|
||||
|
||||
asm("cli\n\t" // Clear interrupts
|
||||
"mov al,index\n\t" // move index address
|
||||
"out 0x70,al\n\t" // copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"mov al,tvalue\n\t" // move value to al
|
||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||
"sti\n\\t" ); // Enable interrupts
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
23
source/kernel/time.h
Normal file
23
source/kernel/time.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "io.h"
|
||||
#define CURRENT_YEAR 2021
|
||||
|
||||
|
||||
extern int century_register;
|
||||
extern unsigned char second;
|
||||
extern unsigned char minute;
|
||||
extern unsigned char hour;
|
||||
extern unsigned char day;
|
||||
extern unsigned char month;
|
||||
extern unsigned int year;
|
||||
|
||||
|
||||
enum {
|
||||
cmos_address = 0x70,
|
||||
cmos_data = 0x71
|
||||
};
|
||||
|
||||
int get_update_in_progress_flag();
|
||||
unsigned char get_RTC_register();
|
||||
void read_rtc();
|
||||
void delay(int t);
|
@ -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,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,149 +0,0 @@
|
||||
#include "idt.h"
|
||||
//#include "scancodes/set1.h"
|
||||
|
||||
IDT_entry idt_table[256];
|
||||
IDT_ptr idt_ptr;
|
||||
|
||||
void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
|
||||
idt_table[num].offset_1 = base & 0xFFFF;
|
||||
idt_table[num].selector = sel;
|
||||
idt_table[num].zero = 0;
|
||||
idt_table[num].type_attr = flags;
|
||||
idt_table[num].offset_2 = (base >> 16) & 0xFFFF;
|
||||
|
||||
};
|
||||
|
||||
|
||||
void irs_handler (registers regs) {
|
||||
kterm_writestring("received interrupt!\n");
|
||||
|
||||
printf("(IRS) Interrupt number: %d \n", regs.int_no);
|
||||
|
||||
if( regs.int_no == 13){
|
||||
printf(" Error code: %d \n", regs.err_code);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void irq_handler (registers regs) {
|
||||
|
||||
|
||||
if ( regs.int_no != 0) {
|
||||
kterm_writestring("received interrupt!\n");
|
||||
printf("(IRQ) Interrupt number: %d \n", regs.int_no);
|
||||
|
||||
}
|
||||
|
||||
if ( regs.int_no == 1 ){
|
||||
// Keyboard interrupt !!
|
||||
|
||||
int scan;
|
||||
/*register*/int i;
|
||||
|
||||
// Read scancode
|
||||
|
||||
scan = inb(0x60);
|
||||
|
||||
// Send ack message!
|
||||
i = inb(0x61);
|
||||
outb(0x61, i|0x80);
|
||||
outb(0x61, i);
|
||||
kterm_writestring("A key was pressed/released\n");
|
||||
printf( "Scancode: %x\n", scan);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
outb(0x20, 0x20); // send end of interrupt to master
|
||||
|
||||
if ( regs.int_no > 8 && regs.int_no <= 15) {
|
||||
outb(0xA0, 0x20); // send end of interrupt to slave
|
||||
}
|
||||
|
||||
|
||||
if( regs.int_no == 13){
|
||||
printf(" Error code: %d \n", regs.err_code);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void init_idt(){
|
||||
// Initialise the IDT pointer
|
||||
idt_ptr.length = sizeof(IDT_entry) * 255;
|
||||
idt_ptr.base = (uint32_t)&idt_table;
|
||||
|
||||
|
||||
// TODO: Set everything to zero first
|
||||
|
||||
set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F);
|
||||
set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E);
|
||||
set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E);
|
||||
set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E);
|
||||
set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E);
|
||||
set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E);
|
||||
set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E);
|
||||
set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E);
|
||||
set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E);
|
||||
set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E);
|
||||
set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E);
|
||||
set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E);
|
||||
set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E);
|
||||
set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E);
|
||||
set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E);
|
||||
set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E);
|
||||
set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E);
|
||||
set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E);
|
||||
set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E);
|
||||
set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E);
|
||||
set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E);
|
||||
set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E);
|
||||
set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E);
|
||||
set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E);
|
||||
set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E);
|
||||
set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E);
|
||||
set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E);
|
||||
set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E);
|
||||
set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E);
|
||||
set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E);
|
||||
set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E);
|
||||
set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E);
|
||||
|
||||
|
||||
//print_serial("Remapping PIC\n");
|
||||
PIC_remap(0x20, 0x28);
|
||||
|
||||
|
||||
// pic IRQ Table
|
||||
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
|
||||
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E);
|
||||
set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E);
|
||||
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
|
||||
set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E);
|
||||
set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E);
|
||||
set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E);
|
||||
set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E);
|
||||
set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E);
|
||||
set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
|
||||
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
||||
set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
|
||||
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E);
|
||||
set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E);
|
||||
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
|
||||
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
|
||||
|
||||
|
||||
idt_flush((uint32_t)&idt_ptr);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
#include "kernel.h"
|
||||
#define GB4 524288
|
||||
#define GB2 262144
|
||||
extern "C" void kernel_main (void);
|
||||
extern "C" void putPixel(int pos_x, int pos_y, unsigned char VGA_COLOR , unsigned char addr , unsigned char pixelWidth, unsigned pitch );
|
||||
|
||||
|
||||
extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||
/** initialize terminal interface */
|
||||
// kterm_init();
|
||||
|
||||
printf("Magic flag 0x%8x\n", magic);
|
||||
printf("Magic must be 0x%8x\n", MULTIBOOT_BOOTLOADER_MAGIC);
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||
printf("Invalid magic number: 0x%8x\n", magic);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckMBT( (multiboot_info_t *) addr);
|
||||
|
||||
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
||||
|
||||
/* Are mmap_* valid? */
|
||||
if (CHECK_FLAG(mbt->flags, 6)){
|
||||
PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/);
|
||||
PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length);
|
||||
PhysicalMemoryManager_deinitialise_kernel();
|
||||
extern uint8_t* kernel_begin;
|
||||
extern uint8_t* kernel_end;
|
||||
|
||||
printf("Kernel MemoryMap:\n");
|
||||
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
||||
}
|
||||
|
||||
initGDT();
|
||||
|
||||
|
||||
kernel_main();
|
||||
|
||||
|
||||
}
|
||||
|
||||
extern "C" void kernel_main (void) {
|
||||
|
||||
printf("call to init serial\n");
|
||||
init_serial();
|
||||
|
||||
|
||||
while (true){
|
||||
//Read time indefinetely
|
||||
read_rtc();
|
||||
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
extern "C"{
|
||||
#include "../libc/include/string.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 "io.h"
|
||||
#include "time.h"
|
||||
#include "cpu.h"
|
||||
#include "serial.h"
|
||||
|
||||
#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,47 +0,0 @@
|
||||
/* The bootloader will look at this image and start execution at the symbol
|
||||
designated as the entry point. */
|
||||
ENTRY(_start)
|
||||
|
||||
/* Tell where the various sections of the object files will be put in the final
|
||||
kernel image. */
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||
loaded at by the bootloader. */
|
||||
. = 1M;
|
||||
kernel_begin = .;
|
||||
/* 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.
|
||||
Next we'll put the .text section. */
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
/* Read-only data. */
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
/* Read-write data (initialized) */
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
kernel_end = .;
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
#include "PageDirectory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
void PageDirectory::enable(){
|
||||
// https://wiki.osdev.org/Setting_Up_Paging
|
||||
//set each entry to not present
|
||||
int i;
|
||||
for(i = 0; i < 1024; i++)
|
||||
{
|
||||
// This sets the following flags to the pages:
|
||||
// Supervisor: Only kernel-mode can access them
|
||||
// Write Enabled: It can be both read from and written to
|
||||
// Not Present: The page table is not present
|
||||
this->page_directory[i] = 0x00000002;
|
||||
}
|
||||
|
||||
// holds the physical address where we want to start mapping these pages to.
|
||||
// in this case, we want to map these pages to the very beginning of memory.
|
||||
|
||||
//we will fill all 1024 entries in the table, mapping 4 megabytes
|
||||
for(unsigned int i = 0; i < 1024; i++)
|
||||
{
|
||||
// As the address is page aligned, it will always leave 12 bits zeroed.
|
||||
// Those bits are used by the attributes ;)
|
||||
first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
|
||||
}
|
||||
|
||||
// attributes: supervisor level, read/write, present
|
||||
this->page_directory[0] = ((unsigned int)first_page_table) | 3;
|
||||
|
||||
|
||||
loadPageDirectory(this->page_directory);
|
||||
enablePaging();
|
||||
}
|
||||
|
||||
/*
|
||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
|
||||
{
|
||||
from = from & 0xFFFFF000; // Discard the bits we don't want
|
||||
for (; size > 0; from += 4096, first_pte++)
|
||||
{
|
||||
*first_pte = from | 1; // makr page present.
|
||||
}
|
||||
}
|
||||
*/
|
@ -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,33 +0,0 @@
|
||||
#pragma once
|
||||
/**
|
||||
* We'll need something to this effect to allocate memory in the kernel
|
||||
* this will hopefully someday implement a full slab allocator
|
||||
**/
|
||||
enum SlabState {
|
||||
empty,
|
||||
partial,
|
||||
full
|
||||
};
|
||||
|
||||
class CacheSlab {
|
||||
const int SlabSize = 4000;
|
||||
void* start = 0x0;
|
||||
};
|
||||
|
||||
|
||||
class Allocator {
|
||||
|
||||
public:
|
||||
Allocator();
|
||||
~Allocator();
|
||||
|
||||
void* kmalloc( int size );
|
||||
void kfree (void* address);
|
||||
|
||||
private:
|
||||
CacheSlab** _cache;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
@ -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,9 +0,0 @@
|
||||
#include "string.h"
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
while(str[len]){
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
21
todo.md
21
todo.md
@ -0,0 +1,21 @@
|
||||
# TODO list
|
||||
|
||||

|
||||
|
||||
|
||||
This list keeps me focused and organised so I don't forget what
|
||||
needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember
|
||||
to do on a more in depth level.
|
||||
|
||||
## --
|
||||
[ ] Setup paging \
|
||||
[ ] HELP command
|
||||
[ ] Setup a proper HEAP \
|
||||
[ ] Setup a proper Stack \
|
||||
[ ] Setup KMalloc and KFree \
|
||||
[ ] Merge Functioning Feature branches into sandboxKernelDev \
|
||||
[ ] Remove merged feature branches \
|
||||
[ ] Merge sandboxKernelDev with dev \
|
||||
[ ] Remove sandboxKernelDev branch \
|
||||
[ ] Implement proper virtual filesystem
|
||||
|
||||
|
Reference in New Issue
Block a user