Add proper Physical memory management to this branch
to ensure it doesn't get too out of date We can now run the FAT command to demo reading out the FAT16 filesystem, however this will cause the need for a reboot as after this command. We are FOR NOW not able to put in any new commands
This commit is contained in:
commit
2e59e6593e
31
Makefile
31
Makefile
@ -9,9 +9,8 @@ OFILES = \
|
||||
$(BUILD_DIR)/boot.o \
|
||||
$(BUILD_DIR)/kterm.o \
|
||||
$(BUILD_DIR)/kernel.o \
|
||||
$(BUILD_DIR)/PhysicalMemoryManager.o \
|
||||
$(BUILD_DIR)/memory.o \
|
||||
$(BUILD_DIR)/io.o \
|
||||
$(BUILD_DIR)/PageDirectory.o \
|
||||
$(BUILD_DIR)/gdtc.o \
|
||||
$(BUILD_DIR)/idt.o \
|
||||
$(BUILD_DIR)/pci.o \
|
||||
@ -21,6 +20,11 @@ $(BUILD_DIR)/pcidevice.o \
|
||||
$(BUILD_DIR)/atapiDevice.o \
|
||||
$(BUILD_DIR)/ataDevice.o \
|
||||
$(BUILD_DIR)/rsdp.o \
|
||||
$(BUILD_DIR)/pit.o \
|
||||
$(BUILD_DIR)/time.o \
|
||||
$(BUILD_DIR)/keyboard.o \
|
||||
$(BUILD_DIR)/sv-terminal.o \
|
||||
|
||||
|
||||
|
||||
SRC_DIR = src
|
||||
@ -39,8 +43,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
|
||||
@ -77,7 +79,7 @@ $(BUILD_DIR)/kterm.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/boot.o:
|
||||
$(AS) $(SRC_DIR)/kernel/boot.S -o $(BUILD_DIR)/boot.o
|
||||
$(AS) $(SRC_DIR)/kernel/boot.s -o $(BUILD_DIR)/boot.o
|
||||
|
||||
$(BUILD_DIR)/crti.o:
|
||||
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
|
||||
@ -88,8 +90,6 @@ $(BUILD_DIR)/crtn.o:
|
||||
$(BUILD_DIR)/io.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/IO/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(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
|
||||
@ -122,3 +122,20 @@ $(BUILD_DIR)/ataDevice.o:
|
||||
|
||||
$(BUILD_DIR)/rsdp.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/drivers/ACPI/rsdp.cpp -o $(BUILD_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/pit.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
$(BUILD_DIR)/keyboard.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/keyboard/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
$(BUILD_DIR)/time.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/time.cpp -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/sv-terminal.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/sv-terminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
||||
$(BUILD_DIR)/memory.o:
|
||||
$(CPP) -c $(SRC_DIR)/kernel/memory/memory.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
|
@ -26,7 +26,8 @@ Correctly identified our ATAPI device 🎉
|
||||
________________________
|
||||
|
||||
### 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
|
||||
|
29
features.md
29
features.md
@ -1,18 +1,25 @@
|
||||
# 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)
|
||||
|
||||
@ -24,6 +31,8 @@
|
||||
<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 +41,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 \
|
||||
|
@ -1,3 +1,8 @@
|
||||
menuentry "BarinkOS"{
|
||||
GRUB_DEFAULT=0
|
||||
GRUB_TIMEOUT=-1
|
||||
GRUB_HIDDEN_TIMEOUT=0
|
||||
GRUB_HIDDEN_TIMEOUT_QUITE=true
|
||||
|
||||
menuentry "BarinkOS" {
|
||||
multiboot /boot/myos.bin
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ stack_bottom:
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
.include "./src/kernel/gdt/gdt.s"
|
||||
.include "./src/kernel/irs_table.s"
|
||||
.include "./src/kernel/irq_table.s"
|
||||
.include "./src/kernel/idt/idt.s"
|
||||
@ -45,34 +46,21 @@ _start:
|
||||
pushl %eax
|
||||
|
||||
call early_main
|
||||
|
||||
|
||||
mov %cr0, %eax
|
||||
or $1, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
|
||||
call kernel_main
|
||||
|
||||
|
||||
cli
|
||||
|
||||
|
||||
|
||||
.include "./src/kernel/gdt/gdt.s"
|
||||
|
||||
loadIDT:
|
||||
#load idt
|
||||
call init_idt
|
||||
sti
|
||||
|
||||
# Try enable A20
|
||||
# mov $0x2401, %ax
|
||||
# int $0x15
|
||||
1: hlt
|
||||
jmp 1b
|
||||
|
||||
|
||||
# enable protected mode
|
||||
mov %cr0, %eax
|
||||
or $1, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
|
||||
call kernel_main
|
||||
.size _start, . - _start
|
||||
|
||||
|
||||
cli
|
||||
1: hlt
|
||||
jmp 1b
|
||||
|
||||
|
||||
.size _start, . - _start
|
@ -10,66 +10,81 @@ void CheckMBT ( multiboot_info_t* mbt ){
|
||||
/* Set MBI to the addresss of the multiboot information structure*/
|
||||
multiboot_info_t * mbi = (multiboot_info_t *) mbt;
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
/* Print out the flags */
|
||||
printf("flags = 0x%x\n", (unsigned) mbi->flags);
|
||||
|
||||
#endif
|
||||
/* Are mem_* valid? */
|
||||
if ( CHECK_FLAG(mbi->flags,0)){
|
||||
printf("mem_lower = %uKB, mem_upper = %uKB\n");
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/* is boot device valid ? */
|
||||
if (CHECK_FLAG (mbi->flags, 1)){
|
||||
if (CHECK_FLAG (mbi->flags, 1))
|
||||
{
|
||||
#ifdef __VERBOSE__
|
||||
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* is the command line passed? */
|
||||
if (CHECK_FLAG ( mbi->flags,2)){
|
||||
if (CHECK_FLAG ( mbi->flags,2))
|
||||
{
|
||||
#ifdef __VERBOSE__
|
||||
printf("cmdline = %s\n", (char *) mbi->cmdline);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Are mods_* valid? */
|
||||
if(CHECK_FLAG ( mbi->flags, 3)){
|
||||
multiboot_module_t *mod;
|
||||
uint32_t i;
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
|
||||
|
||||
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
|
||||
printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Bits 4 and 5 are mutually exclusive! */
|
||||
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){
|
||||
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5))
|
||||
{
|
||||
#ifdef __VERBOSE__
|
||||
printf("Both bits 4 and 5 are set.\n");
|
||||
#endif
|
||||
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);
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n",
|
||||
(unsigned) multiboot_aout_sym->tabsize,
|
||||
(unsigned) multiboot_aout_sym->strsize,
|
||||
(unsigned) multiboot_aout_sym->addr);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Is the section header table of ELF valid? */
|
||||
if (CHECK_FLAG(mbi->flags, 5)){
|
||||
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
|
||||
|
||||
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
|
||||
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Draw diagonal blue line */
|
||||
if (CHECK_FLAG (mbt->flags, 12)){
|
||||
printf("Can draw!");
|
||||
#ifdef __VERBOSE__
|
||||
printf("Can draw!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
9
src/kernel/bootinfo.h
Normal file
9
src/kernel/bootinfo.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "memory/memoryinfo.h"
|
||||
|
||||
|
||||
struct BootInfo{
|
||||
const char* BootStructureID = "BarinkOS";
|
||||
MemoryInfo* memory;
|
||||
|
||||
};
|
11
src/kernel/definitions.h
Normal file
11
src/kernel/definitions.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
/**
|
||||
* Kernel definitions
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define __DEBUG__ false
|
||||
#define KERNEL_VERSION 0
|
||||
|
||||
#define ARCHITECTURE "I386"
|
@ -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
|
@ -23,7 +23,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 ){
|
||||
|
38
src/kernel/drivers/cmos/cmos.cpp
Normal file
38
src/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
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
@ -52,6 +55,4 @@ void initGDT(){
|
||||
|
||||
LoadGlobalDescriptorTable();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "idt.h"
|
||||
//#include "scancodes/set1.h"
|
||||
#include "../pit.h"
|
||||
#include "../keyboard/keyboard.h"
|
||||
|
||||
IDT_entry idt_table[256];
|
||||
IDT_ptr idt_ptr;
|
||||
@ -13,78 +14,249 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
|
||||
|
||||
};
|
||||
|
||||
|
||||
void irs_handler (registers regs) {
|
||||
kterm_writestring("received interrupt!\n");
|
||||
|
||||
printf("(IRS) Interrupt number: %d \n", regs.int_no);
|
||||
|
||||
if( regs.int_no == 13){
|
||||
printf(" Error code: %d \n", regs.err_code);
|
||||
|
||||
}
|
||||
//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("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
// Page Fault Exception #PF
|
||||
printf("#PF\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// x87 FPU Floating-point Error #MF
|
||||
printf("#MF\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 17:
|
||||
// Alignment Check Exception #AC
|
||||
printf("#AC\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
// Machine-Check Exception #MC
|
||||
printf("#MC\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 19:
|
||||
// SIMD Floating-point Exception #XM
|
||||
printf("#XM\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// Virtualization Exception #VE
|
||||
printf("#VE\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
// Control Protection Exception #CP
|
||||
printf("#CP\n");
|
||||
printf("EIP: 0x%x\n", regs.eip);
|
||||
printf("EAX: 0x%x\n", regs.eax);
|
||||
printf("EBP: 0x%x\n", regs.ebp);
|
||||
break;
|
||||
|
||||
default:
|
||||
// PANIC!!!
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void irq_handler (registers regs) {
|
||||
|
||||
|
||||
if ( regs.int_no != 0) {
|
||||
kterm_writestring("received interrupt!\n");
|
||||
printf("(IRQ) Interrupt number: %d \n", regs.int_no);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
outb(0x20, 0x20); // send end of interrupt to master
|
||||
break;
|
||||
case 12:
|
||||
// PS2 Mouse interrupt
|
||||
printf("Mouse event triggered!");
|
||||
//int event = inb(0x60);
|
||||
break;
|
||||
|
||||
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);
|
||||
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
|
||||
|
||||
@ -125,10 +297,15 @@ void init_idt(){
|
||||
//print_serial("Remapping PIC\n");
|
||||
PIC_remap(0x20, 0x28);
|
||||
|
||||
// clear mask for IRQ 12
|
||||
uint8_t value = inb(0x21) & ~(1<< 12);
|
||||
outb(0x21, value);
|
||||
|
||||
|
||||
|
||||
// pic IRQ Table
|
||||
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
|
||||
set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E);
|
||||
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);
|
||||
@ -139,7 +316,7 @@ void init_idt(){
|
||||
set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E);
|
||||
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
||||
set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E);
|
||||
set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E);
|
||||
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);
|
||||
|
@ -167,11 +167,6 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wait_until_shutdown();
|
||||
|
||||
}
|
||||
@ -179,35 +174,118 @@
|
||||
|
||||
|
||||
|
||||
extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||
/** initialize terminal interface */
|
||||
kterm_init();
|
||||
|
||||
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||
printf("Invalid magic number: 0x%x\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 early_main(unsigned long magic, unsigned long addr){
|
||||
/**
|
||||
* Initialize terminal interface
|
||||
* NOTE: This should be done later on , the magic value should be checked first.
|
||||
*/
|
||||
kterm_init();
|
||||
|
||||
/**
|
||||
* Check Multiboot magic number
|
||||
* NOTE: Printf call should not be a thing this early on ...
|
||||
*/
|
||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||
printf("Invalid magic number: 0x%x\n", magic);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the address given as an argument as the pointer
|
||||
* to a Multiboot information structure.
|
||||
*/
|
||||
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
||||
|
||||
/**
|
||||
* Construct our own bootInfo structure
|
||||
*/
|
||||
BootInfo bootinfo = {};
|
||||
|
||||
|
||||
/*
|
||||
If we got a memory map from our bootloader we
|
||||
should be parsing it to find out the memory regions available.
|
||||
*/
|
||||
if (CHECK_FLAG(mbt->flags, 6))
|
||||
{
|
||||
|
||||
/*
|
||||
Setup Physical memory managment
|
||||
*/
|
||||
MemoryInfo meminfo = {};
|
||||
bootinfo.memory = &meminfo;
|
||||
|
||||
mapMultibootMemoryMap(bootinfo.memory , mbt);
|
||||
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
|
||||
|
||||
PhysicalMemory memAlloc = PhysicalMemory{};
|
||||
memAlloc.setup(bootinfo.memory );
|
||||
|
||||
/*
|
||||
Mark already in use sections
|
||||
*/
|
||||
|
||||
// Mark kernel memory as used
|
||||
printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", kernel_begin , kernel_end );
|
||||
|
||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
||||
|
||||
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||
|
||||
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
|
||||
|
||||
} else{
|
||||
printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len );
|
||||
memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
printf("allocate region: 0x%x, size : 0x%x bytes\n", kernel_begin, kernel_end - kernel_begin );
|
||||
memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin);
|
||||
|
||||
// test alloc_block
|
||||
|
||||
|
||||
uint8_t* memory = (uint8_t*) memAlloc.allocate_block();
|
||||
printf("Got a new pointer: 0x%x\n", memory);
|
||||
|
||||
uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block();
|
||||
printf("Got a new pointer: 0x%x\n", memory2);
|
||||
|
||||
|
||||
memAlloc.free_block((void*) memory);
|
||||
|
||||
uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block();
|
||||
|
||||
|
||||
|
||||
|
||||
// memAlloc.free_block((void*) memory);
|
||||
|
||||
|
||||
}
|
||||
|
||||
initGDT();
|
||||
init_idt();
|
||||
// Enable interrupts
|
||||
asm volatile("STI");
|
||||
|
||||
|
||||
init_serial();
|
||||
pit_initialise();
|
||||
|
||||
|
||||
CheckMBT( (multiboot_info_t *) addr);
|
||||
|
||||
startSuperVisorTerminal(&bootinfo);
|
||||
|
||||
kernel_main();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
extern "C"{
|
||||
extern "C"
|
||||
{
|
||||
#include "../libc/include/string.h"
|
||||
}
|
||||
|
||||
@ -8,14 +9,19 @@ extern "C"{
|
||||
#include "tty/kterm.h"
|
||||
|
||||
#include "./bootloader/multiboot.h"
|
||||
#include "bootinfo.h"
|
||||
|
||||
#include "memory/memory.h"
|
||||
#include "memory/memoryinfo.h"
|
||||
#include "bootcheck.h"
|
||||
#include "memory/PhysicalMemoryManager.h"
|
||||
|
||||
#include "gdt/gdtc.h"
|
||||
#include "idt/idt.h"
|
||||
|
||||
#include "drivers/IO/io.h"
|
||||
#include "time.h"
|
||||
#include "pit.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "serial.h"
|
||||
#include "drivers/IO/PCI/pci.h"
|
||||
@ -28,17 +34,10 @@ extern "C"{
|
||||
#include "drivers/ACPI/rsdp.h"
|
||||
|
||||
|
||||
#include "time.h"
|
||||
#include "sv-terminal/superVisorTerminal.h"
|
||||
|
||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
|
||||
#define PANIC(message) { return; }
|
||||
#define PANIC(message) {return;}
|
||||
|
||||
|
||||
/* This needs to be moved! */
|
||||
/**
|
||||
* simple delay function
|
||||
**/
|
||||
void delay(int t){
|
||||
volatile int i,j;
|
||||
for(i=0;i<t;i++)
|
||||
for(j=0;j<25000;j++)
|
||||
asm("NOP");
|
||||
}
|
||||
|
51
src/kernel/keyboard/keyboard.cpp
Normal file
51
src/kernel/keyboard/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
src/kernel/keyboard/keyboard.h
Normal file
34
src/kernel/keyboard/keyboard.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "../tty/kterm.h"
|
||||
typedef enum ScanCodeSet{
|
||||
None = 0,
|
||||
ScanCodeSet1 = 1,
|
||||
ScanCodeSet2 = 2,
|
||||
ScanCodeSet3 = 3,
|
||||
};
|
||||
|
||||
typedef enum Modifiers{
|
||||
LSHIFT = 1,
|
||||
RSHIFT = 2,
|
||||
|
||||
LCTRL = 3,
|
||||
RCTRL = 4,
|
||||
|
||||
LALT = 5,
|
||||
RALT = 6
|
||||
};
|
||||
|
||||
struct KeyPressInfo{
|
||||
uint8_t PressedModifiers;
|
||||
uint8_t ScanCode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern KeyPressInfo keyPress;
|
||||
|
||||
void KeyHandled();
|
||||
|
||||
char getASCIIKey();
|
||||
uint8_t getKey();
|
@ -13,26 +13,26 @@ 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)
|
||||
inline uint32_t bitmap_first_unset( uint32_t* map , int map_size)
|
||||
{
|
||||
uint32_t rem_bits = size % 32;
|
||||
for(uint32_t i = 0; i < size/32; i++)
|
||||
for ( int i = 0 ; i < map_size ; i ++ )
|
||||
{
|
||||
if(map[i] != 0xFFFFFFFF){
|
||||
for(int j = 0; j < 32; j++){
|
||||
if(!(map[i] & (1<< j))){
|
||||
return (i*32) + j;
|
||||
// a bit or more is set within this byte!
|
||||
if( (map[i] & 0xFFFFFFFF) > 0 ){
|
||||
|
||||
// which bit is set?
|
||||
for(int j = 0 ; j < 32 ; j++){
|
||||
if ( (map[i] & (0x00000001 << j)) > 0)
|
||||
{
|
||||
printf("Found bit: byte 0x%x , bit 0x%x\n", i , j);
|
||||
return (i*32)+j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(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 +1,43 @@
|
||||
#include "PageDirectory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void PageDirectory::enable()
|
||||
{
|
||||
|
||||
|
||||
|
||||
void PageDirectory::enable(){
|
||||
// https://wiki.osdev.org/Setting_Up_Paging
|
||||
//set each entry to not present
|
||||
int i;
|
||||
for(i = 0; i < 1024; i++)
|
||||
{
|
||||
// This sets the following flags to the pages:
|
||||
// Supervisor: Only kernel-mode can access them
|
||||
// Write Enabled: It can be both read from and written to
|
||||
// Not Present: The page table is not present
|
||||
this->page_directory[i] = 0x00000002;
|
||||
}
|
||||
// int i;
|
||||
// for(i = 0; i < 1024; i++)
|
||||
// {
|
||||
// // This sets the following flags to the pages:
|
||||
// // Supervisor: Only kernel-mode can access them
|
||||
// // Write Enabled: It can be both read from and written to
|
||||
// // Not Present: The page table is not present
|
||||
// this->page_directory[i] = 0x00000002;
|
||||
// }
|
||||
|
||||
// holds the physical address where we want to start mapping these pages to.
|
||||
// in this case, we want to map these pages to the very beginning of memory.
|
||||
// // holds the physical address where we want to start mapping these pages to.
|
||||
// // in this case, we want to map these pages to the very beginning of memory.
|
||||
|
||||
//we will fill all 1024 entries in the table, mapping 4 megabytes
|
||||
for(unsigned int i = 0; i < 1024; i++)
|
||||
{
|
||||
// As the address is page aligned, it will always leave 12 bits zeroed.
|
||||
// Those bits are used by the attributes ;)
|
||||
first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
|
||||
}
|
||||
// //we will fill all 1024 entries in the table, mapping 4 megabytes
|
||||
// for(unsigned int i = 0; i < 1024; i++)
|
||||
// {
|
||||
// // As the address is page aligned, it will always leave 12 bits zeroed.
|
||||
// // Those bits are used by the attributes ;)
|
||||
// first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
|
||||
// }
|
||||
|
||||
// attributes: supervisor level, read/write, present
|
||||
this->page_directory[0] = ((unsigned int)first_page_table) | 3;
|
||||
// // attributes: supervisor level, read/write, present
|
||||
// this->page_directory[0] = ((unsigned int)first_page_table) | 3;
|
||||
|
||||
printf("Enable Paging!\n");
|
||||
|
||||
loadPageDirectory(this->page_directory);
|
||||
enablePaging();
|
||||
}
|
||||
|
||||
/*
|
||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
|
||||
|
||||
void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t 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,17 +1,18 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||
extern "C" void enablePaging();
|
||||
typedef uintptr_t address_t;
|
||||
|
||||
|
||||
#include "./memory.h"
|
||||
#include "./../tty/kterm.h"
|
||||
#define KB 1024
|
||||
|
||||
|
||||
typedef uintptr_t address_t;
|
||||
|
||||
static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page
|
||||
static volatile address_t pmem_stack[MAX_PAGES];
|
||||
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
|
||||
|
||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||
extern "C" void enablePaging();
|
||||
|
||||
struct page_directory_entry {};
|
||||
struct page_table_entry{};
|
||||
@ -21,8 +22,10 @@ struct page_table_entry{};
|
||||
class PageDirectory {
|
||||
public:
|
||||
void enable ();
|
||||
|
||||
void MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size );
|
||||
|
||||
private:
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages
|
||||
|
||||
};
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
142
src/kernel/memory/memory.cpp
Normal file
142
src/kernel/memory/memory.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "./memory.h"
|
||||
uint32_t* memoryBitMap;
|
||||
/*
|
||||
|
||||
*/
|
||||
void PhysicalMemory::setup( MemoryInfo* memory) {
|
||||
|
||||
// calculate the maximum number of blocks
|
||||
max_blocks = KB_TO_BLOCKS(memory->TotalMemory);
|
||||
|
||||
used_blocks = 0;
|
||||
|
||||
memoryBitMap = (uint32_t*) 0x00a00000;
|
||||
|
||||
|
||||
printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8));
|
||||
|
||||
//Size of memory map
|
||||
uint32_t memMap_size = (max_blocks / 8 ) ;
|
||||
|
||||
printf("Memory Map size: 0x%x\n", memMap_size );
|
||||
printf("size of int in bytes: 0x%x \n" , sizeof(int));
|
||||
|
||||
// Set all places in memory as free
|
||||
memset(memoryBitMap, 0xFF, memMap_size );
|
||||
}
|
||||
|
||||
// NOTE: this can only give blocks of 4kb at a time!
|
||||
void* PhysicalMemory::allocate_block() {
|
||||
uint8_t blocks_available = max_blocks - used_blocks;
|
||||
// Are there any blocks available?
|
||||
if( blocks_available <= 0)
|
||||
{
|
||||
printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find 1 free block somewhere
|
||||
int free_block_index = bitmap_first_unset(memoryBitMap, (max_blocks /8) /*memMap Size*/ );
|
||||
|
||||
|
||||
|
||||
if(free_block_index == -1)
|
||||
{
|
||||
printf("Could not find a good block!\n");
|
||||
// Could not find a block
|
||||
return (void*)0xFFFF;
|
||||
}
|
||||
|
||||
if(free_block_index == 0)
|
||||
printf("Somethings wrong!!!\n");
|
||||
|
||||
// Set the block to be used!
|
||||
bitmap_unset(memoryBitMap, free_block_index);
|
||||
// Increase the used_block count!
|
||||
used_blocks++;
|
||||
printf("used blocks: 0x%x\n", used_blocks);
|
||||
// return the pointer to the physical address
|
||||
return (void*) (BLOCK_SIZE * free_block_index);
|
||||
}
|
||||
|
||||
|
||||
void PhysicalMemory::free_block(void* p) {
|
||||
// If it is a null pointer we don't need to do anything.
|
||||
if(p==0) {
|
||||
return;
|
||||
}
|
||||
// calculate the index into the bitmap
|
||||
int index = ((uint32_t) p) / BLOCK_SIZE;
|
||||
|
||||
// set the block to be free
|
||||
bitmap_set(memoryBitMap, index);
|
||||
used_blocks--;
|
||||
printf("used blocks: 0x%x, after free\n", used_blocks);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhysicalMemory::allocate_region(uint32_t startAddress, uint32_t size) {
|
||||
// every bit should be 4KiB
|
||||
// every byte is 8*4KiB = 32KiB
|
||||
|
||||
int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1;
|
||||
int startBlock = (startAddress / 1024) / 4 / 8 ;
|
||||
|
||||
// printf("NumberOfBlocksToAllocate: 0x%x\n", NumberOfBlocksToAllocate);
|
||||
//printf( "start block: 0x%x\n" , startBlock);
|
||||
for( int i = 0; i < NumberOfBlocksToAllocate; i++)
|
||||
{
|
||||
|
||||
//printf("ALLOCATE BLOCK: 0x%x\n" , startBlock + i );
|
||||
bitmap_unset(memoryBitMap, startBlock+ i);
|
||||
used_blocks++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void PhysicalMemory::deallocate_region(uint32_t StartAddress , uint32_t size ) {
|
||||
// NOT IMPLEMENTED YET
|
||||
}
|
||||
|
||||
|
||||
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
|
||||
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
|
||||
(unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
|
||||
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
|
||||
|
||||
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
|
||||
|
||||
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
|
||||
|
||||
memInfo->TotalMemory += mmap->len;
|
||||
} else {
|
||||
memInfo->ReservedMemory += mmap->len;
|
||||
}
|
||||
|
||||
print_Multiboot_memory_Map(mmap);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Debug Verbose functions
|
||||
*
|
||||
* @param mmap
|
||||
*/
|
||||
|
||||
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
|
||||
printf(
|
||||
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
|
||||
(unsigned) mmap->size,
|
||||
(unsigned) (mmap->addr >> 32),
|
||||
(unsigned) (mmap->addr & 0xffffffff),
|
||||
(unsigned) (mmap->len >> 32),
|
||||
(unsigned) (mmap->len & 0xffffffff),
|
||||
(unsigned) mmap->type
|
||||
);
|
||||
}
|
||||
|
48
src/kernel/memory/memory.h
Normal file
48
src/kernel/memory/memory.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memoryinfo.h"
|
||||
#include "../bootloader/multiboot.h"
|
||||
#include "../tty/kterm.h"
|
||||
#include "../../libc/include/mem.h"
|
||||
#include "../kstructures/bitmap.h"
|
||||
|
||||
#define BLOCK_SIZE 4092
|
||||
#define BLOCKS_PER_WORD 32 // A word is 16 bit in x86 machines according to my google search results!
|
||||
|
||||
#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE)
|
||||
#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1))
|
||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||
|
||||
extern uint32_t kernel_begin;
|
||||
extern uint32_t kernel_end;
|
||||
|
||||
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks);
|
||||
|
||||
extern uint32_t* memoryBitMap;
|
||||
|
||||
class PhysicalMemory
|
||||
{
|
||||
public:
|
||||
void setup(MemoryInfo* memory);
|
||||
void destroy();
|
||||
void free_block(void* ptr);
|
||||
void* allocate_block();
|
||||
void allocate_region(uint32_t, uint32_t);
|
||||
void deallocate_region(uint32_t , uint32_t );
|
||||
|
||||
private:
|
||||
size_t pmmap_size;
|
||||
size_t max_blocks;
|
||||
int used_blocks;
|
||||
};
|
||||
|
||||
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt);
|
||||
|
||||
/**
|
||||
* @brief Debug Verbose Functions
|
||||
*
|
||||
* @param mmap
|
||||
*/
|
||||
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap);
|
20
src/kernel/memory/memoryinfo.h
Normal file
20
src/kernel/memory/memoryinfo.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct MemoryArea{
|
||||
void* StartAddress;
|
||||
size_t Size;
|
||||
unsigned int type;
|
||||
MemoryArea* Next;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
struct MemoryInfo {
|
||||
uint32_t TotalMemory;
|
||||
uint32_t ReservedMemory;
|
||||
MemoryArea* MemoryRegionList;
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
|
54
src/kernel/pit.cpp
Normal file
54
src/kernel/pit.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "pit.h"
|
||||
#include "tty/kterm.h"
|
||||
uint32_t pit_tick = 0;
|
||||
|
||||
|
||||
void pit_initialise()
|
||||
{
|
||||
asm volatile("CLI");
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init PIT!\n");
|
||||
#endif
|
||||
// clear mask for IRQ 0
|
||||
uint8_t value = inb(0x21) & ~(1<< 0);
|
||||
outb(0x21, value);
|
||||
|
||||
io_wait();
|
||||
|
||||
const int freq = 500;
|
||||
|
||||
uint32_t divisor = 1193180 / freq;
|
||||
|
||||
outb(PIT_COMMAND, 0x36);
|
||||
|
||||
uint8_t l = (uint8_t) (divisor & 0xFF);
|
||||
uint8_t h = (uint8_t) ( (divisor>>8) & 0xff);
|
||||
|
||||
outb(PIT_DATA_0, l);
|
||||
outb(PIT_DATA_0,h);
|
||||
|
||||
|
||||
asm volatile("STI");
|
||||
}
|
||||
|
||||
|
||||
void get_pit_count()
|
||||
{
|
||||
asm volatile ("CLI");
|
||||
|
||||
outb(PIT_COMMAND, 0);
|
||||
uint16_t count = inb(PIT_DATA_0);
|
||||
count |= inb(PIT_DATA_0) << 8;
|
||||
|
||||
printf("PIT count: 0x%x\n", count);
|
||||
|
||||
asm volatile("STI");
|
||||
|
||||
}
|
||||
|
||||
void set_pit_count()
|
||||
{
|
||||
|
||||
}
|
||||
|
18
src/kernel/pit.h
Normal file
18
src/kernel/pit.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "drivers/IO/io.h"
|
||||
#define PIT_DATA_0 0x40
|
||||
#define PIT_DATA_1 0x41
|
||||
#define PIT_DATA_2 0x42
|
||||
#define PIT_COMMAND 0x43
|
||||
|
||||
|
||||
extern uint32_t pit_tick;
|
||||
|
||||
|
||||
void pit_initialise();
|
||||
|
||||
|
||||
void get_pit_count();
|
||||
|
||||
void set_pit_count();
|
@ -3,7 +3,12 @@
|
||||
#include "tty/kterm.h"
|
||||
#include "drivers/IO/io.h"
|
||||
#define PORT 0x3f8
|
||||
inline static int init_serial() {
|
||||
static int init_serial() {
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
printf("Init Serial\n");
|
||||
#endif
|
||||
|
||||
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
|
||||
|
89
src/kernel/sv-terminal/superVisorTerminal.cpp
Normal file
89
src/kernel/sv-terminal/superVisorTerminal.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "superVisorTerminal.h"
|
||||
|
||||
void startSuperVisorTerminal(BootInfo* bootinfo)
|
||||
{
|
||||
bool isRunning = true;
|
||||
while (isRunning){
|
||||
|
||||
printf("SUPERVISOR:>$ " );
|
||||
int characterCount = 0;
|
||||
char command[10] = "";
|
||||
|
||||
// NOTE: lets just show a kernel prompt
|
||||
uint8_t ScanCode = getKey();
|
||||
while( ScanCode != 0x1C )
|
||||
{
|
||||
char character = getASCIIKey();
|
||||
kterm_put(character );
|
||||
// wHAT THE HELL
|
||||
|
||||
if( characterCount < 10 ){
|
||||
command[characterCount] = character;
|
||||
characterCount++;
|
||||
}
|
||||
|
||||
ScanCode = getKey();
|
||||
}
|
||||
printf("\n");
|
||||
KeyHandled();
|
||||
|
||||
|
||||
if ( strncmp("DATE", command , characterCount ) == 0 )
|
||||
{
|
||||
read_rtc();
|
||||
printf("======= Time & Date ==========\n");
|
||||
printf(" - Date: %02d-%02d-%02d\n",day, month, year);
|
||||
printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second);
|
||||
printf(" - Ticks: %09d\n", pit_tick);
|
||||
}
|
||||
else if( strncmp ("MEMORY" , command , characterCount) == 0 )
|
||||
{
|
||||
// Show memory layout
|
||||
printf("========= Memory ==========\n");
|
||||
printf("Kernel MemoryMap:\n");
|
||||
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
||||
printf("Frames used: 0x%x blocks of 4 KiB\n", 0);
|
||||
const int bytesInGiB = 1073741824;
|
||||
int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB;
|
||||
int64_t effectiveNumberOfGib = bootinfo->memory->TotalMemory / bytesInGiB;
|
||||
|
||||
int64_t GiBs = effectiveNumberOfGib + bytesLeft;
|
||||
|
||||
printf("Available Memory: %d bytes, %d GiB\n", bootinfo->memory->TotalMemory, GiBs );
|
||||
printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory);
|
||||
|
||||
//printf("\n\n");
|
||||
//PrintPhysicalMemoryAllocation( );
|
||||
|
||||
|
||||
}
|
||||
else if(strncmp("TEST", command, characterCount) == 0)
|
||||
{
|
||||
// TEST #DE exception
|
||||
asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0
|
||||
}
|
||||
else if (strncmp("VERSION", command , characterCount) == 0)
|
||||
{
|
||||
// Show version information
|
||||
printf("========= Version ========\n");
|
||||
printf("Kernel v%d\n", 0);
|
||||
|
||||
}
|
||||
else if(strncmp("CLEAR", command, characterCount) == 0)
|
||||
{
|
||||
kterm_init();
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
}
|
||||
else if(strncmp("FAT", command, characterCount) == 0){
|
||||
isRunning = false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
}
|
9
src/kernel/sv-terminal/superVisorTerminal.h
Normal file
9
src/kernel/sv-terminal/superVisorTerminal.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "../tty/kterm.h"
|
||||
#include "../time.h"
|
||||
#include "../pit.h"
|
||||
#include "../keyboard/keyboard.h"
|
||||
#include "../memory/memory.h"
|
||||
#include "../bootinfo.h"
|
||||
|
||||
void startSuperVisorTerminal(BootInfo * );
|
111
src/kernel/time.cpp
Normal file
111
src/kernel/time.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "time.h"
|
||||
|
||||
// Set by ACPI table parsing code if possible
|
||||
int century_register = 0x00;
|
||||
unsigned char second;
|
||||
unsigned char minute;
|
||||
unsigned char hour;
|
||||
unsigned char day;
|
||||
unsigned char month;
|
||||
unsigned int year;
|
||||
|
||||
|
||||
int get_update_in_progress_flag() {
|
||||
outb(cmos_address, 0x0A);
|
||||
return (inb(cmos_data) & 0x80);
|
||||
}
|
||||
|
||||
unsigned char get_RTC_register(int reg) {
|
||||
outb(cmos_address, reg);
|
||||
return inb(cmos_data);
|
||||
}
|
||||
|
||||
void read_rtc() {
|
||||
unsigned char century;
|
||||
unsigned char last_second;
|
||||
unsigned char last_minute;
|
||||
unsigned char last_hour;
|
||||
unsigned char last_day;
|
||||
unsigned char last_month;
|
||||
unsigned char last_year;
|
||||
unsigned char last_century;
|
||||
unsigned char registerB;
|
||||
|
||||
// Note: This uses the "read registers until you get the same values twice in a row" technique
|
||||
// to avoid getting dodgy/inconsistent values due to RTC updates
|
||||
|
||||
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
|
||||
second = get_RTC_register(0x00);
|
||||
minute = get_RTC_register(0x02);
|
||||
hour = get_RTC_register(0x04);
|
||||
day = get_RTC_register(0x07);
|
||||
month = get_RTC_register(0x08);
|
||||
year = get_RTC_register(0x09);
|
||||
if(century_register != 0) {
|
||||
century = get_RTC_register(century_register);
|
||||
} else {
|
||||
century = 21;
|
||||
}
|
||||
|
||||
do {
|
||||
last_second = second;
|
||||
last_minute = minute;
|
||||
last_hour = hour;
|
||||
last_day = day;
|
||||
last_month = month;
|
||||
last_year = year;
|
||||
last_century = century;
|
||||
|
||||
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
|
||||
second = get_RTC_register(0x00);
|
||||
minute = get_RTC_register(0x02);
|
||||
hour = get_RTC_register(0x04);
|
||||
day = get_RTC_register(0x07);
|
||||
month = get_RTC_register(0x08);
|
||||
year = get_RTC_register(0x09);
|
||||
if(century_register != 0) {
|
||||
century = get_RTC_register(century_register);
|
||||
}
|
||||
} while( (last_second != second) || (last_minute != minute) || (last_hour != hour) ||
|
||||
(last_day != day) || (last_month != month) || (last_year != year) ||
|
||||
(last_century != century) );
|
||||
|
||||
registerB = get_RTC_register(0x0B);
|
||||
|
||||
// Convert BCD to binary values if necessary
|
||||
|
||||
if (!(registerB & 0x04)) {
|
||||
second = (second & 0x0F) + ((second / 16) * 10);
|
||||
minute = (minute & 0x0F) + ((minute / 16) * 10);
|
||||
hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
|
||||
day = (day & 0x0F) + ((day / 16) * 10);
|
||||
month = (month & 0x0F) + ((month / 16) * 10);
|
||||
year = (year & 0x0F) + ((year / 16) * 10);
|
||||
if(century_register != 0) {
|
||||
century = (century & 0x0F) + ((century / 16) * 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 12 hour clock to 24 hour clock if necessary
|
||||
|
||||
if (!(registerB & 0x02) && (hour & 0x80)) {
|
||||
hour = ((hour & 0x7F) + 12) % 24;
|
||||
}
|
||||
|
||||
// Calculate the full (4-digit) year
|
||||
|
||||
if(century_register != 0) {
|
||||
year += century * 100;
|
||||
} else {
|
||||
year += (CURRENT_YEAR / 100) * 100;
|
||||
if(year < CURRENT_YEAR) year += 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void delay(int t){
|
||||
volatile int i,j;
|
||||
for(i=0;i<t;i++)
|
||||
for(j=0;j<25000;j++)
|
||||
asm("NOP");
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
#define CURRENT_YEAR 2021 // Change this each year!
|
||||
|
||||
int century_register = 0x00; // Set by ACPI table parsing code if possible
|
||||
|
||||
unsigned char second;
|
||||
unsigned char minute;
|
||||
unsigned char hour;
|
||||
unsigned char day;
|
||||
unsigned char month;
|
||||
unsigned int year;
|
||||
#pragma once
|
||||
#include "drivers/IO/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 {
|
||||
@ -16,138 +17,7 @@ enum {
|
||||
cmos_data = 0x71
|
||||
};
|
||||
|
||||
int get_update_in_progress_flag() {
|
||||
outb(cmos_address, 0x0A);
|
||||
return (inb(cmos_data) & 0x80);
|
||||
}
|
||||
|
||||
unsigned char get_RTC_register(int reg) {
|
||||
outb(cmos_address, reg);
|
||||
return inb(cmos_data);
|
||||
}
|
||||
|
||||
void read_rtc() {
|
||||
unsigned char century;
|
||||
unsigned char last_second;
|
||||
unsigned char last_minute;
|
||||
unsigned char last_hour;
|
||||
unsigned char last_day;
|
||||
unsigned char last_month;
|
||||
unsigned char last_year;
|
||||
unsigned char last_century;
|
||||
unsigned char registerB;
|
||||
|
||||
// Note: This uses the "read registers until you get the same values twice in a row" technique
|
||||
// to avoid getting dodgy/inconsistent values due to RTC updates
|
||||
|
||||
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
|
||||
second = get_RTC_register(0x00);
|
||||
minute = get_RTC_register(0x02);
|
||||
hour = get_RTC_register(0x04);
|
||||
day = get_RTC_register(0x07);
|
||||
month = get_RTC_register(0x08);
|
||||
year = get_RTC_register(0x09);
|
||||
if(century_register != 0) {
|
||||
century = get_RTC_register(century_register);
|
||||
} else {
|
||||
century = 21;
|
||||
}
|
||||
|
||||
do {
|
||||
last_second = second;
|
||||
last_minute = minute;
|
||||
last_hour = hour;
|
||||
last_day = day;
|
||||
last_month = month;
|
||||
last_year = year;
|
||||
last_century = century;
|
||||
|
||||
while (get_update_in_progress_flag()); // Make sure an update isn't in progress
|
||||
second = get_RTC_register(0x00);
|
||||
minute = get_RTC_register(0x02);
|
||||
hour = get_RTC_register(0x04);
|
||||
day = get_RTC_register(0x07);
|
||||
month = get_RTC_register(0x08);
|
||||
year = get_RTC_register(0x09);
|
||||
if(century_register != 0) {
|
||||
century = get_RTC_register(century_register);
|
||||
}
|
||||
} while( (last_second != second) || (last_minute != minute) || (last_hour != hour) ||
|
||||
(last_day != day) || (last_month != month) || (last_year != year) ||
|
||||
(last_century != century) );
|
||||
|
||||
registerB = get_RTC_register(0x0B);
|
||||
|
||||
// Convert BCD to binary values if necessary
|
||||
|
||||
if (!(registerB & 0x04)) {
|
||||
second = (second & 0x0F) + ((second / 16) * 10);
|
||||
minute = (minute & 0x0F) + ((minute / 16) * 10);
|
||||
hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
|
||||
day = (day & 0x0F) + ((day / 16) * 10);
|
||||
month = (month & 0x0F) + ((month / 16) * 10);
|
||||
year = (year & 0x0F) + ((year / 16) * 10);
|
||||
if(century_register != 0) {
|
||||
century = (century & 0x0F) + ((century / 16) * 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 12 hour clock to 24 hour clock if necessary
|
||||
|
||||
if (!(registerB & 0x02) && (hour & 0x80)) {
|
||||
hour = ((hour & 0x7F) + 12) % 24;
|
||||
}
|
||||
|
||||
// Calculate the full (4-digit) year
|
||||
|
||||
if(century_register != 0) {
|
||||
year += century * 100;
|
||||
} else {
|
||||
year += (CURRENT_YEAR / 100) * 100;
|
||||
if(year < CURRENT_YEAR) year += 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void ReadFromCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char tvalue, index;
|
||||
|
||||
for (index = 0; index < 128; index++)
|
||||
{
|
||||
asm(
|
||||
"cli\n\t" // Disable interrupts
|
||||
"mov al, index\n\t" // Move index address
|
||||
// since the 0x80 bit of al is not set, NMI is active
|
||||
"out 0x70,al\n\t" // Copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"in al,0x71\n\t" // Fetch 1 byte to al
|
||||
"sti\n\t" // Enable interrupts
|
||||
"mov tvalue,al\n\t");
|
||||
|
||||
array[index] = tvalue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
void WriteTOCMOS(unsigned char array[])
|
||||
{
|
||||
unsigned char index;
|
||||
|
||||
for(index = 0; index < 128; index++)
|
||||
{
|
||||
unsigned char tvalue = array[index];
|
||||
|
||||
asm("cli\n\t" // Clear interrupts
|
||||
"mov al,index\n\t" // move index address
|
||||
"out 0x70,al\n\t" // copy address to CMOS register
|
||||
// some kind of real delay here is probably best
|
||||
"mov al,tvalue\n\t" // move value to al
|
||||
"out 0x71,al\n\t" // write 1 byte to CMOS
|
||||
"sti\n\\t" ); // Enable interrupts
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
int get_update_in_progress_flag();
|
||||
unsigned char get_RTC_register();
|
||||
void read_rtc();
|
||||
void delay(int t);
|
@ -3,8 +3,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;
|
||||
}
|
||||
|
@ -8,4 +8,19 @@ size_t strlen(const char* str) {
|
||||
return len;
|
||||
}
|
||||
|
||||
int strncmp ( const char* str1, const char* str2, size_t num ){
|
||||
for( int i = 0; i < num ; i++){
|
||||
|
||||
if( str1[i] < str2[i]){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( str1[i] > str2[i] ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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 );
|
21
todo.md
21
todo.md
@ -0,0 +1,21 @@
|
||||
# TODO list
|
||||
|
||||
![Todo image](https://camo.githubusercontent.com/c43d969d9d071c8342e9a69cdd6acb433c541f431127738974ce22290c46f2b8/68747470733a2f2f692e696d6775722e636f6d2f4f764d5a4273392e6a7067)
|
||||
|
||||
|
||||
This list keeps me focused and organised so I don't forget what
|
||||
needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember
|
||||
to do on a more in depth level.
|
||||
|
||||
## --
|
||||
[ ] Setup paging \
|
||||
[ ] HELP command
|
||||
[ ] Setup a proper HEAP \
|
||||
[ ] Setup a proper Stack \
|
||||
[ ] Setup KMalloc and KFree \
|
||||
[ ] Merge Functioning Feature branches into sandboxKernelDev \
|
||||
[ ] Remove merged feature branches \
|
||||
[ ] Merge sandboxKernelDev with dev \
|
||||
[ ] Remove sandboxKernelDev branch \
|
||||
[ ] Implement proper virtual filesystem
|
||||
|
Loading…
Reference in New Issue
Block a user