Autor Thema: APM protected mode  (Gelesen 2980 mal)

Thylon

  • Beiträge: 1
    • Profil anzeigen
Gespeichert
« am: 30. March 2010, 13:50 »
Also durch die Specifikation http://www.microsoft.com/whdc/archive/amp_12.mspx zu APM und die Dokumentation der MUltibootstruktur im Wiki(http://lowlevel.brainsware.org/wiki/index.php/Multiboot) habe ich entdeckt, dass man APM auch im Protected Mode nutzen kann.

Danke der HIlfe von bluecode und kwolf im IRC   :) habe ich herausgefunden, dass man 3 Deskriptoren in der GDT richtig anlegen muss:

        gdt_set_descriptor_byte_granularity(5, size_cseg, base_cseg, GDT_SEGMENT | GDT_PRESENT | GDT_CODESEG, 0);
gdt_set_descriptor_byte_granularity(6, size_cseg16, base_cseg16, GDT_SEGMENT | GDT_PRESENT | GDT_CODESEG, 0);
gdt_set_descriptor_byte_granularity(7, size_dseg, base_dseg, GDT_SEGMENT | GDT_PRESENT | GDT_DATASEG, 0);
So lege ich die Benötigten Deskriptoren an, die auch geladen werden.
Trotzdem lässt ein Aufruf von :
asm("mov $0x28,%%ax;mov %%ax,%%cs; xor %%eax,%%eax;movb $0x53, %%ah;movb $0x08, %%al;xor %%ebx,%%ebx;mov 0x0001,%%bx;mov 0x0001,%%cx;call %%cs:%1;jc Fehler;mov $0x01,%0;jmp done;Fehler:;mov $0x02,%0;done:;" :"=a" (ok): "m"(multiboot_struct->mi_apm->offset));
Die virtuelle Maschiene neustarten. :?
Hat jemand noch einen Tipp für mich?

Danke schon im Vorraus.

Gruß
Thylôn


Edit
der Fehler hat sich erledigt.
Jetzt wird die APM-Funktion (hoffentlich) aufgerufen:

asm("call apm": : "a"(multiboot_struct->mi_apm->offset));
Die APM-Funktion mach folgendes:

apm:
pusha
mov edx,eax
xor eax,eax
mov ah,0x53
mov al,0x08
xor ebx,ebx
mov bx,0x0001
mov cx,bx
;call 0x28:[edx]
push dword cs
push dword after
push dword 0x28
push dword edx
                retf
after:

popa
ret

Jetzt gibt es eine Expection. Unter Bochs ein #GP und unter qemu ein #UD
Meine Frage mache ich sichtbar etwas falsch? :?

Unter bochs nach dem "far call" http://pastebin.com/JJjyBv3q

Gruß Thylôn
« Letzte Änderung: 31. March 2010, 12:03 von Thylôn »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 30. March 2010, 14:11 »
Du musst bei dem Call den richtigen Codesegmentselektor angeben. cs ist ja das momentane Codesegemnt, du möchtest aber in das neu erstellte springen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #2 am: 30. March 2010, 14:29 »
Ich bezweifle auch, dass
Zitat von: Thylôn
mov %%ax,%%cs
funktioniert (im Übrigen frage ich mich, woher das alle haben :-D).

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 30. March 2010, 14:30 »
Und ich hatte noch geschaut und es (in dem Einzeilerwust) nicht gefunden :-D
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 30. March 2010, 20:00 »
Hallo,


call %%cs:%1;
Der call müsste IMHO eher "call APM_CODE_SELECTOR:APM_CODE_OFFSET" lauten, in diesem Fall wohl "call 0x28:??". Das was schon in CS drin ist wird wohl nicht viel nützen und vorher, per mov, was anderes in CS reinschreiben ist eben kein call sondern führt ins Nirwana.
Oder hab ich da was falsch verstanden?


Grüße
Erik

PS: Eine etwas augenfreundlichere Formatierung ist auch bei Assembler möglich!
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 30. March 2010, 21:13 »
per mov, was anderes in CS reinschreiben ist eben kein call sondern führt ins Nirwana.
Nur, wenn der Handler für #UD im Nirvana ist. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen