Autor Thema: PM Switch  (Gelesen 2876 mal)

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« am: 01. January 2006, 23:09 »
Hm, ich habe hier ein kleines Problem mit dem einschalten des PMs. Der folgende Code wird an 0x1000 geladen, und dann an 0x100:0 ausgeführt.
Ich habe Probleme mit dem FAR JMP zum leeren der pipeline. Wie muss des aussehen?

Bochs gibt bei meinen jetztigen Code aus:
00007911925e[CPU1 ] jump_protected: gate type 0 unsupported
00007911925e[CPU1 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting


[bits 16]
[org 0]
aprm_boot:
; zum code springen
jmp aprm_code

; die configtable fängt an 0x8 an
times 8-($-$$) db 0

; die felder hier werden vom kernel eingetragen (dieser code hier bootet die prozessoren in einem SMP system, prozessor0 ist schon im pm und trägt hier die entsprechenden werte ein.)
aprm_config:
; protected mode code entry
dd 0

aprm_code:
; interrupts ausschalten bis wir eine IDT haben usw.
cli

; GDT laden
lgdt [aprm_gdtdesc]

; pm einschalten
mov eax, cr0
or eax, 0x1
mov cr0, eax

; pipeline flushen (kann das nasm auch ohne diese umständliche codierung?)
db 0xEA
dw 0x1000 + aprm_flush
dw 0x8

[bits 32]
aprm_flush:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ebx, [aprm_config]
jmp ebx

aprm_gdt:
; null descriptor
dd 0
dd 0

; kernel code
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0

; kernel data
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

aprm_gdtdesc:
; gdt descriptor
dw aprm_gdtdesc - aprm_gdt - 1
dd aprm_gdt

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. January 2006, 12:53 »
Mir scheint, dass etwas am Codesegment-Deskriptor nicht stimmt. Ist wahrscheinlich versehentlich ein Gate-Deskriptor. Wo tritt der Fehler auf?

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. January 2006, 13:03 »
Ah, ich habe den Fehler gerade gefunden^^.
Nach dem PM Switch stimmen die Addressen nicht mehr, da ich ja org 0 angegeben hatte und CS auf 0x100 gesetzt hatte. Im PM ist die Codesegment-Basis ja anders und daher waren die Addressen falsch. So funktioniert es:
[bits 16]
[org 0x1000]

aprm_boot:
; jump to the code
jmp 0x0:aprm_code

; config table starts at 0x8
times 8-($-$$) db 0

; the config table will be filled by the kernel
aprm_config:
; protected mode entry
dd 0

aprm_code:
; disable interrupts
cli

; load gdt
lgdt [aprm_gdtdesc]

; switch to protected mode
mov eax, cr0
or eax, 0x1
mov cr0, eax

; flush pipeline
jmp 0x8:aprm_flush

[bits 32]
aprm_flush:
mov ax, 0x10
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ebx, [aprm_config]
jmp ebx

aprm_gdt:
; null descriptor
dd 0
dd 0

; kernel code
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0

; kernel data
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

aprm_gdtdesc:
; gdt descriptor
dw aprm_gdtdesc - aprm_gdt - 1

 

Einloggen