Welchen Wert bei Initialisierung für Code- und Datensegmente bei VM86 Task?
-
Hallo zusammen,
EHCI hat erstmal Pause
Mein Multitasking läuft sehr gut. Ich möchte nun gern eine VM86 Task hinzufügen,
die mir lediglich den Buchstaben "V" rechts oben auf dem Schirm in einer Endlos-
schleife ausgibt (somit erspare ich mir hoffentlich irgendwelche Exceptions)Mein Code dazu ist wie folgt:
svga: mov di, 0xA000 mov es, di mov di, 158d mov al, "V" stosb jmp svga
Dazu nutze ich den selben Code wie beim erstellen einer "normalen" Task.
Lediglich Code- und alle Segementregister werden mit 0 initialisiert.
Die Anfangsandresse ist fest 803AhMein Flagregister wird wie bei euch auch mit 020202h initialisiert.
ESP wird beim Taskswitch mit 7F58h geladen. Alles Werte in den ersten
64 Kbyte vom RAM.Paging habe ich dafür ausgeschaltet.
Wie nicht anders zu erwarten gehts natürlich nichts
Ich habe auch schon sämtliche Kombinationen mit Segementdescriptoren (PL3) usw.
versucht.Hat vielleicht hier jemand einen Tipp für mich woran es liegen könnte?
Nicky
-
Code als 16-bit-code assembliert?
-
mov al, "V" <-- sollte wohl 'V' sein, oder ist nasm das egal?
-
Hallo,
Code ist 16bit.
Das mit den Anführungszeichen ist egal...Müssen alle Segmentregister mit 0 initialisiert werden? Also keine
Segmentdescriptoren verwenden?Mein VM86 Stack sieht nach der Erstellung so aus:
Flags: 0x20202h ;Adresse 32600d CS: 0x0h IP: 0x80A3h EAX: 0x0h EBX: 0x0h ECX;: 0x0h EDX: 0x0h EBP: 0x0h ESI: 0x0h EDI: 0x0h SS: 0x0h FS: 0x0h GS: 0x0h ES: 0x0h DS: 0x0h ;Adresse 32540d
ESP bekommt nach Taskswitch 32540d zugewiesen.
Nicky
-
was sagt der bochs debugger?
-
Erhard Henkes schrieb:
was sagt der bochs debugger?
Hallo Erhard,
habe nur VBOX und VPC. Mit Bochs komme ich nicht zurecht.
Der IRQ13 wird immer aufgerufen.
Eip zeigt dann auf 0x80A3Nicky
-
VBox hat auch einen Debugger: http://www.lowlevel.eu/wiki/VirtualBox#Debugger
-
IRQ 13 könnte #GP sein und vlt. auch sensitive opcode error.
-
Hallo zusammen,
der Debugger gibt folgenden aus:
00:05:02.657611 Guest CPUM (VCPU 0) state:
00:05:02.657626 eax=002035f7 ebx=00007fbc ecx=00000000 edx=00000000 esi=01000008 edi=01000004
00:05:02.657629 eip=002010e4 esp=00007f14 ebp=0007fff8 iopl=0 nv up di pl nz na po nc
00:05:02.657631 cs={0008 base=0000000000000000 limit=ffffffff flags=0000c09b} dr0=00000000 dr1=00000000
00:05:02.657636 ds={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr2=00000000 dr3=00000000
00:05:02.657639 es={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr4=00000000 dr5=00000000
00:05:02.657642 fs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr6=ffff0ff0 dr7=00000400
00:05:02.657645 gs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr0=00000011 cr2=00000000
00:05:02.657647 ss={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr3=00033000 cr4=00000000
00:05:02.657650 gdtr=0000000000021000:0028 idtr=0000000000020000:0188 eflags=00000046
00:05:02.657653 ldtr={0000 base=00000000 limit=0000ffff flags=00000082}
00:05:02.657654 tr ={0000 base=00000000 limit=0000ffff flags=0000008b}EIP hängt in der Warteschleife fest die nach dem IRQ13 aufgerufen wird
;------------------------------------------------------------------------------------------------------- ;Programmende = Endlosschleife 000000E4 progr_ende: 000000E4 @@: 000000E4 90 nop 000000E5 EB FD jmp @b
Der Fehlerverursachende Befehl liegt bei 0xDC6 in Zeile 7.
Und der Fehlercode = 0x20h00000DBB 66| 8E D0 C mov ss, ax C C invoke GetNextESP, esp 00000DC4 8B E0 C mov esp, eax C C 00000DC6 17 C pop ss 00000DC7 0F A9 C pop gs 00000DC9 0F A1 C pop fs 00000DCB 07 C pop es 00000DCC 1F C pop ds C 00000DCD 5D C pop ebp 00000DCE 5F C pop edi 00000DCF 5E C pop esi 00000DD0 5A C pop edx 00000DD1 59 C pop ecx 00000DD2 5B C pop ebx 00000DD3 58 C pop eax C C 00000DD4 50 C push eax 00000DD5 FF 05 00000335 R C inc time_counter 00000DDB B0 20 C mov al, 020h 00000DDD E6 20 C out 020h, al 00000DDF 58 C pop eax 00000DE0 CF C iretd 00000DE1 C IRQ32 endp
Dies deutet wohl darauf hin das er das Segmentregister mit 0x23h nicht laden kann. Die selben Adressen/Fehlercodes kommen auch beim Versuch die Segmentregister mit NULL
zu laden.gdttabelle: ;0 142 00000081 00000000 dd 0 143 00000085 00000000 dd 0 144 CODE: ;8 145 00000089 FFFF dw 0xFFFF 146 0000008B 0000 dw 0 147 0000008D 00 db 0 148 0000008E 9A db 10011010b 149 0000008F CF db 11001111b ;DB und G Bit gesetzt 150 00000090 00 db 0 151 DATEN: ;16 152 00000091 FFFF dw 0xFFFF 153 00000093 0000 dw 0 154 00000095 00 db 0 155 00000096 92 db 10010010b 156 00000097 CF db 11001111b ;DB und G Bit gesetzt 157 00000098 00 db 0 158 CODE3: ;24 159 00000099 FFFF dw 0xFFFF 160 0000009B 0000 dw 0 161 0000009D 00 db 0 162 0000009E FA db 11111010b 163 0000009F 00 db 0b ;DB und G Bit nicht gesetzt 164 000000A0 00 db 0 165 DATEN3: ;32 166 000000A1 FFFF dw 0xFFFF 167 000000A3 0000 dw 0 168 000000A5 00 db 0 169 000000A6 F2 db 11110010b 170 000000A7 00 db 0b ;DB und G Bit nicht gesetzt 171 000000A8 00 db 0 172 GDT: 173 000000A9 2800 .gdt_limit dw $ - gdttabelle ;5 * 8 = 40 Byte 174 000000AB [81000000] .gdt_base dd gdttabelle ;
Ich benutze kein Taskregister und mein Programm läuft auf PL0.
Hat jemand eine Idee was ich machen könnte?
Nicky
-
in PrettyOS sieht das so aus am Anfang:
// "Segment Present" bit 7 #define VALID 0x80 // "Deskriptor Privilege Level" bit 6:5 #define RING_0 0x00 #define RING_1 0x20 #define RING_2 0x40 #define RING_3 0x60 // "Segment" bit 4 #define SYSTEM 0x00 #define CODE_DATA_STACK 0x10 // "Descriptor Type" bit 3:1 #define DATA_READ_ONLY 0x0 // ....000. #define DATA_READ_WRITE 0x2 // ....001. #define STACK_READ_ONLY 0x4 // ....010. #define STACK_READ_WRITE 0x6 // ....011. #define CODE_EXEC_ONLY 0x8 // ....100. #define CODE_EXEC_READ 0xA // ....101. #define CODE_EXEC_ONLY_CONF 0xC // ....110. #define CODE_EXEC_READ_CONF 0xE // ....111. // "Segment Accessed" bit 0 #define SEGM_ACCESSED 0x1 /**********************/ /* Parameter "gran" */ /**********************/ // "granularity" bit 7 #define _BYTE_ 0x00 #define _4KB_ 0x80 // "Default Operation Size" bit 6 #define USE16 0x00 #define USE32 0x40 // Defines a GDT entry typedef struct { uint16_t limit_low; uint16_t base_low; uint8_t base_middle; uint8_t access; uint8_t granularity; uint8_t base_high; } __attribute__((packed)) GDTentry_t; typedef struct { uint16_t limit; uint32_t base; } __attribute__((packed)) GDTptr_t; void gdt_install(void) { GDTptr_t gdt_register; // Setup the GDT pointer and limit gdt_register.limit = (sizeof(GDTentry_t) * NUMBER_GDT_GATES)-1; gdt_register.base = (uint32_t)&gdt; // GDT GATES - desriptors with pointers to the linear memory address gdt_setGate(0,0,0,0,0); // NULL descriptor // num base limit access gran gdt_setGate(1, 0, 0xFFFFF, VALID | RING_0 | CODE_DATA_STACK | CODE_EXEC_READ, _4KB_ | USE32); gdt_setGate(2, 0, 0xFFFFF, VALID | RING_0 | CODE_DATA_STACK | DATA_READ_WRITE, _4KB_ | USE32); gdt_setGate(3, 0, 0xFFFFF, VALID | RING_3 | CODE_DATA_STACK | CODE_EXEC_READ, _4KB_ | USE32); gdt_setGate(4, 0, 0xFFFFF, VALID | RING_3 | CODE_DATA_STACK | DATA_READ_WRITE, _4KB_ | USE32); tss_write(5, 0x10, 0x0); // num, ss0, esp0 gdt_flush(&gdt_register); tss_flush(); } void gdt_setGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { // Setup the descriptor base address gdt[num].base_low = base & 0xFFFF; gdt[num].base_middle = (base >> 16) & 0xFF; gdt[num].base_high = (base >> 24) & 0xFF; // Setup the descriptor limits gdt[num].limit_low = limit & 0xFFFF; gdt[num].granularity = (limit >> 16) & 0x0F; // Finally, set up the granularity and access flags gdt[num].granularity |= (gran & 0xF0); gdt[num].access = access; } // Initialise our task state segment structure. void tss_write(int32_t num, uint16_t ss0, uint32_t esp0) { // Firstly, let's compute the base and limit of our entry into the GDT. uint32_t base = (uint32_t)&tss; uint32_t limit = sizeof(tss); //http://forum.osdev.org/viewtopic.php?f=1&t=19819&p=155587&hilit=tss_entry#p155587 // Now, add our TSS descriptor's address to the GDT. gdt_setGate(num, base, limit, 0xE9, 0x00); tss.ss0 = ss0; // Set the kernel stack segment. tss.esp0 = esp0; // Set the kernel stack pointer. tss.cs = 0x08; tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x10; #ifdef _DIAGNOSIS_ tss_log(&tss); #endif }