Trying to make my Kernel an Executable
Moderator:Moderators
Wouldn't all my problems just be solved if I stuck all the declarations into gdt.h and idt.h and then included them in main.c?
EDIT:
And they did ... except something's a bit wrong here lol...
For one thing the cursor is at the totally wrong location? Not sure why. I checked all my screen functions and as far as I can tell they are all taking care of updating the cursor position correctly. And the second problem....segment limit 0x-1000 lol? I think a problem with itoa_s and itoa perhaps?
EDIT:
And they did ... except something's a bit wrong here lol...
For one thing the cursor is at the totally wrong location? Not sure why. I checked all my screen functions and as far as I can tell they are all taking care of updating the cursor position correctly. And the second problem....segment limit 0x-1000 lol? I think a problem with itoa_s and itoa perhaps?
Re: Trying to make my Kernel an Executable
Hello,oib111 wrote:And the second problem....segment limit 0x-1000 lol? I think a problem with itoa_s and itoa perhaps?
That is (technically) the correct values. If the sign bit is set, the current functions will treat it as an signed integer rather then an unsigned integer which is why you are getting those values.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Re: Trying to make my Kernel an Executable
Oh ok, fixed it. Also, whenever I try generating an interrupt Bochs triple faults?
Re: Trying to make my Kernel an Executable
that means you have not set up the IDT correctly, or that your interrupt handlers are broken. Do you mind posting any relevent code please?
Re: Trying to make my Kernel an Executable
Ok, but it'll be a lot of code...
That was all the relevant things in idt.c (well things I thought were relevant), and here's the declaration of the regs structure in idt.h
Code: Select all
//Exception messages
char *exception_messages[32] = {
"Division by Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Info Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Code",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
};
//ISR (interrupt service routine definitions
//they all jump to our common stub which then passes the stack
//(represented by the regs structure) as a parameter to the
//fault_handler function
//remember, we push dummy error codes to keep the stack frame uniform
void isr0() {
_asm {
cli
push 0
push 0
jmp isr_common_stub
}
}
void isr1() {
_asm {
cli
push 0
push 1
jmp isr_common_stub
}
}
void isr2() {
_asm {
cli
push 0
push 2
jmp isr_common_stub
}
}
void isr3() {
_asm {
cli
push 0
push 3
jmp isr_common_stub
}
}
void isr4() {
_asm {
cli
push 0
push 4
jmp isr_common_stub
}
}
void isr5() {
_asm {
cli
push 0
push 5
jmp isr_common_stub
}
}
void isr6() {
_asm {
cli
push 0
push 6
jmp isr_common_stub
}
}
void isr7() {
_asm {
cli
push 0
push 7
jmp isr_common_stub
}
}
void isr8() {
_asm {
cli
push 8
jmp isr_common_stub
}
}
void isr9() {
_asm {
cli
push 0
push 9
jmp isr_common_stub
}
}
void isr10() {
_asm {
cli
push 10
jmp isr_common_stub
}
}
void isr11() {
_asm {
cli
push 11
jmp isr_common_stub
}
}
void isr12() {
_asm {
cli
push 12
jmp isr_common_stub
}
}
void isr13() {
_asm {
cli
push 13
jmp isr_common_stub
}
}
void isr14() {
_asm {
cli
push 14
jmp isr_common_stub
}
}
void isr15() {
_asm {
cli
push 0
push 15
jmp isr_common_stub
}
}
void isr16() {
_asm {
cli
push 0
push 16
jmp isr_common_stub
}
}
void isr17() {
_asm {
cli
push 0
push 17
jmp isr_common_stub
}
}
void isr18() {
_asm {
cli
push 0
push 18
jmp isr_common_stub
}
}
void isr19() {
_asm {
cli
push 0
push 19
jmp isr_common_stub
}
}
void isr20() {
_asm {
cli
push 0
push 20
jmp isr_common_stub
}
}
void isr21() {
_asm {
cli
push 0
push 21
jmp isr_common_stub
}
}
void isr22() {
_asm {
cli
push 0
push 22
jmp isr_common_stub
}
}
void isr23() {
_asm {
cli
push 0
push 23
jmp isr_common_stub
}
}
void isr24() {
_asm {
cli
push 0
push 24
jmp isr_common_stub
}
}
void isr25() {
_asm {
cli
push 0
push 25
jmp isr_common_stub
}
}
void isr26() {
_asm {
cli
push 0
push 26
jmp isr_common_stub
}
}
void isr27() {
_asm {
cli
push 0
push 27
jmp isr_common_stub
}
}
void isr28() {
_asm {
cli
push 0
push 28
jmp isr_common_stub
}
}
void isr29() {
_asm {
cli
push 0
push 29
jmp isr_common_stub
}
}
void isr30() {
_asm {
cli
push 0
push 30
jmp isr_common_stub
}
}
void isr31() {
_asm {
cli
push 0
push 31
jmp isr_common_stub
}
}
void isr_common_stub() {
_asm {
pusha
push ds
push es
push fs
push gs
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
call fault_handler
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8 ; Cleans up the stack
iret
}
return;
}
void fault_handler(struct regs *stack) {
setattrib(4, 15);
clrscr();
if(stack->int_no < 32) {
printf("fault_handler: Exception occurred: %s\n", exception_messages[stack->int_no]);
}
else {
printf("fault_handler: Unhandled exception occurred\n");
}
}
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) {
idt[num].base_lo = (base & 0xFFFF);
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
idt[num].always0 = 0;
idt[num].flags = flags;
}
void install_idt() {
idtp.limit = (sizeof(struct idt_entry)*256)-1;
idtp.base = &idt;
// blank out the IDT entries
memset(idt, 0, (sizeof(struct idt_entry)*256)-1);
// install all of our ISRs
idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E);
idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E);
idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E);
idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E);
idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E);
idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E);
idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E);
idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E);
idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
// load our IDT
idt_load();
}
Code: Select all
// What the stack looks like after an ISR was run
struct regs
{
unsigned int gs, fs, es, ds; // pushed the segs last
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by 'pusha'
unsigned int int_no, err_code; // our 'push #' and ecodes do this
int eip, cs, eflags, useresp, ss; // pushed by the processor automatically
};
Re: Trying to make my Kernel an Executable
That would be your problem.
You are not cleaning the stack up properly.
as a start, all the functions need to be declared as __declspec(naked) so there is no prolog or epilog code.
also, you need to use the "iretd" opcode rather than the "iret" one as you are in a 32bit code segment.
With any luck, that should stop the stack problems.
However, can you please explain why you are doing these things in the common_stub function?
You are not cleaning the stack up properly.
as a start, all the
Code: Select all
void isr<num>() {
_asm {
cli
push 0
push 0
jmp isr_common_stub
}
}
also, you need to use the "iretd" opcode rather than the "iret" one as you are in a 32bit code segment.
With any luck, that should stop the stack problems.
However, can you please explain why you are doing these things in the common_stub function?
Code: Select all
void isr_common_stub() {
_asm {
pusha
push ds
push es
push fs
push gs
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
call fault_handler
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8 ; Cleans up the stack
iret
}
return;
}
Re: Trying to make my Kernel an Executable
So that my function's don't change the previous registers. Also it'd be helpful for debugging purposes.
EDIT:
Adding _declspec(naked) and using iretd didn't help.
EDIT:
Adding _declspec(naked) and using iretd didn't help.
Re: Trying to make my Kernel an Executable
Hello,
isr_common_stub should also have __declspec (naked). Also insure you remove the add esp, 8 instruction when you do this as it will not be needed and will cause problems.
isr_common_stub should also have __declspec (naked). Also insure you remove the add esp, 8 instruction when you do this as it will not be needed and will cause problems.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Re: Trying to make my Kernel an Executable
Still triple faulting
Re: Trying to make my Kernel an Executable
Hello,
Are you sure the IRQ handlers are being executed properly without crashing? That is, put a CLI and HLT in your IRQ handlers to test if they properly halt the system or still triple fault.
Are you sure the IRQ handlers are being executed properly without crashing? That is, put a CLI and HLT in your IRQ handlers to test if they properly halt the system or still triple fault.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com
Re: Trying to make my Kernel an Executable
After a long discussion with Andy we fixed the problem! Woot haha.