Page 4 of 4

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:12 pm
by Octocontrabass
Where does it say that?

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:14 pm
by austanss

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:37 pm
by austanss
I get an error in assembling this:

Code: Select all

loadGDT64:
	push rax
	push rbx
	lgdt [GDT64.Pointer]        ; Load the new GDT pointer
	mov ax, 0x10
	shl ax, 3
	mov ds, ax
	mov es, ax
   	mov fs, ax
   	mov gs, ax
   	mov ss, ax
	pop rbx
	pop rax
	jmp 0x08:.ret

	.ret:
		ret
Error at the far jump, says not supported in 64-bit mode
[NASM btw]

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:42 pm
by Octocontrabass
rizxt wrote:https://www.amd.com/system/files/TechDocs/24593.pdf page 130
I don't see anything on that page that says the offset is 8 bits.
rizxt wrote:Error at the far jump, says not supported in 64-bit mode
That instruction doesn't exist in 64-bit mode. If you want to use JMP, you have to use an indirect JMP like my example code. (Or you could try using CALL or RET instead.)

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:48 pm
by austanss
I gotta go to sleep, but the indirect jump is causing a fault:

Code: Select all

global loadGDT64
global GDT64

loadGDT64:
	push rax
	lgdt [GDT64.Pointer]        ; Load the new GDT pointer
	mov ax, 0x10
	mov ds, ax
	mov es, ax
   	mov fs, ax
   	mov gs, ax
   	mov ss, ax
	pop rax
	jmp far [cs_ptr]

	.ret:
		ret


GDT64:                           ; Global Descriptor Table (64-bit).
    .Null: equ $ - GDT64         ; The null descriptor.
    dw 0xFFFF                    ; Limit (low).
    dw 0                         ; Base (low).
    db 0                         ; Base (middle)
    db 0                         ; Access.
    db 1                         ; Granularity.
    db 0                         ; Base (high).
    .Code: equ $ - GDT64         ; The code descriptor.
    dw 0                         ; Limit (low).
    dw 0                         ; Base (low).
    db 0                         ; Base (middle)
    db 10011010b                 ; Access (exec/read).
    db 10101111b                 ; Granularity, 64 bits flag, limit19:16.
    db 0                         ; Base (high).
    .Data: equ $ - GDT64         ; The data descriptor.
    dw 0                         ; Limit (low).
    dw 0                         ; Base (low).
    db 0                         ; Base (middle)
    db 10010010b                 ; Access (read/write).
    db 00000000b                 ; Granularity.
    db 0                         ; Base (high).
    .Pointer:                    ; The GDT-pointer.
    dw $ - GDT64 - 1             ; Limit.
    dq GDT64                     ; Base.

cs_ptr:
	dq loadGDT64.ret
	dw 0x10

Re: converting 32-bit IDT to 64-bit IDT

Posted: Tue Dec 01, 2020 11:55 pm
by Octocontrabass
The fault is because you can't load a data segment into CS.

Re: converting 32-bit IDT to 64-bit IDT

Posted: Wed Dec 02, 2020 8:05 am
by austanss
oh oops didn't mean to do that

Re: converting 32-bit IDT to 64-bit IDT

Posted: Wed Dec 02, 2020 8:14 am
by austanss
Aight so it still faults, but I figured something out. I switched my disassembler from ndisasm to objdump, and the address at RIP points to the IRETQ instruction of the IRQ handler, which leaves me to investigate a possible stack error.

Re: converting 32-bit IDT to 64-bit IDT

Posted: Wed Dec 02, 2020 8:44 am
by austanss
The IRQs push a value in place of the error code corresponding to their IRQ number.

pusha/popa macros:

Code: Select all

%macro pusha 0
    push rax
    push rcx
    push rdx
    push rbx
    push rbp
    push rsi
    push rdi
%endmacro

%macro popa 0
    pop rdi
    pop rsi
    pop rbp
    pop rbx
    pop rdx
    pop rcx
    pop rax
%endmacro
Also, haven't seen you in a while, Michael.

Anyway, I identified a potential issue where I was pushing bytes before jumping to the common stub, yet at the end I add 8 to rsp to cover those up, therefore corrupting the stack and faulting when IRETQ pops values off the stack.

Re: converting 32-bit IDT to 64-bit IDT

Posted: Wed Dec 02, 2020 8:47 am
by austanss
And just like that, I fixed the issue.

I changed the values to push as 64 bits long, and then added 16 to rsp instead of 8.

SOLVED.

Re: [SOLVED] converting 32-bit IDT to 64-bit IDT

Posted: Wed Dec 02, 2020 11:23 am
by austanss
With all this newfound knowledge, I feel it is my sworn duty to edit the wiki and add some of this important information.