Autor Thema: Jump an falsche Addresse nach switch zu Protected Mode  (Gelesen 3227 mal)

openglfreak

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« am: 29. December 2014, 01:32 »
Ich habe versucht einen bootloader zu programmieren, doch der Sprung nach dem aktivieren des Protected Mode führt an Adresse 0xB866, obwohl er da nicht hin soll :-(.

Ich hab' den code bereits gefühlte 10000h mal gecheckt doch habe keinen Fehler gefunden :? :cry:

Wo ist der Fehler? :x

(Compiliert mit nasm, debuggt mit bochs und gdb)

[global main16]

[section .text]

[BITS 16]
main16:
cli

mov byte [bootdrive],dl

xor ax,ax
mov ds,ax
mov ss,ax
mov ebp,(main32-0xFF)
mov esp,(main32-0x01)

initdrive:
xor ah,ah
int 0x13
jc error16

load:
mov byte dl,[bootdrive]
mov ah,0x02
mov al,nsectors
xor dh,dh
xor ch,ch
mov cl,0x02
mov bx,(main32>>0x04)
mov es,bx
mov bx,(main32&0x0F)
int 0x13
jc error16


initgdt:
mov ecx,(gdt_template_end-gdt_template)
copytemplate:
dec ecx
mov byte bl,[gdt_template+ecx]
mov byte [gdt_start+ecx],bl
test ecx,ecx
jnz copytemplate
initgdtr:
mov word [gdtr],(gdt_template_end-gdt_template-1)
%line 20+1 loader.asm
lgdt [gdtr]
jmp switchpmode


error16:
jmp $


switchpmode:
mov eax,cr0
or eax,0x01
mov cr0,eax
%line 27+1 loader.asm
mov ax,codeseg
mov es,ax
jmp [es:b32]


[Bits 32]
b32:
mov ax,dataseg
mov ds,ax
mov ss,ax
mov ebp,(main32-0xFF)
mov esp,(main32-0x01)
jmp $
;Some stuff + jumping to main32


nsectors equ 0x08
main32 equ (0x10000-(nsectors*0x0200))

bootdrive equ 0x7BFF
gdt_start equ 0x9000
gdt_end equ 0xB000


gdtr:
dw gdt_end-gdt_start-1
dd gdt_start

gdt_template:
nullseg equ 0
dd 0x00000000, 0x00000000

codeseg equ $-gdt_template
dw 0xFFFF
dw 0x0000
db 0x00
db 0x9A
db 0xCF
db 0x00

dataseg equ $-gdt_template
dw 0xFFFF
dw 0x0000
db 0x00
db 0x92
db 0xCF
db 0x00

gdt_template_end:


times (0x01FE)-($-$$) db 0x00
db 0x55
db 0xAA

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 29. December 2014, 02:44 »
Moin!

jmp [es:b32]


[Bits 32]
b32:
mov ax,dataseg

Das mov ax,dataseg wird zu irgendwas assembliert, das mit den Bytes 0x66, 0xB8, ... beginnt. Der Sprung jmp [es:b32] ist ein indirekter Sprung, das heißt er liest den Speicher an Adresse b32 aus, anstatt nach b32 zu springen. Dort steht die eben genannte Instruktion, die als Adresse interpretiert wird, wodurch die CPU bei 0xB866 landet. (x86 ist Little Endian, deswegen sind die vertauscht.)

Bei einem far-jump kannst du kein Segmentregister angeben. Entweder du kodierst die Adresse hart, vermutlich sowas wie jmp 0x08:(0x7c00 + b32), falls der Assembler das schluckt Oder du machst das über den Stack:
push es
push b32 + 0x7c00
retf

Das 0x7c00 musst du vermutlich addieren, weil du annimmst, dass der Bootloader an Offset 0 (in Segment 0x7c0), geladen wird (statt 0x7c00 in Segment 0). (Das erkenne ich daran, dass du die ORG-Instruktion weggelassen hast, wodurch ORG 0 impliziert ist.) Übrigens heißt das auch, dass du beispielsweise die Variable bootdrive bei "load:" nicht korrekt ausliest, nachdem du ds auf 0 gesetzt hast. Vermutlich wird dadurch auch der restliche Code nicht funktionieren. Ich kann natürlich eine ewige Ausführung über Speicheradressierung im Real Mode schreiben, falls du das benötigst, aber ich würde vorschlagen du schlägst erstmal im NASM-Handbuch die ORG-Instruktion nach, und machst dir dann Gedanken, ob 1. du, 2. der Assembler, 3. die CPU alle dieselbe Vorstellung von dem Inhalt der Segmentregister haben, und ob diese korrekt ist.
Dieser Text wird unter jedem Beitrag angezeigt.

openglfreak

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 29. December 2014, 16:08 »
Danke, das mit dem push und retf funktioniert (Das andere ist mir nicht so sympathisch).
Allerdings brauche ich das ORG 0x7C00 nicht, denn ich compiliere mit
nasm -f elf -g -o loader.o loader.asmerstmal zu einer elf-i386 und dann mit
ld -melf_i386 -A i386 --oformat binary -o loader.bin loader.o -Ttext=0x7C00 -e main16zu einer binary. Dadurch habe ich auch gleich die debug-infos.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 29. December 2014, 18:24 »
Ah ich verstehe. Das sieht man auch nicht so oft.
Dieser Text wird unter jedem Beitrag angezeigt.

 

Einloggen