Permalink
Browse files

Files for part 5, https://www.youtube.com/watch?v=AgeX-U4dKSs

  • Loading branch information...
Viktor Engelmann Viktor Engelmann
Viktor Engelmann authored and Viktor Engelmann committed Jul 4, 2016
1 parent 8745b3c commit 01557ac3b68bc7f9e39e76d4b4bf2fdbe627ce3d
Showing with 348 additions and 8 deletions.
  1. +144 −0 interrupts.cpp
  2. +93 −0 interrupts.h
  3. +101 −0 interruptstubs.s
  4. +6 −3 kernel.cpp
  5. +4 −5 makefile
View
@@ -0,0 +1,144 @@
#include "interrupts.h"
void printf(char* str);
InterruptManager::GateDescriptor InterruptManager::interruptDescriptorTable[256];
void InterruptManager::SetInterruptDescriptorTableEntry(uint8_t interrupt,
uint16_t CodeSegment, void (*handler)(), uint8_t DescriptorPrivilegeLevel, uint8_t DescriptorType)
{
// address of pointer to code segment (relative to global descriptor table)
// and address of the handler (relative to segment)
interruptDescriptorTable[interrupt].handlerAddressLowBits = ((uint32_t) handler) & 0xFFFF;
interruptDescriptorTable[interrupt].handlerAddressHighBits = (((uint32_t) handler) >> 16) & 0xFFFF;
interruptDescriptorTable[interrupt].gdt_codeSegmentSelector = CodeSegment;
const uint8_t IDT_DESC_PRESENT = 0x80;
interruptDescriptorTable[interrupt].access = IDT_DESC_PRESENT | ((DescriptorPrivilegeLevel & 3) << 5) | DescriptorType;
interruptDescriptorTable[interrupt].reserved = 0;
}
InterruptManager::InterruptManager(uint16_t hardwareInterruptOffset, GlobalDescriptorTable* globalDescriptorTable)
: programmableInterruptControllerMasterCommandPort(0x20),
programmableInterruptControllerMasterDataPort(0x21),
programmableInterruptControllerSlaveCommandPort(0xA0),
programmableInterruptControllerSlaveDataPort(0xA1)
{
this->hardwareInterruptOffset = hardwareInterruptOffset;
uint32_t CodeSegment = globalDescriptorTable->CodeSegmentSelector();
const uint8_t IDT_INTERRUPT_GATE = 0xE;
for(uint8_t i = 255; i > 0; --i)
{
SetInterruptDescriptorTableEntry(i, CodeSegment, &InterruptIgnore, 0, IDT_INTERRUPT_GATE);
//handlers[i] = 0;
}
SetInterruptDescriptorTableEntry(0, CodeSegment, &InterruptIgnore, 0, IDT_INTERRUPT_GATE);
//handlers[0] = 0;
SetInterruptDescriptorTableEntry(0x00, CodeSegment, &HandleException0x00, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x01, CodeSegment, &HandleException0x01, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x02, CodeSegment, &HandleException0x02, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x03, CodeSegment, &HandleException0x03, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x04, CodeSegment, &HandleException0x04, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x05, CodeSegment, &HandleException0x05, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x06, CodeSegment, &HandleException0x06, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x07, CodeSegment, &HandleException0x07, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x08, CodeSegment, &HandleException0x08, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x09, CodeSegment, &HandleException0x09, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0A, CodeSegment, &HandleException0x0A, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0B, CodeSegment, &HandleException0x0B, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0C, CodeSegment, &HandleException0x0C, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0D, CodeSegment, &HandleException0x0D, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0E, CodeSegment, &HandleException0x0E, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x0F, CodeSegment, &HandleException0x0F, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x10, CodeSegment, &HandleException0x10, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x11, CodeSegment, &HandleException0x11, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x12, CodeSegment, &HandleException0x12, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(0x13, CodeSegment, &HandleException0x13, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x00, CodeSegment, &HandleInterruptRequest0x00, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x01, CodeSegment, &HandleInterruptRequest0x01, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x02, CodeSegment, &HandleInterruptRequest0x02, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x03, CodeSegment, &HandleInterruptRequest0x03, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x04, CodeSegment, &HandleInterruptRequest0x04, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x05, CodeSegment, &HandleInterruptRequest0x05, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x06, CodeSegment, &HandleInterruptRequest0x06, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x07, CodeSegment, &HandleInterruptRequest0x07, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x08, CodeSegment, &HandleInterruptRequest0x08, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x09, CodeSegment, &HandleInterruptRequest0x09, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0A, CodeSegment, &HandleInterruptRequest0x0A, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0B, CodeSegment, &HandleInterruptRequest0x0B, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0C, CodeSegment, &HandleInterruptRequest0x0C, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0D, CodeSegment, &HandleInterruptRequest0x0D, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0E, CodeSegment, &HandleInterruptRequest0x0E, 0, IDT_INTERRUPT_GATE);
SetInterruptDescriptorTableEntry(hardwareInterruptOffset + 0x0F, CodeSegment, &HandleInterruptRequest0x0F, 0, IDT_INTERRUPT_GATE);
programmableInterruptControllerMasterCommandPort.Write(0x11);
programmableInterruptControllerSlaveCommandPort.Write(0x11);
// remap
programmableInterruptControllerMasterDataPort.Write(hardwareInterruptOffset);
programmableInterruptControllerSlaveDataPort.Write(hardwareInterruptOffset+8);
programmableInterruptControllerMasterDataPort.Write(0x04);
programmableInterruptControllerSlaveDataPort.Write(0x02);
programmableInterruptControllerMasterDataPort.Write(0x01);
programmableInterruptControllerSlaveDataPort.Write(0x01);
programmableInterruptControllerMasterDataPort.Write(0x00);
programmableInterruptControllerSlaveDataPort.Write(0x00);
InterruptDescriptorTablePointer idt_pointer;
idt_pointer.size = 256*sizeof(GateDescriptor) - 1;
idt_pointer.base = (uint32_t)interruptDescriptorTable;
asm volatile("lidt %0" : : "m" (idt_pointer));
}
InterruptManager::~InterruptManager()
{
Deactivate();
}
uint16_t InterruptManager::HardwareInterruptOffset()
{
return hardwareInterruptOffset;
}
void InterruptManager::Activate()
{
//if(ActiveInterruptManager == 0)
{
//ActiveInterruptManager = this;
asm("sti");
}
}
void InterruptManager::Deactivate()
{
/*if(ActiveInterruptManager == this)
{
ActiveInterruptManager = 0;
*/
//asm("cli");
/*
}*/
}
uint32_t InterruptManager::HandleInterrupt(uint8_t interrupt, uint32_t esp)
{
char* foo = "INTERRUPT 0x00";
char* hex = "0123456789ABCDEF";
foo[12] = hex[(interrupt >> 4) & 0xF];
foo[13] = hex[interrupt & 0xF];
printf(foo);
return esp;
}
View
@@ -0,0 +1,93 @@
#ifndef __INTERRUPTMANAGER_H
#define __INTERRUPTMANAGER_H
#include "gdt.h"
#include "types.h"
#include "port.h"
class InterruptManager
{
//friend class InterruptHandler;
protected:
struct GateDescriptor
{
uint16_t handlerAddressLowBits;
uint16_t gdt_codeSegmentSelector;
uint8_t reserved;
uint8_t access;
uint16_t handlerAddressHighBits;
} __attribute__((packed));
static GateDescriptor interruptDescriptorTable[256];
struct InterruptDescriptorTablePointer
{
uint16_t size;
uint32_t base;
} __attribute__((packed));
uint16_t hardwareInterruptOffset;
//static InterruptManager* ActiveInterruptManager;
static void SetInterruptDescriptorTableEntry(uint8_t interrupt,
uint16_t codeSegmentSelectorOffset, void (*handler)(),
uint8_t DescriptorPrivilegeLevel, uint8_t DescriptorType);
static void InterruptIgnore();
static void HandleInterruptRequest0x00();
static void HandleInterruptRequest0x01();
static void HandleInterruptRequest0x02();
static void HandleInterruptRequest0x03();
static void HandleInterruptRequest0x04();
static void HandleInterruptRequest0x05();
static void HandleInterruptRequest0x06();
static void HandleInterruptRequest0x07();
static void HandleInterruptRequest0x08();
static void HandleInterruptRequest0x09();
static void HandleInterruptRequest0x0A();
static void HandleInterruptRequest0x0B();
static void HandleInterruptRequest0x0C();
static void HandleInterruptRequest0x0D();
static void HandleInterruptRequest0x0E();
static void HandleInterruptRequest0x0F();
static void HandleInterruptRequest0x31();
static void HandleException0x00();
static void HandleException0x01();
static void HandleException0x02();
static void HandleException0x03();
static void HandleException0x04();
static void HandleException0x05();
static void HandleException0x06();
static void HandleException0x07();
static void HandleException0x08();
static void HandleException0x09();
static void HandleException0x0A();
static void HandleException0x0B();
static void HandleException0x0C();
static void HandleException0x0D();
static void HandleException0x0E();
static void HandleException0x0F();
static void HandleException0x10();
static void HandleException0x11();
static void HandleException0x12();
static void HandleException0x13();
static uint32_t HandleInterrupt(uint8_t interrupt, uint32_t esp);
Port8BitSlow programmableInterruptControllerMasterCommandPort;
Port8BitSlow programmableInterruptControllerMasterDataPort;
Port8BitSlow programmableInterruptControllerSlaveCommandPort;
Port8BitSlow programmableInterruptControllerSlaveDataPort;
public:
InterruptManager(uint16_t hardwareInterruptOffset, GlobalDescriptorTable* globalDescriptorTable);
~InterruptManager();
uint16_t HardwareInterruptOffset();
void Activate();
void Deactivate();
};
#endif
View
@@ -0,0 +1,101 @@
.set IRQ_BASE, 0x20
.section .text
.extern _ZN16InterruptManager15HandleInterruptEhj
.macro HandleException num
.global _ZN16InterruptManager19HandleException\num\()Ev
_ZN16InterruptManager19HandleException\num\()Ev:
movb $\num, (interruptnumber)
jmp int_bottom
.endm
.macro HandleInterruptRequest num
.global _ZN16InterruptManager26HandleInterruptRequest\num\()Ev
_ZN16InterruptManager26HandleInterruptRequest\num\()Ev:
movb $\num + IRQ_BASE, (interruptnumber)
jmp int_bottom
.endm
HandleException 0x00
HandleException 0x01
HandleException 0x02
HandleException 0x03
HandleException 0x04
HandleException 0x05
HandleException 0x06
HandleException 0x07
HandleException 0x08
HandleException 0x09
HandleException 0x0A
HandleException 0x0B
HandleException 0x0C
HandleException 0x0D
HandleException 0x0E
HandleException 0x0F
HandleException 0x10
HandleException 0x11
HandleException 0x12
HandleException 0x13
HandleInterruptRequest 0x00
HandleInterruptRequest 0x01
HandleInterruptRequest 0x02
HandleInterruptRequest 0x03
HandleInterruptRequest 0x04
HandleInterruptRequest 0x05
HandleInterruptRequest 0x06
HandleInterruptRequest 0x07
HandleInterruptRequest 0x08
HandleInterruptRequest 0x09
HandleInterruptRequest 0x0A
HandleInterruptRequest 0x0B
HandleInterruptRequest 0x0C
HandleInterruptRequest 0x0D
HandleInterruptRequest 0x0E
HandleInterruptRequest 0x0F
HandleInterruptRequest 0x31
int_bottom:
# register sichern
pusha
pushl %ds
pushl %es
pushl %fs
pushl %gs
# ring 0 segment register laden
#cld
#mov $0x10, %eax
#mov %eax, %eds
#mov %eax, %ees
# C++ Handler aufrufen
pushl %esp
push (interruptnumber)
call _ZN16InterruptManager15HandleInterruptEhj
add %esp, 6
mov %eax, %esp # den stack wechseln
# register laden
pop %gs
pop %fs
pop %es
pop %ds
popa
.global _ZN16InterruptManager15InterruptIgnoreEv
_ZN16InterruptManager15InterruptIgnoreEv:
iret
.data
interruptnumber: .byte 0
View
@@ -1,13 +1,14 @@
#include "types.h"
#include "gdt.h"
#include "interrupts.h"
void printf(char* str)
{
static uint16_t* VideoMemory = (uint16_t*)0xb8000;
static uint8_t x=0,y=0;
for(int i = 0; str[i] != '\0'; ++i)
{
switch(str[i])
@@ -21,13 +22,13 @@ void printf(char* str)
x++;
break;
}
if(x >= 80)
{
x = 0;
y++;
}
if(y >= 25)
{
for(y = 0; y < 25; y++)
@@ -57,6 +58,8 @@ extern "C" void kernelMain(const void* multiboot_structure, uint32_t /*multiboot
printf("Hello World! --- http://www.AlgorithMan.de");
GlobalDescriptorTable gdt;
InterruptManager interrupts(0x20, &gdt);
interrupts.Activate();
while(1);
}
Oops, something went wrong.

5 comments on commit 01557ac

@MasterCna

This comment has been minimized.

Show comment
Hide comment
@MasterCna

MasterCna Apr 15, 2017

I told you in the forum everything is fine, but somewhere in your code was wrong!

MasterCna replied Apr 15, 2017

I told you in the forum everything is fine, but somewhere in your code was wrong!

@Muttsuri

This comment has been minimized.

Show comment
Hide comment
@Muttsuri

Muttsuri Jun 25, 2017

There is a syntax error on this line on interrupts.cpp.
Located in the begining of the " Interrupt::InterruptManager" functin:
The line is like this:

this->hardwareInterruptOffset = hardwareInterruptOffset; 

It should be like this:

uint16_t hardwareInterruptOffset = this->hardwareInterruptOffset(); 

EDIT: That is unless you want to get the HardwareInterruptOffset value out of the function call and then send it to this->hardwareInterruptOffset(). (Which you are still missing () at the end of hardwareInterruptOffset I think)

The next line applies this syntax corectly(taken in count the original statement). At least to me they seem to be the same opertation but with diferent values. Shouldn't they follow the same syntax. Please do correct me if I'm wrong.

uint32_t CodeSegment = globalDescriptorTable->CodeSegmentSelector();

And this one has it's own problems I think, wasn't "CodeSegmentSelector()" as defined in gdt.h a uint16_t value. And as such should it not be:

uint16_t CodeSegment = globalDescriptorTable->CodeSegmentSelector();

instead ?

Muttsuri replied Jun 25, 2017

There is a syntax error on this line on interrupts.cpp.
Located in the begining of the " Interrupt::InterruptManager" functin:
The line is like this:

this->hardwareInterruptOffset = hardwareInterruptOffset; 

It should be like this:

uint16_t hardwareInterruptOffset = this->hardwareInterruptOffset(); 

EDIT: That is unless you want to get the HardwareInterruptOffset value out of the function call and then send it to this->hardwareInterruptOffset(). (Which you are still missing () at the end of hardwareInterruptOffset I think)

The next line applies this syntax corectly(taken in count the original statement). At least to me they seem to be the same opertation but with diferent values. Shouldn't they follow the same syntax. Please do correct me if I'm wrong.

uint32_t CodeSegment = globalDescriptorTable->CodeSegmentSelector();

And this one has it's own problems I think, wasn't "CodeSegmentSelector()" as defined in gdt.h a uint16_t value. And as such should it not be:

uint16_t CodeSegment = globalDescriptorTable->CodeSegmentSelector();

instead ?

@mkhanstk

This comment has been minimized.

Show comment
Hide comment
@mkhanstk

mkhanstk Jul 7, 2018

Hi, the Video 5 has no audio. please reload it with audio.
https://www.youtube.com/watch?v=AgeX-U4dKSs
thanks.

mkhanstk replied Jul 7, 2018

Hi, the Video 5 has no audio. please reload it with audio.
https://www.youtube.com/watch?v=AgeX-U4dKSs
thanks.

@AlgorithMan-de

This comment has been minimized.

Show comment
Hide comment
@AlgorithMan-de

AlgorithMan-de Jul 8, 2018

Owner

The video has audio, but only on the left channel.

Owner

AlgorithMan-de replied Jul 8, 2018

The video has audio, but only on the left channel.

@zwoelfer

This comment has been minimized.

Show comment
Hide comment
@zwoelfer

zwoelfer Aug 15, 2018

Why is 1 substracted from 256 * sizeof(GateDescriptor) when setting the size of the table (see interrupts.cpp, line 99)? I thought 256 * sizeof(GateDescriptor) was the size of the IDT in bytes.

zwoelfer replied Aug 15, 2018

Why is 1 substracted from 256 * sizeof(GateDescriptor) when setting the size of the table (see interrupts.cpp, line 99)? I thought 256 * sizeof(GateDescriptor) was the size of the IDT in bytes.

Please sign in to comment.