Autor Thema: Software Multitasking  (Gelesen 42357 mal)

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #60 am: 11. May 2009, 23:23 »
Hast du beachtet, dass du nicht einfach irq_common_stub in die IDT eintragen darfst, weil du da nicht den Fehlercode sowie die Interruptnummer auf den Stack legst, sondern du einen Stub ähnlich wie diesen verwenden musst? So einen Stub meine ich:
irq_stub_0:
    push dword 0 ; Ersatz für Fehlercode
    push dword 32 ; Nummer des Interrupts (IRQ 0 ist z.B. nach Interrupt 32 gemappt)
    jmp irq_common_stub
Sonst ist dein Stack nicht wie erwartet aufgebaut, und du bekommst Probleme beim Auslesen der Register, und spätestens beim IRET einen GPF.

Dass in der Parameter esp auch als Zeiger auf dein Register-Struct zuverwenden ist, hab ich vielleicht auch nicht ganz gut rübergebracht. Ich meinte das in etwa so:
ULONG irq_handler1(ULONG esp)
{
     struct regs* r = (struct regs*)esp;
     ...

Ansonsten hilft nur den Fehler einzugrenzen. Es hilft manchmal mittels Breakpoints an wichtigen Stellen sich die Register genau anzugucken, und zu überlegen, ob sie die erwarteten Werte enthalten. Und wenn ja, musst du überlegen, ob die Erwartung sinnvoll ist. Außerdem kannst du natürlich deinen Code kürzen, indem du Behandlung des PICs sowie das Paging rauswirfst.
Dieser Text wird unter jedem Beitrag angezeigt.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #61 am: 11. May 2009, 23:26 »
Und IRQs (zumindest der Timer-IRQ) sollten auch funktionieren, wenn du sie direkt mit INT 32 (o.ä.) aufrufst. Falls du den PIC ignorierst, ist das ganz hilfreich.
Dieser Text wird unter jedem Beitrag angezeigt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #62 am: 11. May 2009, 23:38 »
Das mit cr3 im TSS dürfte auch nicht funktionieren, oder? Wenn ich mich recht erinnere werden da für Software-Multitasking nur die Stack-Einträge (also esp und ss jeweils für Kernel- und Userspace) benutzt. Du solltest also stattdessen irgendwo gegen Ende des C-Interrupt-Handlers manuell cr3 neu laden (nur wenn es wirklich einen Taskwechsel gab, das ist teuer!)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #63 am: 11. May 2009, 23:43 »
so sieht das im asm stub aus:
_irq0:
    cli
    push byte 0
    push byte 32
    jmp irq_common_stub

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #64 am: 11. May 2009, 23:50 »
Das cli kannst du dir sparen, wenn du den Gate-Typ richtig gesetzt hast (Interrupt Gate statt Trap Gate), das ist dann automatisch dabei. Ansonsten kommt mir ein byte-Push etwas klein vor - ich hätte sogar gedacht, daß man überhaupt nicht byteweise pushen kann. dword wie PorkChicken es geschrieben hat wäre wohl sinnvoller (und beim Fehlercode ist das auch, was die CPU pusht, wenn sie es selber macht).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #65 am: 11. May 2009, 23:52 »
So ich habe jetzt mal user mode, vfs, RAM disk weg gelassen. Mit pODA->ts_flag ==0 kann ich mittels IRQ0 eine Zeitschleife realisieren, also sollte der IRQ-Mechanismus gehen. Das geht:
    k_clear_screen();
    settextcolor(getpid(),0);
    printformat("SS: %x, ESP: %x, EBP: %x, CS: %x, DS: %x\n", fetchSS(),fetchESP(),fetchEBP(),fetchCS(),fetchDS());

    sti();
    sleepSeconds(5);

    //pODA->ts_flag = 1;
    ULONG c=0;
    while(TRUE)
{
  if( k_checkKQ_and_print_char() )
  {
    ++c;
    if(c>5)
    {
      c=0;
      settextcolor(4,0);
      printformat("\nT: %x H: %x WRITE: %i Read: %i ", pODA->pTailKQ, pODA->pHeadKQ, pODA->KQ_count_write, pODA->KQ_count_read);
          printformat("*T: %c %i *H: %c %i\n", *(pODA->pTailKQ),*(pODA->pTailKQ),*(pODA->pHeadKQ),*(pODA->pHeadKQ));
          settextcolor(2,0);
          settextcolor(getpid(),0);
    }
  }
}
return 0;
Schon mal ein guter Anfang.

ehenkes

  • Gast
Gespeichert
« Antwort #66 am: 11. May 2009, 23:55 »
Zitat
Das cli kannst du dir sparen, wenn du den Gate-Typ richtig gesetzt hast (Interrupt Gate statt Trap Gate), das ist dann automatisch dabei.
Ich verwende IDT.


Zitat
Ansonsten kommt mir ein byte-Push etwas klein vor - ich hätte sogar gedacht, daß man überhaupt nicht byteweise pushen kann. dword wie PorkChicken es geschrieben hat wäre wohl sinnvoller (und beim Fehlercode ist das auch, was die CPU pusht, wenn sie es selber macht).
Ich habe mir das aus Bran's und James Molloy's Tutorial abgeschaut. Ging aber die ganze Zeit, sollte also nicht das Problem sein.
« Letzte Änderung: 12. May 2009, 00:21 von ehenkes »

ehenkes

  • Gast
Gespeichert
« Antwort #67 am: 12. May 2009, 00:00 »
Mit gesetztem ts_flag gibt es leider einen GPF:
Zitat
jksdghfjkdghdfjkgh: 0018FFE0h, EBP: 0018FFF0h, CS: 00000008h, DS: 00000010h
T: 0000DAF6h H: 0000DAF6h WRITE: 18 Read: 18 *T:  0 *H:  0100

TSS log:
prev_tss: 00000000h esp0: 40105800h ss0: 00000010h esp1: 00000000h ss1: 00000000h esp2: 00000000h ss2: 00000000h cr3: 0041E000h eip: 00000000h eflags: 00000000h eax: 00000000h ecx: 00000000h edx: 00000000h ebx: 00000000h esp: 00000000h ebp: 00000000h esi: 00000000h edi: 00000000h es: 00000013h cs: 0000000Bh ss: 00000013h ds: 00000013h fs: 00000013h gs: 00000013h ldt: 00000000h trap: 00000000h iomap_base: 00000000h

err_code: 0000DAD0h address(eip): 00008497h
edi: 000B8FDCh esi: 000082ABh ebp: 00190000h eax: 0018FFD8h ebx: 00000000h ecx: 000B800Ah edx: 00000020h cs: 8 ds: 16 es: 16 fs: 16 gs 16 ss 753674 int_no 13 eflags 00010016h useresp 0000DAD0h
General Protection Fault >>> Exception. System Halted! <<<

ehenkes

  • Gast
Gespeichert
« Antwort #68 am: 12. May 2009, 00:28 »
Ich poste mal den Code, da ich momentan nicht weiß, wo es am meisten hängt, werde aber dennoch Fehlereingrenzung versuchen. Vielleicht seht ihr das Problem mit einem Blick. Würde mich freuen, wenn ihr mir aus dem Tiefpunkt heraus helft. Vielleicht fehlt mir auch noch der Durchblick. Die Thematik ist komplex aber auch sehr interessant.  :-)

http://www.henkessoft.de/OS_Dev/Downloads/36i.zip

Leider hat mir euer Code aber auch nicht zum Multitasking geholfen.
Es ist echt verhext.

Falls ihr den Code compilieren wollt:
http://www.osdever.net/downloads/compilers/DJGPP-Installer-nocpp.exe

Ich verwende den Compiler gcc.exe (Version 3.1) und Linker ld.exe (Version 2.13) wegen des Formats aout für den Linker. Nur so konnte ich den Übergang 16/32 Bit schaffen, wollte aus didaktischen Gründen keinen GRUB bootloader (die Diskussion hatten wir schon, ihr habt mich überzeugt, bitte nicht nachsetzen).   

« Letzte Änderung: 12. May 2009, 00:33 von ehenkes »

ehenkes

  • Gast
Gespeichert
« Antwort #69 am: 12. May 2009, 00:56 »
Ich habe nun folgendes getestet: Umschalten von task A nach task A, um mal zu sehen, ob der ganze Mechanismus überhaupt läuft, und es geht!
ULONG task_switch1(ULONG esp)
{

    // If we haven't initialised tasking yet, just return.
    if(!current_task) return esp;

    current_task->esp = esp;   // save esp

    //old_task ==> new_task
    printformat("ts ");
    /*
    current_task = current_task->next;
    if(!current_task) current_task = ready_queue;
    */
    current_task = current_task; //same task TEST TEST TEST

    // new_task
    current_directory = current_task->page_directory;
    tss_entry.cr3 = current_directory->physicalAddr;

    set_kernel_stack(current_task->kernel_stack+KERNEL_STACK_SIZE);

    return current_task->esp;  // return esp
}
Zitat
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
 ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts t
s ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts ts
:-)
Nun gilt es heraus zu finden, woran es liegt, dass das Umschalten von task A nach task B nicht fehlerfrei gelingt. Wie läuft das bei tyndur? Wie sieht da die task-Struktur aus?

Was muss genau beachtet werden, dass dies klappt?
    current_task = current_task->next;
    if(!current_task) current_task = ready_queue;

« Letzte Änderung: 12. May 2009, 01:06 von ehenkes »

ehenkes

  • Gast
Gespeichert
« Antwort #70 am: 12. May 2009, 01:19 »
Ich habe das jetzt so aufgesetzt, dass ich die Daten des zweiten Tasks vor dem GPF gerade noch sehe:
ULONG task_switch1(ULONG esp)
{

    // If we haven't initialised tasking yet, just return.
    if(!current_task) return esp;

    current_task->esp = esp;   // save esp

    //old_task ==> new_task
    printformat("ts: ");
    task_log(current_task);
    printformat("\n\n");

    current_task = current_task->next;
    if(!current_task) current_task = ready_queue;

    printformat("ts: ");
    task_log(current_task);
    printformat("\n\n");


    //current_task = current_task; //same task TEST TEST TEST

    // new_task
    current_directory = current_task->page_directory;
    tss_entry.cr3 = current_directory->physicalAddr;

    set_kernel_stack(current_task->kernel_stack+KERNEL_STACK_SIZE);

    return current_task->esp;  // return esp
}
Screen Output:
Zitat
SS: 00000010h, ESP: 0018FFE0h, EBP: 0018FFF0h, CS: 00000008h, DS: 00000010h

ts: id: 1 ebp: 00000000h esp: 0018FFC0h eip: 00000000h PD: 00000000h k_stack: 40101800h next: 40101814h

ts: id: 2 ebp: 0018FFF0h esp: 0018FFD8h eip: 0000D36Bh PD: 40102000h k_stack: 40105000h next: 40101844h

TSS log:
prev_tss: 00000000h esp0: 40105800h ss0: 00000010h esp1: 00000000h ss1: 00000000h esp2: 00000000h ss2: 00000000h cr3: 0041E000h eip: 00000000h eflags: 00000000h eax: 00000000h ecx: 00000000h edx: 00000000h ebx: 00000000h esp: 00000000h ebp: 00000000h esi: 00000000h edi: 00000000h es: 00000013h cs: 0000000Bh ss: 00000013h ds: 00000013h fs: 00000013h gs: 00000013h ldt: 00000000h trap: 00000000h iomap_base: 00000000h

err_code: 0000FFF8h address(eip): 00008497h edi: 000B8FDCh esi: 000082ABh ebp: 001FFFF8h eax: 0018FFD8h ebx: 00000000h ecx:
000B800Ah edx: 00000020h cs: 8 ds: 16 es: 16 fs: 16 gs 16 ss 0
int_no 13 eflags 00010002h useresp 001FFFF8h

General Protection Fault >>> Exception. System Halted! <<<

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #71 am: 12. May 2009, 01:30 »
Ich hab deinen Code auch mal versucht zu debuggen. So ganz schlau, werd ich da gerade auch nicht. Bei mir tritt der GPF beim pop fs im Interrupt Handler auf. Seltsamerweise nicht beim pop gs davor. Außerdem tritt bei mir der Fehler nicht beim ersten Interrupt auf, sondern ein paar Interrupts später.

Irgendwas stimmt da mit dem Stack nicht (ein 0xd9a7 sollte da nicht einfach so draufliegen). Auszug aus dem Bochs Log:
Zitat
00158736424-e-@0000849d-[CPU0 ] fetch_raw_descriptor: GDT: index (d9a7)1b34 > limit (2f)

Ich denke du suchst das Problem an der falschen Stelle. Mehr kann ich dir um diese Zeit leider auch noch nicht sagen. Am besten verlässt du dich nicht nur auf deine eigenen Ausgaben, sondern nutzt den Debugger deines Emulators.
Dieser Text wird unter jedem Beitrag angezeigt.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #72 am: 12. May 2009, 09:37 »
ich habe jetzt ein paar posts übersprungen:
aber mir ist aufgefallen das der parameter für _irq_handler1 nicht
vom stack geholt wird:
mov gs, ax

push esp              ; parameter of _irq_handler1
call _irq_handler1    ;
mov esp, eax          ; return value: changed or unchanged esp
;>>>  add esp, 4 <<<

pop gs
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

ehenkes

  • Gast
Gespeichert
« Antwort #73 am: 12. May 2009, 19:05 »
Zitat
add esp, 4
Ich habe dies hinzu gefügt, dann stürzt er noch früher mit GPF ab.

Zitat
Ich hab deinen Code auch mal versucht zu debuggen. So ganz schlau, werd ich da gerade auch nicht. Bei mir tritt der GPF beim pop fs im Interrupt Handler auf. Seltsamerweise nicht beim pop gs davor. Außerdem tritt bei mir der Fehler nicht beim ersten Interrupt auf, sondern ein paar Interrupts später.

Irgendwas stimmt da mit dem Stack nicht (ein 0xd9a7 sollte da nicht einfach so draufliegen). Auszug aus dem Bochs Log:
Zitat
00158736424-e-@0000849d-[CPU0 ] fetch_raw_descriptor: GDT: index (d9a7)1b34 > limit (2f)

Ich denke du suchst das Problem an der falschen Stelle. Mehr kann ich dir um diese Zeit leider auch noch nicht sagen. Am besten verlässt du dich nicht nur auf deine eigenen Ausgaben, sondern nutzt den Debugger deines Emulators.
Ich verwende Bochs. Wie wendest Du den Debugger genau an, damit Du diese Meldungen siehst? Mir fiel auf, dass beim Vergleich des eigenen error logs bei GPF und output von Bochs Unterschiede sind, und zwar bei eip, esi, ebp, eax, edx.


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #74 am: 12. May 2009, 19:20 »
ich habe jetzt ein paar posts übersprungen:
aber mir ist aufgefallen das der parameter für _irq_handler1 nicht
vom stack geholt wird:
mov gs, ax

push esp              ; parameter of _irq_handler1
call _irq_handler1    ;
mov esp, eax          ; return value: changed or unchanged esp
;>>>  add esp, 4 <<<

pop gs
Nein, das wäre falsch. Die Funktion gibt das korrekte esp in eax zurück und das wird ja sofort gesetzt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #75 am: 12. May 2009, 19:35 »
Ich verwende Bochs. Wie wendest Du den Debugger genau an, damit Du diese Meldungen siehst?
Wenn meine bochs-Version nicht schon längst veraltet ist und sich alles verändert hat, brauchst du ungefähr sowas in deiner Konfigurationsdatei:
error: action=report
info: action=report
debug: action=report
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #76 am: 12. May 2009, 20:22 »
error: action=report
info: action=report
debug: action=ignore

steht da bei mir.

Nach dem GPF:
RAX=000000000000001a  RBX=0000000000000000
RCX=00000000000b8000  RDX=00000000000003d5
RSP=000000000018ff6c  RBP=000000000018ff94
RSI=000000000018ffa0  RDI=0000000000000004
IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
RIP=0000000000009a07 (0000000000009a07)
CR0=0xe0000011
CR1=0x0
CR2=0x0000000000000000
CR3=0x00306000
CR4=0x00000000
jmp .+0xfffffffe (0x00009a07) : EBFE

... habe nun auch die byte gegen dword getauscht, macht aber keinen Unterschied.  :-(
_irq0:
    cli
    push dword 0
    push dword 32
    jmp irq_common_stub

Ich habe mal nachgeschaut, was ein GPF im Rahmen des Switching bewirkt:

Zitat
Faults can occur in the task state segment (TSS) structure when:
  * switching to a busy task during a call or jump instruction
  * switching to an available task during an interrupt return (IRET) instruction
  * using a segment selector on a switch pointing to a TSS descriptor in the LDT

Hat jemand eine Idee, wo und wie ich genau ansetzen könnte, um das Problem zu lösen? Wie soll ich das schaffen, wenn selbst PorkChicken, der mich so hervorragend zur Umsetzung des tyndur-taskswitch-Mechanismus  geführt hat, den Fehler nicht leicht findet.  :?

Ich habe nochmals
von task A nach task A umgeschaltet:
Zitat
id: 1 esp: 0018FFB8h k_stack: 40101800h next: 40101814h
id: 1 esp: 0018FFB8h k_stack: 40101800h next: 40101814h
id: 1 esp: 0018FFBCh k_stack: 40101800h next: 40101814h
id: 1 esp: 0018FFBCh k_stack: 40101800h next: 40101814h
Kann das sein, dass esp dabei ab und zu um 4 Byte hin und her springt?

Was muss im task_switch im TSS eingetragen werden?
« Letzte Änderung: 12. May 2009, 22:10 von ehenkes »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #77 am: 12. May 2009, 22:25 »
error: action=report
info: action=report
debug: action=ignore

steht da bei mir.
Ja. ignore ist eben weniger Ausgabe als report.

Zitat
RIP=0000000000009a07 (0000000000009a07)
Ich weiß nicht, wohin du deinen Kernel legst (du benutzt ja kein GRUB), aber normal würde ich das als einen kaputten Wert ansehen.

Zitat
Ich habe mal nachgeschaut, was ein GPF im Rahmen des Switching bewirkt:

Zitat
Faults can occur in the task state segment (TSS) structure when:
  * switching to a busy task during a call or jump instruction
  * switching to an available task during an interrupt return (IRET) instruction
  * using a segment selector on a switch pointing to a TSS descriptor in the LDT
Du machst kein Hardware-Taskswitching, deswegen klingt das alles nicht so richtig relevant. Du kriegst deinen GPF entweder bei einem Interrupt oder beim Rücksprung aus einem Interrupt, würde ich sagen.

Zitat
Kann das sein, dass esp dabei ab und zu um 4 Byte hin und her springt?
Das klingt auf jeden Fall komisch. Ich würde mal versuchen rauszufinden, woran das liegt. Dann kannst du wahrscheinlich auch sagen, ob es harmlos oder böse ist.

Zitat
Was muss im task_switch im TSS eingetragen werden?
Nichts. Wie oben schonmal erwähnt wird beim Software-Taskswitchung der TSS nur benutzt, um ss und esp von Kernel und Userspace zu sichern. Alles andere interessiert den Prozessor nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ehenkes

  • Gast
Gespeichert
« Antwort #78 am: 12. May 2009, 22:37 »
Momentan bin ich für jede Klarstellung dankbar, denn vor lauter lauter baut man zum Schluss noch mehr Blödsinn ein, so dass garnichts mehr geht.

Zitat
Ich weiß nicht, wohin du deinen Kernel legst (du benutzt ja kein GRUB), aber normal würde ich das als einen kaputten Wert ansehen.
Der Kernel beginnt bei 0x8000h:
OUTPUT_FORMAT("binary")
ENTRY(RealMode)
phys = 0x00008000;
...

Zitat
...wird beim Software-Taskswitchung der TSS nur benutzt, um ss und esp von Kernel und Userspace zu sichern. Alles andere interessiert den Prozessor nicht.

Was ist mit cr3?

ULONG task_switch1(ULONG esp)
{
    // If we haven't initialised tasking yet, just return.
    if(!current_task) return esp;

    current_task->esp = esp;   // save esp

    current_task = current_task->next;
    if(!current_task) current_task = ready_queue;

    // new_task
    current_directory = current_task->page_directory;
    asm volatile("mov %0, %%cr3" : : "r" (current_directory->physicalAddr));
    tss_entry.cr3 = current_directory->physicalAddr; //notwendig?
    tss_entry.esp = current_task->esp;
    tss_entry.esp0 = (current_task->kernel_stack)+KERNEL_STACK_SIZE;

    return current_task->esp;  // return esp
}
Ist das so in Ordnung?

« Letzte Änderung: 12. May 2009, 23:05 von ehenkes »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #79 am: 12. May 2009, 22:43 »
Ah gut, dann kann das eip so natürlich stimmen. Ist nur eine ungewöhnliche Position.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen