Autor Thema: MultiTasking im RM  (Gelesen 3475 mal)

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« am: 06. December 2004, 21:05 »
hallo everybody! da bin ich wieder! und zwar mit einem neuen problem.

diesmal geht es um (die der titel schon sagt) MultiTasking. dazu habe ich einen Tasktable, der so aufgebaut ist:

    - ID 2 bytes
    - Name 12 bytes
    - SS 2 bytes
    - SP 2 bytes
    - Reserviert 2 bytes
    [/list:u]

    am ende des tables steht 0xFFFF als ID. ich habe den task "kernel" so initialisiert:


mov ax,0x0000
mov [fs:0x100000],ax
mov byte [fs:0x100002],'K'
mov byte [fs:0x100003],'E'
mov byte [fs:0x100004],'R'
mov byte [fs:0x100005],'N'
mov byte [fs:0x100006],'E'
mov byte [fs:0x100007],'L'
mov byte [fs:0x100008],0x00
mov byte [fs:0x100009],0x00
mov byte [fs:0x10000A],0x00
mov byte [fs:0x10000B],0x00
mov byte [fs:0x10000C],0x00
mov byte [fs:0x10000D],0x00
mov word [fs:0x10000E],0x9000
mov word [fs:0x100010],0xFFEF
mov byte [fs:0x100012],0xFF
mov byte [fs:0x100013],0x00
mov ax,0xFFFF
mov [fs:0x100014],ax    


mein table ist also an 0x100000 linear. das geht mit dem FRM. jetzt will ich die einzellnen Tasks abrufen, bis als ID 0xFFFF da steht. es gibt dazu die vars task_offset, die den offset in der table merkt, task_current, die die aktuelle ID merkt, und task_name, die den namen merkt. die register werden auf dem stack gesichert (danke Roshl, für die Idee). geswitcht wird mit dem folgenden code als timerinterrupt 0x08 software oder 0x00 hardware:


_int0x08:
cli
pusha
push ds
push es

mov ax,0x50
mov ds,ax
mov cx,[task_current]
mov ah,0x07
int 0x67
mov si,[task_offset]
sub si,0x06
mov [fs:si],ss
add si,0x02
mov [fs:si],sp
add si,0x04
;müsste am ende des taskentrys sein
mov ax,[fs:si]
read_next_task:
mov [task_current],ax
cmp ax,0xFFFF
je near task_get_next
add si,0x02
mov al,[fs:si]
mov byte [task_name],al
mov al,[fs:si+1]
mov byte [task_name+1],al
mov al,[fs:si+2]
mov byte [task_name+2],al
mov al,[fs:si+3]
mov byte [task_name+3],al
mov al,[fs:si+4]
mov byte [task_name+4],al
mov al,[fs:si+5]
mov byte [task_name+5],al
mov al,[fs:si+6]
mov byte [task_name+6],al
mov al,[fs:si+7]
mov byte [task_name+7],al
mov al,[fs:si+8]
mov byte [task_name+8],al
mov al,[fs:si+9]
mov byte [task_name+9],al
mov al,[fs:si+10]
mov byte [task_name+10],al
mov al,[fs:si+11]
mov byte [task_name+11],al
add si,0x0C
mov ax,[fs:si]
mov ss,ax
add si,0x02
mov ax,[fs:si]
mov sp,ax
add si,0x04
mov [task_offset],si

mov cx,[task_current]
mov ah,0x06
int 0x67

pop es
pop ds
popa

task_ende:
push ax
mov al,0x20       ;ende des ints abschicken
out 0x20,al
pop ax
sti
iret

task_get_next:
mov si,0x0000
mov [task_offset],si
mov ax,[fs:si]
jmp read_next_task        


problem: er geht nicht. ich weiß nicht, warum, aber er geht nicht. jedoch bleibt der code nicht einfach stecken, sondern geht schon, aber er kommt irgendwie nichtmehr richtig an, sodass der kernel nichtmehr ausgeführt wird. bochs zeigt allerdings keinen fehler an. hat jemand eine idee, wo der fehler sein könnte?

mfg

joachim_neu
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #1 am: 06. December 2004, 21:11 »
Am besten setzt du einen Breakpoint in deine Switch-Routine und schaust dir im Debugmodus an ob die Register nach dem Switch korrekt wiederhergestellt werden.
----------------------
Redakteur bei LowLevel

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #2 am: 06. December 2004, 21:14 »
wie finde ich den punkt? ich kapier das bei bochs nicht so ganz, man findet ja nie den richtigen punkt...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #3 am: 06. December 2004, 23:14 »
Also ich hab mal in der Dokumentation von Bochs geschaut.

Den Einstiegspunkt deines Kernels wirst du ja kennen.
Dann setzt du einen Breakpoint dahin. Von da aus kannst du ja schrittweise vorgehen bis zu dem Punkt an dem dein Interrupt für den Timer gesetzt wird.

Dann kannst du im Debugger mit
  x  /nuf addr      Examine memory at linear address addr
  xp /nuf addr      Examine memory at physical address addr
     n              Count of how many units to display
     u              Unit size; one of
                      b Individual bytes
                      h Halfwords (2 bytes)
                      w Words (4 bytes)
                      g Giant words (8 bytes)
                      NOTE: these are *not* typical Intel nomenclature sizes,
                            but they are consistent with GDB convention.
     f              Printing format.  one of
                      x Print in hexadecimal
                      d Print in decimal
                      u Print in unsigned decimal
                      o Print in octal
                      t Print in binary

 

Dir Speicherinhalt anzeigen lassen. Somit könntest du also in der VectorTable auslesen wo deine Int-Routine für den Timer, und somit für deine Switch-Routine liegt. Dann kannste darauf einen neuen Breakpoint setzen.

Klingt etwas umständlich, aber theoretisch solltest du es nur einmal machen müssen. Sofern du nichts groß umstellst, solltest du deine Int-Routine jedesmal an der selben Speicherstelle finden.
----------------------
Redakteur bei LowLevel

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #4 am: 07. December 2004, 12:49 »
es ist jetzt so, dass meine routine schon anständig initialisiert und aufgerufen wird. das funktioniert. ich habe eine textausgabe eingebaut, und die wird immer wieder ausgegeben. das funktioniert also. außerdem habe ich das problem, dass anscheinend der return nicht geht. denn nach dem initialisieren kommen noch weitere textausgaben, nach denen dann das interrupt anscheinend zum ersten mal aufgerufen wird. und danach geht es nicht weiter. es liegt also nicht an der initialisierung, sondern muss irgendwo im code liegen. allerdings verstehe ich nicht, wo... mein jetziger code ist das hier:


_int0x08:
pusha
push ds
push es

mov ax,0x50
mov ds,ax
mov cx,[task_current]
mov ah,0x07
int 0x67

mov si,[task_offset]
sub si,0x06
mov [fs:si],ss
add si,0x02
mov [fs:si],sp
add si,0x04
;müsste am ende des taskentrys sein
mov ax,[fs:si]
read_next_task:
mov [task_current],ax
cmp ax,0xFFFF
je near task_get_next
add si,0x02
mov al,[fs:si]
mov byte [task_name],al
mov al,[fs:si+1]
mov byte [task_name+1],al
mov al,[fs:si+2]
mov byte [task_name+2],al
mov al,[fs:si+3]
mov byte [task_name+3],al
mov al,[fs:si+4]
mov byte [task_name+4],al
mov al,[fs:si+5]
mov byte [task_name+5],al
mov al,[fs:si+6]
mov byte [task_name+6],al
mov al,[fs:si+7]
mov byte [task_name+7],al
mov al,[fs:si+8]
mov byte [task_name+8],al
mov al,[fs:si+9]
mov byte [task_name+9],al
mov al,[fs:si+10]
mov byte [task_name+10],al
mov al,[fs:si+11]
mov byte [task_name+11],al
add si,0x0C
mov ax,[fs:si]
mov ss,ax
add si,0x02
mov ax,[fs:si]
mov sp,ax
add si,0x04
mov [task_offset],si

mov cx,[task_current]
mov ah,0x06
int 0x67

pop es
pop ds
popa

task_ende:
push ax
mov al,0x20       ;ende des ints abschicken
out 0x20,al
pop ax
iret

task_get_next:
mov si,0x0000
mov [task_offset],si
mov ax,[fs:si]
jmp read_next_task


mfg

Joachim_Neu
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #5 am: 07. December 2004, 15:16 »
Aja mit dem Debugger könntest du den Code deiner Int-Routine Schrittweise durchlaufen und schauen ob alles so eingestellt wird für den jeweils nächsten Task wie du es gerne hättest.

Ein Debugger ist das beste Spielzeug das man einem Programmiere bei Seite stellen kann. Man muss sich halt auch mal damit auseinandersetzen.

Ein dritter muss sich erst die Mühe machen, deinen Code zu lesen, zu verstehen, nachzuvollziehen was du erreichen willst um DANN noch den evtl. Fehler zu finden UND zu korrigieren.

Da hast du es viel einfacher wenn du selbst nach dem Fehler suchen kannst.....
----------------------
Redakteur bei LowLevel

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #6 am: 07. December 2004, 15:49 »
stimmt... ich werde mich ranmachen.
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

 

Einloggen