Strange long mode fault on real computer
Posted: Wed Mar 25, 2009 1:50 pm
Hey guys!
I'm having a strange bug in my system and I decided to ask you.
I've written a bootloader which enters protected mode (without paging), copies my Kernel to 0x00400000, enables the long mode after setting up PML4 and jumps to 00400000 where my Kernel is located. Everything works good till here.
But now I've a very strange problem. In virtual machines on Vmware Workstation, Vmware Fusion and Microsoft Hyper-V everything work as it should (Interrupts, Kernel and so on), but my real computer reboots directly after the first call instruction in my kernel and I dont know why. No exception, just a reboot.
So I decided to wirte a simple "test-kernel" to explorer this bug and I found out that the following code works perfectly on the real machine:
But simple code like this causes a direct reboot:
The strange thing is that on emulated machines both codes are working as they should. Also my regular non "test-kernel" works as it should on emulated machines.
It's very difficult to locate the problem if my real machine just reboots. Because of this I decieded to show you my PML4, long mode GDT and long mode IDT. Maybe there is a problem I've not found.
PML4 Code:
long mode GDT code:
long mode IDT:
That's it. Mabe one of you have a clue what's going wrong.
Thank you very much for your support
I'm having a strange bug in my system and I decided to ask you.
I've written a bootloader which enters protected mode (without paging), copies my Kernel to 0x00400000, enables the long mode after setting up PML4 and jumps to 00400000 where my Kernel is located. Everything works good till here.
But now I've a very strange problem. In virtual machines on Vmware Workstation, Vmware Fusion and Microsoft Hyper-V everything work as it should (Interrupts, Kernel and so on), but my real computer reboots directly after the first call instruction in my kernel and I dont know why. No exception, just a reboot.
So I decided to wirte a simple "test-kernel" to explorer this bug and I found out that the following code works perfectly on the real machine:
Code: Select all
[BITS 64]
[ORG 0x0000000000400000]
; configuration data for my os
mov dword [0x0000000000100000], 0x000B88C0
mov byte [0x000000000010000C], 0x07
mov byte [0x000000000010000D], 0x03
mov byte [0x0000000000800000], 0x00
mov r10, 0x0000000000000000
test_1:
hlt
jmp test_1
Code: Select all
[BITS 64]
[ORG 0x0000000000400000]
; configuration data for my os
mov dword [0x0000000000100000], 0x000B88C0
mov byte [0x000000000010000C], 0x07
mov byte [0x000000000010000D], 0x03
mov byte [0x0000000000800000], 0x00
mov r10, 0x0000000000000000
call make_terminal
test_1:
hlt
jmp test_1
make_terminal_x64:
mov r9, terminal
call print.line
mov dword ebx, [0x0000000000100000]
sub ebx, 0xA0
mov dword [0x0000000000100000], ebx
mov r10, 0x0000000000000004
mov al, 0xDB
mov cl, 0x87
call print.char.colored
ret
It's very difficult to locate the problem if my real machine just reboots. Because of this I decieded to show you my PML4, long mode GDT and long mode IDT. Maybe there is a problem I've not found.
PML4 Code:
Code: Select all
setup_PML4:
; *** Map the first 10 MB of memory ***
; PML4 located at 0x70000:
mov dword [0x70000], 0x71000 + 111b ; 1st PML4 Entry -> PDP table.
; PDP located at 0x71000:
mov dword [0x71000], 72000h + 111b ; 1st PDP Entry -> PD table.
; PD located at 0x72000:
mov dword [0x72000 + (8*0)], 0x73000 + 111b ; 1st PD Entry -> 0 MB
mov dword [0x72000 + (8*1)], 0x74000 + 111b ; 2nd PD Entry -> 2 MB
mov dword [0x72000 + (8*2)], 0x75000 + 111b ; 3rd PD Entry -> 4 MB
mov dword [0x72000 + (8*3)], 0x76000 + 111b ; 4th PD Entry -> 6 MB
mov dword [0x72000 + (8*4)], 0x77000 + 111b ; 5th PD Entry -> 8 MB
; address entry frame flags
mov edi,73000h ; address of first page table
mov eax,0 + 111b
mov ecx,512 ; number of pages to map (0-2 MB)
call make_page_entries
mov edi,0x74000
mov eax,0x200000 + 111b
mov ecx,512 ; number of pages to map (2-4 MB)
call make_page_entries
mov edi,0x75000
mov eax,0x400000 + 111b
mov ecx,512 ; number of pages to map (4-6 MB)
call make_page_entries
mov edi,0x76000
mov eax,0x600000 + 111b
mov ecx,512 ; number of pages to map (6-8 MB)
call make_page_entries
mov edi,0x77000
mov eax,0x800000 + 111b
mov ecx,512 ; number of pages to map (8-10 MB)
call make_page_entries
ret
make_page_entries:
stosd
add edi,4
add eax,1000h
loop make_page_entries
ret
Code: Select all
gdtr_x64: dw gdt_end_x64 - gdt_x64 - 1 ; GDT limit
dq gdt_x64 ; (GDT base gets set above)
gdt_x64:
dw 0
dw 0
db 0
db 0
db 0
db 0
LINEAR_SEL_X64 equ $-gdt_x64
dw 0xFFFF
dw 0x0000
db 0x00
db 10010010b
db 0xAF
db 0x00
SYS_CODE_SEL_X64 equ $-gdt_x64
gdt1_x64:
dw 0xFFFF
dw 0x0000
db 0x00
db 10011010b
db 0xAF
db 0x00
SYS_DATA_SEL_X64 equ $-gdt_x64
gdt2_x64:
dw 0xFFFF
dw 0x0000
db 0x00
db 10010010b
db 0xAF
db 0x00
gdt_end_x64:
Code: Select all
;*******************************************************************************************************
;* Interrupt Deskriptor Tabelle für den 64-Bit Modus von Project-K *
;* Teil von "Project-K" *
;* (c) 2007-2008 Sebastian Langer *
;*******************************************************************************************************
%macro mkirqring0_x64 2 ;make exception interrupt for ring 0 (operatingsystem)
dw %1 ;offset
dw %2 ;selector
db 0
db 10001110b
dw 0
dq 0
%endmacro
%macro mkirqring0_x641 2 ;make hardware interrupt for ring 0 (operatingsystem)
dw %1 ;offset
dw %2 ;selector
db 0
db 10001111b
dw 0
dq 0
%endmacro
;*************************************
;* Die IDT mit und ihre Deskriptoren *
;*************************************
start_of_idt_X64:
;*****************************
;* Interrupts für Exceptions *
;*****************************
mkirqring0_x64 IRQ_00h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_01h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_02h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_03h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_04h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_05h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_06h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_07h_x64,SYS_CODE_SEL_X64 ;Interrupt 07 fpu nicht installiert
mkirqring0_x64 IRQ_08h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_09h_x64,SYS_CODE_SEL_X64 ;Interrupt 09 fpu register?berlauf und keyboard events
mkirqring0_x64 IRQ_0ah_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0bh_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0ch_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0dh_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_0eh_x64,SYS_CODE_SEL_X64
dq 0 ;Reserviert
dq 0
mkirqring0_x64 IRQ_10h_x64,SYS_CODE_SEL_X64
mkirqring0_x64 IRQ_11h_x64,SYS_CODE_SEL_X64 ;
mkirqring0_x64 IRQ_12h_x64,SYS_CODE_SEL_X64 ;Machine-Check Exception (#MC)
mkirqring0_x64 IRQ_13h_x64,SYS_CODE_SEL_X64 ;SIMD Floating-Point Exception (#XM)
TIMES 24 dq 0 ;Reserviert
;*******************************
;* Interrupts für die Hardware *
;*******************************
mkirqring0_x641 IRQ_20h_x64,SYS_CODE_SEL_X64 ; Timer
mkirqring0_x641 IRQ_21h_x64,SYS_CODE_SEL_X64 ; Tastatur
mkirqring0_x641 IRQ_22h_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_23h_x64,SYS_CODE_SEL_X64 ; Com 2
mkirqring0_x641 IRQ_24h_x64,SYS_CODE_SEL_X64 ; Com 1
mkirqring0_x641 IRQ_25h_x64,SYS_CODE_SEL_X64 ; LPT 2
mkirqring0_x641 IRQ_26h_x64,SYS_CODE_SEL_X64 ; FDD
mkirqring0_x641 IRQ_27h_x64,SYS_CODE_SEL_X64 ; LPT 1
mkirqring0_x641 IRQ_28h_x64,SYS_CODE_SEL_X64 ; CMOS Real Time Clock
mkirqring0_x641 IRQ_29h_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_2ah_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_2bh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_2ch_x64,SYS_CODE_SEL_X64 ; PS / 2 Maus (u.U.)
mkirqring0_x641 IRQ_2dh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_2eh_x64,SYS_CODE_SEL_X64 ; unbenutzt
mkirqring0_x641 IRQ_2fh_x64,SYS_CODE_SEL_X64 ; unbenutzt
;*********************************
;* Interrupts für die System API *
;*********************************
mkirqring0_x641 IRQ_30h_x64,SYS_CODE_SEL_X64
end_of_idt_X64:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; now for the IDT pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
idt_pointer_X64:
dw end_of_idt_X64 - start_of_idt_X64 - 1
dq start_of_idt_X64
IRQ_00h_x64:
call make_bluescreen_x64
call handle_irq00_x64
cli
hlt
IRQ_01h_x64:
call make_bluescreen_x64
call handle_irq01_x64
cli
hlt
IRQ_02h_x64:
call make_bluescreen_x64
call handle_irq02_x64
cli
hlt
IRQ_03h_x64:
call make_bluescreen_x64
call handle_irq03_x64
cli
hlt
IRQ_04h_x64:
call make_bluescreen_x64
call handle_irq04_x64
cli
hlt
IRQ_05h_x64:
call make_bluescreen_x64
call handle_irq05_x64
cli
hlt
IRQ_06h_x64:
call make_bluescreen_x64
call handle_irq06_x64
cli
hlt
IRQ_07h_x64:
call make_bluescreen_x64
call handle_irq07_x64
cli
hlt
IRQ_08h_x64:
call make_bluescreen_x64
call handle_irq08_x64
cli
hlt
IRQ_09h_x64:
call make_bluescreen_x64
call handle_irq09_x64
cli
hlt
IRQ_0ah_x64:
call make_bluescreen_x64
call handle_irq0A_x64
cli
hlt
IRQ_0bh_x64:
call make_bluescreen_x64
call handle_irq0B_x64
cli
hlt
IRQ_0ch_x64:
call make_bluescreen_x64
call handle_irq0C_x64
cli
hlt
IRQ_0dh_x64:
call make_bluescreen_x64
call handle_irq0D_x64
cli
hlt
IRQ_0eh_x64:
call make_bluescreen_x64
call handle_irq0E_x64
cli
hlt
IRQ_10h_x64:
call make_bluescreen_x64
call handle_irq10_x64
cli
hlt
IRQ_11h_x64:
call make_bluescreen_x64
call handle_irq11_x64
cli
hlt
IRQ_12h_x64:
call make_bluescreen_x64
call handle_irq12_x64
cli
hlt
IRQ_13h_x64:
call make_bluescreen_x64
call handle_irq13_x64
cli
hlt
IRQ_20h_x64:
mov [s_rax_0x20], rax
mov [s_rbx_0x20], rbx
mov [s_rcx_0x20], rcx
mov [s_rdx_0x20], rdx
call 0x0000000000200000 ;location of handler code
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
mov rax, [s_rax_0x20]
mov rbx, [s_rbx_0x20]
mov rcx, [s_rcx_0x20]
mov rdx, [s_rdx_0x20]
iretq
IRQ_21h_x64:
mov [s_rax_0x21], rax
mov [s_rbx_0x21], rbx
mov [s_rcx_0x21], rcx
mov [s_rdx_0x21], rdx
call 0x0000000000300000 ;location of keyboard driver
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
mov rax, [s_rax_0x21]
mov rbx, [s_rbx_0x21]
mov rcx, [s_rcx_0x21]
mov rdx, [s_rdx_0x21]
iretq
IRQ_22h_x64:
mov byte [0xB8964], '3'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_23h_x64:
mov byte [0xB8966], '4'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_24h_x64:
mov byte [0xB8968], '5'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_25h_x64:
mov byte [0xB896A], '6'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_26h_x64:
mov byte [0xB896C], '7'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_27h_x64:
mov byte [0xB896E], '8'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_28h_x64:
mov byte [0xB8970], '9'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_29h_x64:
mov byte [0xB8972], 'A'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iret
IRQ_2ah_x64:
mov byte [0xB8974], 'B'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_2bh_x64:
mov byte [0xB8976], 'C'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_2ch_x64:
mov byte [0xB8978], 'D'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_2dh_x64:
mov byte [0xB897A], 'E'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_2eh_x64:
mov byte [0xB897C], 'F'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_2fh_x64:
mov byte [0xB897E], 'G'
mov al,20H ;send End-Of-Interrupt signal
out 20H,al
iretq
IRQ_30h_x64: ; screen and text interactions
mov [s_rax_0x30], rax
mov [s_rbx_0x30], rbx
mov [s_rcx_0x30], rcx
mov [s_rdx_0x30], rdx
call 0x000000000020063D
mov rax, [s_rax_0x30]
mov rbx, [s_rbx_0x30]
mov rcx, [s_rcx_0x30]
mov rdx, [s_rdx_0x30]
iretq
s_rax_0x20 dq 0
s_rbx_0x20 dq 0
s_rcx_0x20 dq 0
s_rdx_0x20 dq 0
s_rax_0x21 dq 0
s_rbx_0x21 dq 0
s_rcx_0x21 dq 0
s_rdx_0x21 dq 0
s_rax_0x30 dq 0
s_rbx_0x30 dq 0
s_rcx_0x30 dq 0
s_rdx_0x30 dq 0
%include "./system/x64/basic/bluescreen.inc"
%include "./system/x64/basic/IRQs/00.inc"
%include "./system/x64/basic/IRQs/01.inc"
%include "./system/x64/basic/IRQs/02.inc"
%include "./system/x64/basic/IRQs/03.inc"
%include "./system/x64/basic/IRQs/04.inc"
%include "./system/x64/basic/IRQs/05.inc"
%include "./system/x64/basic/IRQs/06.inc"
%include "./system/x64/basic/IRQs/07.inc"
%include "./system/x64/basic/IRQs/08.inc"
%include "./system/x64/basic/IRQs/09.inc"
%include "./system/x64/basic/IRQs/0A.inc"
%include "./system/x64/basic/IRQs/0B.inc"
%include "./system/x64/basic/IRQs/0C.inc"
%include "./system/x64/basic/IRQs/0D.inc"
%include "./system/x64/basic/IRQs/0E.inc"
%include "./system/x64/basic/IRQs/10.inc"
%include "./system/x64/basic/IRQs/11.inc"
%include "./system/x64/basic/IRQs/12.inc"
%include "./system/x64/basic/IRQs/13.inc"
Thank you very much for your support