Page 1 of 1
When try to install GDT in GRUB, it does not call the kernel
Posted: Tue Dec 03, 2019 12:30 pm
by mrjbom
Hello.
I asked a similar question
here, but the solution outlined there did not help me. I tried writing the code myself. The bootloader code is described
here(there you can also see the code of the entire system).
Now my problem is that the
kmain function does not work completely. GRUB does not call it.
The code should call it right after setting up
GDT and enabling interrupts, but I see a black screen even though the screen should be colored.
Thanks.
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Tue Dec 03, 2019 2:13 pm
by Octocontrabass
It's a bad idea to copy code you don't understand.
I suggest you study assembly language a bit and come back once you understand why your code will never call kmain. You don't need to be an expert, but you must at least learn the basics to write an OS.
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Tue Dec 03, 2019 2:32 pm
by iansjack
Do you think it is wise to enable interrupts before installing an IDT and some interrupt handlers?
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Wed Dec 04, 2019 2:57 pm
by mrjbom
iansjack wrote:Do you think it is wise to enable interrupts before installing an IDT and some interrupt handlers?
Understood. I updated the loader code, now it only loads GDT, then in kmain I try to initialize IDT, but when I try do that I get a critical error. What's wrong?
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 8:54 am
by MichaelPetch
Because in your bootloader.asm asm after using LGDT to load the new global descriptor table you don't actually set the segment registers to the new values. The original values that GRUB may have set may not be the layout of yours. After doing LGDT do something like:
Code: Select all
load_gdt:
lgdt [gdt_desc] ;load GDT
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.setcs
.setcs:
One other problem is that you don't have any infinite loop in your `kmain` and you return back to bootloader.asm where you do a HLT instruction. HLT will wait for the first interrupt and then carry on executing code after the HLT and that could be anything that is in memory. If you want to keep interrupts disabled at the end then you'd have to do something like:
If you wish to keep them enabled you'd have to do something like:
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 12:12 pm
by mrjbom
MichaelPetch wrote:Because in your bootloader.asm asm after using LGDT to load the new global descriptor table you don't actually set the segment registers to the new values. The original values that GRUB may have set may not be the layout of yours.
Okay, now I'm not getting a critical error. But the interrupts still don't work.
I get false from
are_interrupts_enabled().
Did I forget to do something?
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 3:16 pm
by MichaelPetch
Because your function that detects if the IF flag is set return a bool which you have defined as `typedef unsigned char bool;` The compiler is likely returning 0 because the 9th bit is beyond the extent of a byte return value. If you want to return a value of 0 or 1 you'll have to modify what you return. One way is to change what you return to:
to convert a non zero value to 1 or a zero value to 0.
I'd also recommend compiling with -Wall -Wextra -Werror so that you eliminate all the warnings. -Werror is convenient as it will refuse to continue generate an object file when an error is encountered forcing you to deal with the warnings.
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 3:53 pm
by mrjbom
MichaelPetch wrote:Because your function that detects if the IF flag is set return a bool which you have defined as `typedef unsigned char bool;` The compiler is likely returning 0 because the 9th bit is beyond the extent of a byte return value. If you want to return a value of 0 or 1 you'll have to modify what you return. One way is to change what you return to:
to convert a non zero value to 1 or a zero value to 0..
How would it be more correct to declare
bool to avoid such problems?
It helped. But I found that I do not call
lidt() before
idt_init(), maybe this is the problem?
Now, if there is an interruption, for example when a button is pressed on the keyboard, then
irq2_handler() will be called?
And another small question: Now
kmain() immediately terminates after execution and I do not see a reaction to the interrupt(I tried to check this with the keyboard and
irq2_handler()), how can I make
kmain() not terminate but work as much as I need?
MichaelPetch wrote:
I'd also recommend compiling with -Wall -Wextra -Werror so that you eliminate all the warnings. -Werror is convenient as it will refuse to continue generate an object file when an error is encountered forcing you to deal with the warnings.
Understood, in the future I will compile like this.
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 4:52 pm
by mrjbom
MichaelPetch wrote:Because your function that detects if the IF flag is set return a bool which you have defined as `typedef unsigned char bool;`
I tried declaring
bool this way
typedef _Bool bool; , which is what does
stdbool.h, but that didn't help either. So how can I declare it so as not to face similar problems in the future?
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Thu Dec 05, 2019 6:53 pm
by MichaelPetch
A bool is a value of 0 or 1 normally. EFLAGS is a 32-bit value. You need to convert the `eflags & (1<<9)` to a value of 1 or 0 or you would have to return a 32-bit type from your interrupt flag test routine (so a uint32_t rather than bool) but then that defeats the purpose of having a bool type.
And yes you need to initialize the IDT, use LIDT and THEN enable interrupts. If you use LIDT, enable interrupts and then initialize the interrupt table then you risk the chance of an interrupt occurring before you have set the interrupt handlers in the IDT and that would fault. So you might crash occasionally out of the blue but other times it would appear to work.
Re: When try to install GDT in GRUB, it does not call the ke
Posted: Fri Dec 06, 2019 3:23 am
by mrjbom
MichaelPetch wrote:And yes you need to initialize the IDT, use LIDT and THEN enable interrupts. If you use LIDT, enable interrupts and then initialize the interrupt table then you risk the chance of an interrupt occurring before you have set the interrupt handlers in the IDT and that would fault. So you might crash occasionally out of the blue but other times it would appear to work.
I am currently initializing IDT with
idt_init(). Then I have to configure LIDT with
lidt(), but I don't know what parameters it takes. I tried using it like this:
lidt(IDT, sizeof(IDT)), is that right?
After that the interrupts will fire as I assume?
Will
irq1_handler() be called if I press a key?