Re-enabled interrupts from keyboard, Enabled and configured the PIT to throw interrupts at a regular interval

dev
Nigel Barink 2021-12-20 21:53:57 +01:00
parent 23ede25ed6
commit 88cc1d75bb
10 changed files with 128 additions and 60 deletions

View File

@ -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)/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)/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
@ -23,8 +23,6 @@ all: clean build
build: build_kernel iso
clean_iso:
if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi
if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi
@ -36,7 +34,7 @@ iso: clean_iso clean build
grub-mkrescue -o build/barinkOS.iso root
test:
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -monitor stdio -display gtk -m 2G -cpu core2duo
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo
build_kernel: $(OBJ_LINK_LIST)
$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
@ -85,3 +83,6 @@ $(BUILD_DIR)/string.o:
$(BUILD_DIR)/PhysicalMemoryManager.o:
$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.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

View File

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

View File

@ -29,6 +29,8 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
void initGDT(){
printf("Init GDT!\n");
// NULL segment
add_descriptor(NULL_SEGMENT, 0,0,0,0);
@ -52,10 +54,4 @@ void initGDT(){
LoadGlobalDescriptorTable();
while (true)
asm volatile("hlt");
}

View File

@ -1,4 +1,5 @@
#include "idt.h"
#include "../pit.h"
//#include "scancodes/set1.h"
IDT_entry idt_table[256];
@ -24,6 +25,8 @@ void irs_handler (registers regs) {
}
@ -32,36 +35,33 @@ void irs_handler (registers regs) {
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 ){
switch (regs.int_no)
{
case 0:
pit_tick++;
break;
case 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);
break;
}
default:
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) {
@ -76,16 +76,13 @@ void irq_handler (registers regs) {
}
void init_idt(){
// Initialise the IDT pointer
idt_ptr.length = sizeof(IDT_entry) * 255;
idt_ptr.base = (uint32_t)&idt_table;
printf("Init IDT\n");
// TODO: Set everything to zero first
set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F);

View File

@ -22,7 +22,7 @@ unsigned int inl_p(unsigned short ){
}
void outb_p(unsigned char , unsigned short ){
void b_p(unsigned char , unsigned short ){
}
void outw(unsigned short , unsigned short ){

View File

@ -1,6 +1,8 @@
#include "kernel.h"
#define GB4 524288
#define GB2 262144
extern "C" void kernel_main (void);
extern "C" void early_main(unsigned long magic, unsigned long addr){
/** initialize terminal interface */
kterm_init();
@ -27,19 +29,30 @@
}
initGDT();
init_idt();
// Enable interrupts
asm volatile("STI");
kernel_main();
}
extern "C" void kernel_main (void) {
printf("call to init serial\n");
init_serial();
pit_initialise();
while (true){
//Read time indefinetely
read_rtc();
printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
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);
}

View File

@ -12,6 +12,7 @@ extern "C"{
#include "gdt/gdtc.h"
#include "idt/idt.h"
#include "pit.h"
#include "io.h"
#include "time.h"
#include "cpu.h"

53
src/kernel/pit.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "pit.h"
#include "tty/kterm.h"
uint32_t pit_tick = 0;
void pit_initialise()
{
asm volatile("CLI");
printf("init PIT!\n");
// 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
View File

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
#include "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();

View File

@ -4,6 +4,7 @@
#include "io.h"
#define PORT 0x3f8
static int init_serial() {
printf("Init serial\n");
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