[Stage1] Start IDT implementation
[Stage1] Screen.h improvements
This commit is contained in:
parent
5b17b79264
commit
17a18e4f91
8 changed files with 195 additions and 10 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
43
stage1/include/interrupts.h
Normal file
43
stage1/include/interrupts.h
Normal 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
|
||||
|
|
@ -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
|
||||
37
stage1/interrupt_utils.asm
Normal file
37
stage1/interrupt_utils.asm
Normal 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
56
stage1/interrupts.c
Normal 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();
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue