OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 10:51 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 54 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: IDT Help
PostPosted: Thu Mar 11, 2021 11:22 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
Well yes, but actually no. The loop sets the entries to the same handler. If you use it for the entire IDT, every interrupt/exception/IRQ will call the same code. Since you're in a very early stage, you can set the exception entries (0-31) to the same handler. However, as I said before, you will need to give each interrupt its own handler at some point. But for now, setting all the exceptions (only exceptions, not IRQs) to a dummy handler that just hangs is fine.

Alright, I think I'm starting to understand it more. So basically in the IDT label I need to define 32 exceptions, 16 IRQs, and then the pointer? The loop has a counter of 48, so it sets all 32 exceptions and 16 IRQs to the same handler. But only the exceptions can have the same handler (for now, later that has to be changed)? So I should change the counter to 32, and then add code to set each of the 16 IRQs to a different handler? What should that handlers for the IRQs do? Also, should I call the loop after I load the IDT or before?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 12:20 am 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
isaiah0311 wrote:
Alright, I think I'm starting to understand it more. So basically in the IDT label I need to define 32 exceptions, 16 IRQs, and then the pointer? The loop has a counter of 48, so it sets all 32 exceptions and 16 IRQs to the same handler. But only the exceptions can have the same handler (for now, later that has to be changed)? So I should change the counter to 32, and then add code to set each of the 16 IRQs to a different handler?

Exactly.
isaiah0311 wrote:
What should that handlers for the IRQs do?

The only thing that is common among IRQ handlers is that they send EOI (End Of Interrupt, you can read more about it here). Besides that, each IRQ handler is built to communicate with different hardware. Since you started this topic saying that you want to get keyboard input, I'll use it as an example. The keyboard uses IRQ1 (interrupt 33), and the handler would probably read from the keyboard and save the input somewhere. You can set the IRQs you don't use/support to a dummy handler that sends EOI and returns.
isaiah0311 wrote:
Also, should I call the loop after I load the IDT or before?

Before. Loading an empty/corrupt IDT is like not having an IDT.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 10:36 am 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
So here is the current main64.asm file. I'm still getting issues when I enable interrupts. If I don't enable interrupts it freezes before loading the kernel which is a new issue.

Code:
global long_mode_start
extern gdt.data
extern kernel_main

section .text
bits 64
long_mode_start:
   mov ax, gdt.data
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax

   call map_entries
   lidt [idt.pointer]
   sti
   
   call kernel_main
   mov rax, 60
   mov rdi, 2
   syscall

map_entries:
   mov rbx, idt
.map_exceptions:
   mov rdx, 0
   mov rax, exception_handler
   mov rcx, 32
   jmp .loop
.map_irqs_pic1:
   mov rdx, 1
   mov rax, isr_handler.pic1
   mov rcx, 8
   jmp .loop
.map_irqs_pic2:
   mov rdx, 2
   mov rax, isr_handler.pic2
   mov rcx, 8
.loop:
   mov word [rbx], ax
   shr rax, 16
   mov word [rbx + 6], ax
   shr rax, 16
   mov dword [rbx + 8], eax
   add rbx, 16
   dec rcx
   jne .loop

   test rdx, 0
   je .map_irqs_pic1
   
   test rdx, 1
   je .map_irqs_pic2
   ret

idt:
.exception_0:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
; --------------------------------
; exception_1 - 30
; --------------------------------
.exception_31:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
.irq_0:
   dw 0
   dw 0x8
   db 0
   db 10001110b
   dw 0
   dd 0
   dd 0
; --------------------------------
; irq_1 - 14
; --------------------------------
.irq_15:
        dw 0
        dw 0x8
        db 0
        db 10001110b
        dw 0
        dd 0
        dd 0
.pointer:
        dw $ - idt - 1
        dq idt

exception_handler:
   jmp $

isr_handler:
.pic1:
   mov ax, 0x20
   out 0x20, ax
   iretq
.pic2:
   mov ax, 0x20
   out 0xa0, ax
   iretq


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 10:50 am 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
What is gdt.data? Is it a selector, or is it the data descriptor in your GDT?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:01 am 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
What is gdt.data? Is it a selector, or is it the data descriptor in your GDT?

It's the data descriptor. I used the example in the wiki.
Code:
section .rodata
gdt:
.null: equ $ - gdt
        dw 0xffff
        dw 0
        db 0
        db 0
        db 1
        db 0
.code: equ $ - gdt
        dw 0
        dw 0
        db 0
        db 10011010b
        db 10101111b
        db 0
.data: equ $ - gdt
        dw 0
        dw 0
        db 0
        db 10010010b
        db 00000000b
        db 0
.pointer:
        dw $ - gdt - 1
        dq gdt


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:24 am 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
You need to set the data segment registers to the data selector, not descriptor.
Also, I don't think that your code descriptor is valid. I set the 7th byte (10101111b in your code) to 00100000b.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:47 am 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
You need to set the data segment registers to the data selector, not descriptor.
Also, I don't think that your code descriptor is valid. I set the 7th byte (10101111b in your code) to 00100000b.

I changed the byte to 00100000b and the data segment registers to 0x10 again. The OS still didn't boot.
I checked the wiki. The comment next to 10101111b is: granularity, 64 bits flag, limit19:16.
It also labels the .data as the descriptor and then loads gdt.data into the segment registers.
Is it valid both ways, or is the wiki wrong?
Here is the link.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 11:59 am 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
isaiah0311 wrote:
The comment next to 10101111b is: granularity, 64 bits flag, limit19:16.

AMD's manual says that granularity and limit are ignored, so I guess it's fine. Also, I didn't notice that, but I think 'equ $ - gdt' sets the labels to the selectors (so you can do 'mov ax,gdt.data'). Anyway, I think it's clearer to use the selector itself.
isaiah0311 wrote:
The OS still didn't boot.

What happens? Exception? Triple fault? It just hangs?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 12:11 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
What happens? Exception? Triple fault? It just hangs?

It just hangs.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 1:08 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
Update: It works... sort of?

The issue was in the loop where I map the IDT entries to the handler functions.
The new loop is this:
Code:
map_entries:
   mov rbx, idt
.map_exceptions:
   mov rdx, 0
   mov rax, exception_handler
   mov rcx, 32
   jmp .loop
.map_irqs_pic1:
   mov rdx, 1
   mov rax, isr_handler.pic1
   mov rcx, 8
   jmp .loop
.map_irqs_pic2:
   mov rdx, 2
   mov rax, isr_handler.pic2
   mov rcx, 8
.loop:
   mov word [rbx], ax
   shr rax, 16
   mov word [rbx + 6], ax
   shr rax, 16
   mov dword [rbx + 8], eax
   add rbx, 16
   dec rcx
   jne .loop

   test rdx, rdx
   je .map_irqs_pic1
   
   dec rdx
   test rdx, rdx
   je .map_irqs_pic2
   ret


It now boots into the OS even with interrupts enabled. The issue I have now is when I press a key, it reboots.
Here is how the IRQs are handled:
Code:
isr_handler:
.pic1
   mov ax, 0x20
   out 0x20, ax
   iretq
.pic2
   mov ax, 0x20
   out 0xa0, ax
   iretq

I know this won't read the keyboard input, but I didn't except it to cause a reboot. I figured it would just do nothing.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 9:12 pm 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
Wow. You know what I've just noticed? rax is not being set up properly after each loop iteration! I just shoved the code into a loop, and I overlooked that… To fix it, you need to use another register, and set rax to that register at the start of the loop. I'm thinking about something like:
Code:
.loop:
   mov rax, r8 ; r8 is the additional register
   mov word [rbx], ax
   shr rax, 16
   mov word [rbx + 6], ax
   shr rax, 16
   mov dword [rbx + 8], eax
   add rbx, 16
   dec rcx
   jne .loop

And then in the rest of your map_entries function, just change rax to r8.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 9:23 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
Wow. You know what I've just noticed? rax is not being set up properly after each loop iteration! I just shoved the code into a loop, and I overlooked that… To fix it, you need to use another register, and set rax to that register at the start of the loop. I'm thinking about something like:
Code:
.loop:
   mov rax, r8 ; r8 is the additional register
   mov word [rbx], ax
   shr rax, 16
   mov word [rbx + 6], ax
   shr rax, 16
   mov dword [rbx + 8], eax
   add rbx, 16
   dec rcx
   jne .loop

And then in the rest of your map_entries function, just change rax to r8.

It works! Interrupts are enabled and it doesn't crash, even when I press a key.
So now the next step would be to assign the keyboard IRQ a handler of its own?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 9:26 pm 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
I'm glad it works! And yes, now you need to give the keyboard its own handler.


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 9:44 pm 
Offline
Member
Member

Joined: Tue Mar 09, 2021 9:31 pm
Posts: 25
SKC wrote:
And yes, now you need to give the keyboard its own handler.

So how do I go about accessing the data for which key is pressed? After that can I just store it in RAX and then call a C function?


Top
 Profile  
 
 Post subject: Re: IDT Help
PostPosted: Fri Mar 12, 2021 10:00 pm 
Offline
Member
Member

Joined: Thu Feb 18, 2021 3:07 am
Posts: 28
isaiah0311 wrote:
So how do I go about accessing the data for which key is pressed?

Read this.
isaiah0311 wrote:
After that can I just store it in RAX and then call a C function?

And this.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 54 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 74 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