OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Dec 06, 2019 6:37 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: When try to install GDT in GRUB, it does not call the kernel
PostPosted: Tue Dec 03, 2019 12:30 pm 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
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.


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Tue Dec 03, 2019 2:13 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1697
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.


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Tue Dec 03, 2019 2:32 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3589
Location: Chichester, UK
Do you think it is wise to enable interrupts before installing an IDT and some interrupt handlers?


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Wed Dec 04, 2019 2:57 pm 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
iansjack wrote:
Do you think it is wise to enable interrupts before installing an IDT and some interrupt handlers?


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.


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?


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 8:54 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 498
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:
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:
Code:
  cli
  hlt
If you wish to keep them enabled you'd have to do something like:
Code:
.hltloop:
  hlt
  jmp .hltloop


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 12:12 pm 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
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?


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 3:16 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 498
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:
Code:
return !!(flags & (1 << 9));
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.


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 3:53 pm 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
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:
Code:
return !!(flags & (1 << 9));
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.


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 4:52 pm 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
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?


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Thu Dec 05, 2019 6:53 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 498
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.


Top
 Profile  
 
 Post subject: Re: When try to install GDT in GRUB, it does not call the ke
PostPosted: Fri Dec 06, 2019 3:23 am 
Offline
Member
Member

Joined: Sun Jul 21, 2019 7:34 am
Posts: 50
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?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 21 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group