Merge into main the new state of the operating system/kernel #1
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++ 
 | 
			
		||||
CFLAGS =  -ffreestanding -O2 -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
OFILES =  $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
 | 
			
		||||
OFILES =  $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
 | 
			
		||||
 | 
			
		||||
SRC_DIR = src
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
@ -86,3 +86,7 @@ $(BUILD_DIR)/PhysicalMemoryManager.o:
 | 
			
		||||
 | 
			
		||||
$(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
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
#include "../pit.h"
 | 
			
		||||
//#include "scancodes/set1.h"
 | 
			
		||||
#include "../keyboard/keyboard.h"
 | 
			
		||||
 | 
			
		||||
IDT_entry idt_table[256];
 | 
			
		||||
IDT_ptr idt_ptr;
 | 
			
		||||
@ -14,7 +14,6 @@ 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");
 | 
			
		||||
     
 | 
			
		||||
@ -36,44 +35,61 @@ void irs_handler (registers regs) {
 | 
			
		||||
 | 
			
		||||
void irq_handler (registers regs) {
 | 
			
		||||
 | 
			
		||||
        switch (regs.int_no)
 | 
			
		||||
        {
 | 
			
		||||
        case 0:
 | 
			
		||||
             pit_tick++;
 | 
			
		||||
            break;
 | 
			
		||||
        case 1:
 | 
			
		||||
            // Keyboard interrupt !!
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            int scan;
 | 
			
		||||
            /*register*/int i;
 | 
			
		||||
    switch (regs.int_no) {
 | 
			
		||||
    case 0:
 | 
			
		||||
            pit_tick++;
 | 
			
		||||
        break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        // Keyboard interrupt !!
 | 
			
		||||
 | 
			
		||||
            // Read scancode 
 | 
			
		||||
            scan = inb(0x60);
 | 
			
		||||
            
 | 
			
		||||
            // Send ack message!
 | 
			
		||||
            i = inb(0x61);
 | 
			
		||||
            outb(0x61, i|0x80);
 | 
			
		||||
            outb(0x61, i);
 | 
			
		||||
            printf( "Scancode: %x\n", scan);
 | 
			
		||||
            break;    
 | 
			
		||||
        int scan;
 | 
			
		||||
        int i;/*register*/
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            printf("Received INT: 0x%x\n", regs.int_no);
 | 
			
		||||
            break;
 | 
			
		||||
        }        
 | 
			
		||||
        // Read scancode 
 | 
			
		||||
        scan = inb(0x60);
 | 
			
		||||
        
 | 
			
		||||
        // Send ack message!
 | 
			
		||||
        i = inb(0x61);
 | 
			
		||||
        outb(0x61, i|0x80);
 | 
			
		||||
        outb(0x61, i);
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
        // NOTE: check for special scan codes 
 | 
			
		||||
        // e.g. modifiers etc..
 | 
			
		||||
        if( scan < 0x37){
 | 
			
		||||
            //printf("Read from IO: 0x%x\n", scan);
 | 
			
		||||
            keyPress.ScanCode = scan ;
 | 
			
		||||
            //printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        break;    
 | 
			
		||||
    case 12:
 | 
			
		||||
        // PS2 Mouse interrupt 
 | 
			
		||||
        printf("Mouse event triggered!");
 | 
			
		||||
        //int event = inb(0x60);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        printf("Interrupt happened!");
 | 
			
		||||
        printf("Received INT: 0x%x\n", regs.int_no);
 | 
			
		||||
        break;
 | 
			
		||||
    }        
 | 
			
		||||
 | 
			
		||||
    outb(0x20, 0x20); // send end of interrupt to master
 | 
			
		||||
 | 
			
		||||
    if ( regs.int_no > 8 && regs.int_no <= 15) {
 | 
			
		||||
        outb(0xA0, 0x20); // send end of interrupt to slave 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    if( regs.int_no == 13){
 | 
			
		||||
        printf(" Error code: %d \n", regs.err_code);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_idt(){
 | 
			
		||||
@ -122,10 +138,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);
 | 
			
		||||
@ -136,7 +157,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);
 | 
			
		||||
 | 
			
		||||
@ -7,13 +7,12 @@
 | 
			
		||||
        /** initialize terminal interface */ 
 | 
			
		||||
        kterm_init();
 | 
			
		||||
        
 | 
			
		||||
        // Check Multiboot magic number 
 | 
			
		||||
        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? */
 | 
			
		||||
@ -26,38 +25,67 @@
 | 
			
		||||
 | 
			
		||||
            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", used_blocks); 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        initGDT();
 | 
			
		||||
        init_idt();
 | 
			
		||||
        // Enable interrupts
 | 
			
		||||
        asm volatile("STI");
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        CheckMBT(  (multiboot_info_t *) addr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        kernel_main();
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern "C" void kernel_main (void) {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
        init_serial();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        pit_initialise();
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        while (true){
 | 
			
		||||
            //Read time indefinetely 
 | 
			
		||||
            read_rtc();
 | 
			
		||||
            printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)  [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second, pit_tick);
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
           
 | 
			
		||||
           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("TIME", command , characterCount ) == 0 ) {
 | 
			
		||||
                 read_rtc();
 | 
			
		||||
                 printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)\n" ,year, month, day, hour, minute, second, pit_tick);            
 | 
			
		||||
            } else if(strncmp("TEST", command, characterCount) == 0){
 | 
			
		||||
               // asm volatile ("MOV $4, %AX ;  MOV $0, %BX ; DIV %BX"); // IRS 0
 | 
			
		||||
            }
 | 
			
		||||
            else{
 | 
			
		||||
                printf("Unknown command\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
    }   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,8 @@ extern "C"{
 | 
			
		||||
#include "gdt/gdtc.h"
 | 
			
		||||
#include "idt/idt.h"
 | 
			
		||||
 | 
			
		||||
#include "keyboard/keyboard.h"
 | 
			
		||||
 | 
			
		||||
#include "pit.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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();
 | 
			
		||||
@ -6,4 +6,23 @@ size_t strlen(const char* str) {
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num ){
 | 
			
		||||
    for( int i = 0; i < num ; i++){
 | 
			
		||||
        
 | 
			
		||||
        if( str1[i] < str2[i]){
 | 
			
		||||
            return -1;
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        if( str1[i] > str2[i] ){
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
size_t strlen(const char* str);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int strncmp ( const char* str1, const char* str2, size_t num );
 | 
			
		||||
		Reference in New Issue
	
	Block a user