Skip to content

Commit 549cf6b

Browse files
committed
Improve hardware exception handler.
1 parent e17f27e commit 549cf6b

File tree

7 files changed

+67
-5
lines changed

7 files changed

+67
-5
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ binaries: $(bt_stage1) $(bt_stage2) $(kernel_core) $(rm_static)
102102
SECTOR_COUNT_BT_STAGE1 = 1
103103
SECTOR_COUNT_SHARED_LIBRARY = 1
104104
SECTOR_COUNT_BT_STAGE2 = 12
105-
SECTOR_COUNT_KERNEL = 52
105+
SECTOR_COUNT_KERNEL = 54
106106

107107
SECTOR_START_BT_STAGE1 = 0
108108
SECTOR_START_SHARED_LIBRARY = $(shell expr $(SECTOR_START_BT_STAGE1) + $(SECTOR_COUNT_BT_STAGE1) )

include/fuzzy/kernel/panic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
void panic_just_halt();
1010
int panic(int err, const char *message, const char *src_file,
1111
unsigned int line_number);
12+
int panic_screen_init();

include/fuzzy/memmgr/tables/gdt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct GDTEntry {
1818
};
1919
#pragma pack(pop)
2020

21+
int get_gdt_baseaddress(struct GDTEntry gdt_table[], unsigned int table_size, int entry_id);
2122

2223
void populate_gdt_entry(struct GDTEntry *entry,
2324
unsigned int base,

src/kernel/interrupts/exceptions.asm

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,16 @@ global _interrupt_handler_0x1F_exception
4141
_interrupt_handler_%1_exception:
4242
; As we are HLT at end of exception there
4343
; is no need to save context for now.
44+
xor eax, eax
45+
mov eax, ds ; execution ds
46+
push eax
47+
xor eax, eax
48+
mov eax, ss ; execution ss (current also)
49+
push eax
50+
mov eax, 0x10 ; kernel ds
51+
mov ds, eax
4452
mov eax, %1
4553
push eax
46-
; arg0: exception number
47-
; arg1: return IP
48-
; arg2: return CS
4954
call interrupt_handler_0x00_0x1F_exception
5055
HLT
5156
%endmacro

src/kernel/interrupts/exceptions.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#include <fuzzy/kernel/panic.h>
2+
#include <fuzzy/memmgr/tables/gdt.h>
3+
#include <fuzzy/kernel/process/process.h>
4+
5+
extern struct GDTEntry gdt_table[];
26

37
extern void _interrupt_handler_0x00_exception();
48
extern void _interrupt_handler_0x01_exception();
@@ -33,7 +37,37 @@ extern void _interrupt_handler_0x1D_exception();
3337
extern void _interrupt_handler_0x1E_exception();
3438
extern void _interrupt_handler_0x1F_exception();
3539

36-
void interrupt_handler_0x00_0x1F_exception(int id, int ip, int cs) {
40+
void interrupt_handler_0x00_0x1F_exception(int id, int err_code, int ds, int ss, int ip, int cs, int eflag) {
41+
panic_screen_init();
42+
unsigned int abs_address =
43+
print_log("Hardware exception %d (0x%x) triggered", id, id);
44+
print_log(" Error Code: %x or %x", err_code);
45+
print_log(" CS : %x (GDT entry)", cs);
46+
print_log(" DS : %x (GDT entry)", ds);
47+
print_log(" SS : %x (GDT entry)", ss);
48+
print_log(" IP : %x", ip);
49+
print_log(" FLAG : %x", eflag);
50+
if(cs%sizeof(struct GDTEntry)==0) {
51+
print_log(" PID : %d", get_idt_reverse_pid_lookup_cs(cs));
52+
unsigned int abs_cs = get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, cs/sizeof(struct GDTEntry));
53+
print_log(" abs IP: %x", abs_cs+ip);
54+
print_log(" abs CS: %x", abs_cs);
55+
} else {
56+
print_log(" PID : invalid");
57+
print_log(" abs IP: invalid");
58+
print_log(" abs CS: invalid");
59+
}
60+
if(ds%sizeof(struct GDTEntry)==0) {
61+
print_log(" abs DS: %x", get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, ds/sizeof(struct GDTEntry)));
62+
} else {
63+
print_log(" abs DS: invalid");
64+
}
65+
if(ss%sizeof(struct GDTEntry)==0) {
66+
print_log(" abs SS: %x", get_gdt_baseaddress(gdt_table, GDT_TABLE_SIZE, ss/sizeof(struct GDTEntry)));
67+
} else {
68+
print_log(" abs SS: invalid");
69+
}
70+
3771
switch (id) {
3872
case 0x0D:
3973
PANIC(id, "[hw_exception] general_protection_fault");

src/kernel/panic.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ int panic(int err, const char *message, const char *src_file,
2323
print_line(message);
2424
panic_just_halt();
2525
}
26+
27+
int panic_screen_init() {
28+
set_color_bg(C_RED);
29+
set_color_fg(C_WHITE);
30+
// first two lines are used by panic(...)
31+
move_xy(0,2);
32+
// kernel can not use print_log(...) to write.
33+
return 0;
34+
}

src/memmgr/tables/gdt.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33

44
#include <lib/utils/logging.h>
55

6+
int get_gdt_baseaddress(struct GDTEntry gdt_table[], unsigned int table_size, int entry_id) {
7+
if(entry_id>=0 && entry_id<table_size) {
8+
unsigned int base0 = gdt_table[entry_id].base0;
9+
unsigned int base1 = gdt_table[entry_id].base1;
10+
base1 <<= 16;
11+
unsigned int base2 = gdt_table[entry_id].base2;
12+
base2 <<= 24;
13+
return base2|base1|base0;
14+
}
15+
return -1;
16+
}
17+
618
void populate_gdt_entry(struct GDTEntry *entry,
719
unsigned int base,
820
unsigned int limit, // 20 bits

0 commit comments

Comments
 (0)