When try to install GDT in GRUB, it does not call the kernel
When try to install GDT in GRUB, it does not call the kernel
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.
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.
-
- Member
- Posts: 5580
- Joined: Mon Mar 25, 2013 7:01 pm
Re: When try to install GDT in GRUB, it does not call the ke
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.
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
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
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?Octocontrabass wrote: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.
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: When try to install GDT in GRUB, it does not call the ke
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:
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:
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:
Code: Select all
cli
hlt
Code: Select all
.hltloop:
hlt
jmp .hltloop
Re: When try to install GDT in GRUB, it does not call the ke
Okay, now I'm not getting a critical error. But the interrupts still don't work.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.
I get false from are_interrupts_enabled().
Did I forget to do something?
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: When try to install GDT in GRUB, it does not call the ke
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.
Code: Select all
return !!(flags & (1 << 9));
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
How would it be more correct to declare bool to avoid such problems?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..Code: Select all
return !!(flags & (1 << 9));
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?
Understood, in the future I will compile like this.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.
Re: When try to install GDT in GRUB, it does not call the ke
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?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;`
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: When try to install GDT in GRUB, it does not call the ke
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.
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
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?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.
After that the interrupts will fire as I assume?
Will irq1_handler() be called if I press a key?