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++
|
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||||
|
|
||||||
OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/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
|
SRC_DIR = src
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
@ -86,3 +86,7 @@ $(BUILD_DIR)/PhysicalMemoryManager.o:
|
|||||||
|
|
||||||
$(BUILD_DIR)/pit.o:
|
$(BUILD_DIR)/pit.o:
|
||||||
$(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
|
$(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 "idt.h"
|
||||||
#include "../pit.h"
|
#include "../pit.h"
|
||||||
//#include "scancodes/set1.h"
|
#include "../keyboard/keyboard.h"
|
||||||
|
|
||||||
IDT_entry idt_table[256];
|
IDT_entry idt_table[256];
|
||||||
IDT_ptr idt_ptr;
|
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) {
|
void irs_handler (registers regs) {
|
||||||
kterm_writestring("received interrupt!\n");
|
kterm_writestring("received interrupt!\n");
|
||||||
|
|
||||||
@ -36,44 +35,61 @@ void irs_handler (registers regs) {
|
|||||||
|
|
||||||
void irq_handler (registers regs) {
|
void irq_handler (registers regs) {
|
||||||
|
|
||||||
switch (regs.int_no)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
pit_tick++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Keyboard interrupt !!
|
|
||||||
|
|
||||||
int scan;
|
switch (regs.int_no) {
|
||||||
/*register*/int i;
|
case 0:
|
||||||
|
pit_tick++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// Keyboard interrupt !!
|
||||||
|
|
||||||
// Read scancode
|
int scan;
|
||||||
scan = inb(0x60);
|
int i;/*register*/
|
||||||
|
|
||||||
// Send ack message!
|
|
||||||
i = inb(0x61);
|
|
||||||
outb(0x61, i|0x80);
|
|
||||||
outb(0x61, i);
|
|
||||||
printf( "Scancode: %x\n", scan);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
// Read scancode
|
||||||
printf("Received INT: 0x%x\n", regs.int_no);
|
scan = inb(0x60);
|
||||||
break;
|
|
||||||
}
|
// Send ack message!
|
||||||
|
i = inb(0x61);
|
||||||
|
outb(0x61, i|0x80);
|
||||||
|
outb(0x61, i);
|
||||||
|
|
||||||
outb(0x20, 0x20); // send end of interrupt to master
|
// NOTE: check for special scan codes
|
||||||
|
// e.g. modifiers etc..
|
||||||
if ( regs.int_no > 8 && regs.int_no <= 15) {
|
if( scan < 0x37){
|
||||||
outb(0xA0, 0x20); // send end of interrupt to slave
|
//printf("Read from IO: 0x%x\n", scan);
|
||||||
}
|
keyPress.ScanCode = scan ;
|
||||||
|
//printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode);
|
||||||
|
|
||||||
if( regs.int_no == 13){
|
|
||||||
printf(" Error code: %d \n", regs.err_code);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(){
|
void init_idt(){
|
||||||
@ -122,10 +138,15 @@ void init_idt(){
|
|||||||
//print_serial("Remapping PIC\n");
|
//print_serial("Remapping PIC\n");
|
||||||
PIC_remap(0x20, 0x28);
|
PIC_remap(0x20, 0x28);
|
||||||
|
|
||||||
|
// clear mask for IRQ 12
|
||||||
|
uint8_t value = inb(0x21) & ~(1<< 12);
|
||||||
|
outb(0x21, value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// pic IRQ Table
|
// pic IRQ Table
|
||||||
set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E);
|
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(34, (uint32_t)irq2, 0x08, 0x8E);
|
||||||
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
|
set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E);
|
||||||
set_id_entry(36, (uint32_t)irq4, 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(41, (uint32_t)irq9, 0x08, 0x8E);
|
||||||
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E);
|
||||||
set_id_entry(43, (uint32_t)irq11, 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(45, (uint32_t)irq13, 0x08, 0x8E);
|
||||||
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
|
set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E);
|
||||||
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
|
set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E);
|
||||||
|
@ -7,13 +7,12 @@
|
|||||||
/** initialize terminal interface */
|
/** initialize terminal interface */
|
||||||
kterm_init();
|
kterm_init();
|
||||||
|
|
||||||
|
// Check Multiboot magic number
|
||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
|
||||||
printf("Invalid magic number: 0x%x\n", magic);
|
printf("Invalid magic number: 0x%x\n", magic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckMBT( (multiboot_info_t *) addr);
|
|
||||||
|
|
||||||
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
multiboot_info_t* mbt = (multiboot_info_t*) addr;
|
||||||
|
|
||||||
/* Are mmap_* valid? */
|
/* Are mmap_* valid? */
|
||||||
@ -26,38 +25,67 @@
|
|||||||
|
|
||||||
printf("Kernel MemoryMap:\n");
|
printf("Kernel MemoryMap:\n");
|
||||||
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end);
|
||||||
|
printf("Frames used: 0x%x blocks of 4 KiB\n", used_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
initGDT();
|
initGDT();
|
||||||
init_idt();
|
init_idt();
|
||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
asm volatile("STI");
|
asm volatile("STI");
|
||||||
|
|
||||||
|
|
||||||
|
CheckMBT( (multiboot_info_t *) addr);
|
||||||
|
|
||||||
|
|
||||||
kernel_main();
|
kernel_main();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void kernel_main (void) {
|
extern "C" void kernel_main (void) {
|
||||||
|
|
||||||
|
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pit_initialise();
|
pit_initialise();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (true){
|
while (true){
|
||||||
//Read time indefinetely
|
|
||||||
read_rtc();
|
printf("SUPERVISOR:>$ " );
|
||||||
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);
|
int characterCount = 0;
|
||||||
delay(1000);
|
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 "gdt/gdtc.h"
|
||||||
#include "idt/idt.h"
|
#include "idt/idt.h"
|
||||||
|
|
||||||
|
#include "keyboard/keyboard.h"
|
||||||
|
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "time.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++;
|
len++;
|
||||||
}
|
}
|
||||||
return 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
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
size_t strlen(const char* str);
|
size_t strlen(const char* str);
|
||||||
|
|
||||||
|
|
||||||
|
int strncmp ( const char* str1, const char* str2, size_t num );
|
Loading…
Reference in New Issue
Block a user