[Stage1] Start IDT implementation

[Stage1] Screen.h improvements
This commit is contained in:
John 2023-01-18 10:59:09 +01:00
parent 5b17b79264
commit 17a18e4f91
Signed by: jstefanelli
GPG key ID: 60EDE2437640D2AA
8 changed files with 195 additions and 10 deletions

View file

@ -252,7 +252,7 @@ init_32:
MOV FS, AX ; ^^^^
MOV GS, AX ; ^^^^
MOV SS, AX ; ^^^^
MOV EAX, 0x7CFE ; reset stack
MOV EAX, 0x7bFF ; reset stack
MOV ESP, EAX ; ^^^^
JMP 0x10000 ; jump to stage1 bootloader

View file

@ -1,5 +1,6 @@
add_executable(stage1 stage1.c screen.c)
target_compile_options(stage1 PUBLIC -ffreestanding)
add_executable(stage1 stage1.c screen.c include/interrupts.h interrupts.c interrupt_utils.asm)
target_compile_options(stage1 PUBLIC "$<$<COMPILE_LANGUAGE:C>:-ffreestanding>")
set_target_properties(stage1 PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
target_link_options(stage1 PRIVATE -T${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
target_include_directories(stage1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../os3_common/)
target_link_libraries(stage1 libfat)

View file

@ -0,0 +1,43 @@
#ifndef OS3_INTERRUPTS_H
#define OS3_INTERRUPTS_H
#include "datatypes.h"
#include "packing.h"
#include "screen.h"
OS_PACK_START
typedef struct __idt_attributes {
os_u8 gate_type: 4;
os_u8 empty : 1;
os_u8 dpl : 2;
os_u8 present: 1;
} OS_PACK_MID idt_attributes;
OS_PACK_END
#define IDT_GATE_TYPE_TASK 0x5
#define IDT_GATE_TYPE_INTERRUPT_16 0x6
#define IDT_GATE_TYPE_TRAP_16 0x7
#define IDT_GATE_TYPE_INTERRUPT_32 0xE
#define IDT_GATE_TYPE_TRAP_32 0xF
OS_PACK_START
typedef struct __idt_entry {
os_u16 isr_low;
os_u16 kernel_gdt_code_segment;
os_u8 reserved;
//idt_attributes attributes;
os_u8 attributes;
os_u16 isr_high;
} OS_PACK_MID idt_entry;
OS_PACK_END
OS_PACK_START
typedef struct __idt_ptr {
os_u16 limit;
os_u32 base;
} OS_PACK_MID idt_ptr;
OS_PACK_END
extern void fill_idt();
#endif //OS3_INTERRUPTS_H

View file

@ -1,7 +1,10 @@
#ifndef __OS3_ST1_SCREEN_H
#define __OS3_ST1_SCREEN_H
extern void write_string(const char*, int);
#include "datatypes.h"
extern void write_string(const char*, int);
extern void clear_screen();
extern void write_number(os_u32 number);
#endif

View file

@ -0,0 +1,37 @@
; list of 256 void* to call when the corresponding interrupt is received
extern interrupt_service_list, generic_exception
%macro interrupt_service_routine 1
isr_stub_%+%1:
;CALL interrupt_service_list + (%1*4)
CALL generic_exception
IRET
%endmacro
; Generate entry points for interrupt service routines
%assign i 0
%rep 256
interrupt_service_routine i
%assign i i+1
%endrep
; list of ISR entries
global interrupt_service_table
interrupt_service_table:
%assign i 0
%rep 256
dd isr_stub_%+i
%assign i i+1
%endrep
; void load_idt(void* idt_ptr)
global load_idt
load_idt:
LIDT [ESP+4] ; load idt with SP+4
RET ; return
; void enable_interrupts()
global enable_interrupts
enable_interrupts:
STI ; enable interrupts
RET ; return

56
stage1/interrupts.c Normal file
View file

@ -0,0 +1,56 @@
#include "include/interrupts.h"
#define EFFECTIVE_INTERRUPT_AMOUNT 32
__attribute__((aligned(0x10)))
idt_entry main_idt[EFFECTIVE_INTERRUPT_AMOUNT];
idt_ptr main_idt_ptr;
volatile void* interrupt_service_list[EFFECTIVE_INTERRUPT_AMOUNT];
void generic_exception() {
//clear_screen();
write_string("Exception received: ", 0);
write_number(0);
write_string("\n", 0);
__asm__("cli; hlt;");
while(1) {
}
}
/* The following is defined in interrupt_utils.asm */
extern void* interrupt_service_table[];
extern void load_idt(void* idtr_ptr);
extern void enable_interrupts();
/* --- */
void fill_idt() {
main_idt_ptr.base = (os_u32) &main_idt[0];
main_idt_ptr.limit = ((os_u16) (sizeof(idt_entry) * EFFECTIVE_INTERRUPT_AMOUNT)) - 1;
os_u32 val = (os_u32) interrupt_service_table[0];
write_string("ISR address: ", 0);
write_number(val);
write_string("\n", 1);
for (int i = 0; i < EFFECTIVE_INTERRUPT_AMOUNT; i++) {
//os_u32 val = (os_u32) interrupt_service_table[0];
os_u32 val = (os_u32) &generic_exception;
main_idt[i].isr_low = (os_u16)(val & 0xFFFF);
main_idt[i].isr_high = (os_u16)(val >> 16);
main_idt[i].kernel_gdt_code_segment = 0x08;
main_idt[i].reserved = 0;
/*
main_idt[i].attributes.present = 1;
main_idt[i].attributes.gate_type = IDT_GATE_TYPE_INTERRUPT_32;
main_idt[i].attributes.empty = 0;
main_idt[i].attributes.dpl = i == 0x49 ? 3 : 0;
*/
main_idt[i].attributes = 0x8e;
interrupt_service_list[i] = (void*)&generic_exception;
}
load_idt((void*)&main_idt_ptr);
enable_interrupts();
}

View file

@ -21,6 +21,9 @@ void write_string(const char* str, int max_len) {
}
if (c == '\n') {
if (y == 24) {
clear_screen();
}
y = (y + 1) % 25;
x = 0;
str++;
@ -30,6 +33,9 @@ void write_string(const char* str, int max_len) {
write_character(c);
x++;
if (x >= 80) {
if (y == 24) {
clear_screen();
}
y = (y + 1) % 25;
x = 0;
}
@ -37,3 +43,41 @@ void write_string(const char* str, int max_len) {
i++;
} while(i < max_len || max_len == 0);
}
void clear_screen() {
os_u16* ptr = (os_u16*) 0xB8000;
for (int y = 0; y < 25; y++) {
for (int x = 0; x < 80; x++) {
*ptr = 0;
ptr++;
}
}
x = 0;
y = 0;
}
void write_number(os_u32 number) {
char buffer[32];
char buffer_2[32];
os_s32 i = 1;
while(i < 32) {
if (i > 1 && number == 0) {
break;
}
buffer[i] = ((char)(number % 10)) + '0';
i++;
number /= 10;
}
i--;
buffer[0] = '\0';
char* buffer_2_ptr = buffer_2;
while(i >= 0) {
*buffer_2_ptr = buffer[i];
buffer_2_ptr++;
i--;
}
write_string(buffer_2, 0);
}

View file

@ -1,16 +1,17 @@
//
// Created by barba on 06/10/2022.
//
#include "../os3_common/datatypes.h"
#include "../os3_common/packing.h"
#include "include/screen.h"
#include "include/interrupts.h"
int main() {
clear_screen();
write_string("OS3 Booted into stage 1!\n", 0);
write_string("Looking for stage 2....", 0);
write_string("Looking for stage 2....\n", 0);
fill_idt();
os_u32 i = 0;
while(1) {
write_number(i++);
write_string("\n", 0);
};
return 0;