Merge into main the new state of the operating system/kernel #1
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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