Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Adi am 26. March 2007, 13:47
-
Hallo,
das ist mein erster Beitrag und muss sagen ich bin echt begeistert ein so tolles deutschsprachiges Forum bezüglich OS-Entwicklung gefunden zu haben! ;-)
Schreibe gerade selbst ein kleines Betriebssystem in c++... allerdings habe ich ein Problem welches ich bisher nicht lösen konnte! wäre froh wenn von euch jemand eine Lösung hat :-)
Also es geht um folgenden Beispiel-Kernel:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=6718&lngWId=3
dessen Code teilweise auch bei mir Verwendung findet...
Nun nach genauerem betrachten wird klar dass man eine neue ISR mit folgendem Code aktiviert:
(keyboard.cpp)
enable_irq(1, keyboard_int, INT_GATE|BITS_32|PRESENT|RING_2);
Dies funktioniert auch alles soweit! Wenn ich allerdings Interrupt0 nutzen möchte (z.b. für Taskswitching) bekomme ich merkwürdige Bildschirmausgaben oder auch gleich einen Page-Fault!
Hier meine Ergänzungen:
enable_irq(0, int_test, INT_GATE|BITS_32|PRESENT|RING_2);
void int_test(){
//Don't let interrupts bother us while handling one.
interrupt_disable();
kernel->video->put('x');
kernel->video->refresh();
//tell pic we have acknowledged the interrupt
outportb(0x20, 0x20);
interrupt_enable();
asm("mov %ebp,%esp");
asm("pop %ebp");
asm("iret"); //return to executing code
}
Wie im obigen Code gewünscht werden die X'e ausgegeben un erst nach ein paar Zeilen tritt ein Page-fault auf!
-
Du solltest evtl. die Register im Interrupthandler sichern... dazu ist halt ne C/C++ Funktion nicht so geeignet, deshalb empfehle ich da dann doch den C/C++ Interruptbehandlungsroutinen einen assemblerstub vorneanzustellen, welcher die Register speichert und danach auch wiederherstellt.
Sicher bin ich mir natürlich nicht, da du ein bisschen wenig informationen über den pagefault herausrückst :wink: Am besten wäre es natürlich wenn du bochs anwerfen würdest, beim logging für das cpu device alles auf "report" und dann sagen würdest, wo eip gerade ist beim pagefault ist (am besten dir vom compiler/linker ne datei mit den adressen aller symbole ausgeben lassen, dann weißt du auch gleich welche funktion da pagefaultet) und an welcher adresse der Pagefault auftritt.
-
Eine OffTopic-Anmerkung: Du kannst deine Beiträge auch editieren, dann steht unten zwar, dass es editiert wurde, aber das macht ja auch nichts.
-
dazu ist halt ne C/C++ Funktion nicht so geeignet
*duck und weg* :-P
bitmaster
-
dazu ist halt ne C/C++ Funktion nicht so geeignet
*duck und weg* :-P
bitmaster
Damit hast du deinem Titel mal wieder alle Ehre gemacht. Dieser Post bringt genau _nichts_
@Topic:
Mit irgendwelchen Compiler-Hacks wärs warscheinlich möglich, das auch in C(++) zu erledigen. Das führt aber dazu, dass der Code compilerabhängig wird, und als sonderlich elegant würde ich diese Lösung auch nicht bezeichnen. Daher würde ich dir auch raten, das mit ASM-Stubs zu machen, die eigentlich nichts anderes machen als die Register zu sichern.
Hier kannst du dir anschauen, wie wir das in LOST gelöst haben:
http://lost.famkaufmann.info/websvn/filedetails.php?repname=Lost&path=%2Ftrunk%2Fsrc%2Fkernel%2Fsrc%2Fstubs.asm
-
Text editiert ;-)
Hey, also danke für die Antworten!
Also zu Bochs... bisher nutzte ich VMware! werde aber umsteigen!
Dann kann ich euch sicher auch mehr Details zum Fehler liefern!
Zu den Register... dachte dass die CPU diese automatisch sichert und nach einem "iret" wiederherstellt! oder liege ich da falsch?
Schließlich funktioniert die ISR des Keyboard-Treiber doch auch einwandfrei?!
-
Nein, iret sichert nur das eflags Register und cs:eip. Alle anderen Register wie eax-edx,esi,edi,ebp etc. musst du mittels push/pop selber sichern und wieder vom stack holen. Warum der keyboard irq funktioniert kann ich jetzt nicht sagen, aber sobald er aufgerufen wird und Register verändert werden, stimmen nach der rückkehr die Werte nicht mehr. Also als Beispiel:
irq1:
push eax
push ebx
push ecx ;Werte speichern
... ;Code der die Register eax, ebx und ecx verändert
mov al,20h
out 20h,al ;EOI
pop ecx ;Werte zurück holen
pop ebx
pop eax
iret
Multitasking hast du noch nicht, oder? Weil der irq0 da sonst ohne Sichern der Register alles kaput machen würde.
bitmaster
-
@bitmaster
Danke für das Beispiel! Die X'e wurden ohne Page-Fault ausgegeben ;-)
Jedoch traten noch einige Grafikfehler auf... die hatten sich allerdings auch erledigt nach dem ich noch ein paar Register mehr gesichert hab!
Wie ich inzwischen glaube, sind wohl auch in der Keyboard-ISR Fehler aufgetreten wenn man die Register nicht sichert! Allerdings die Auswirkungen zeigten sich sehr selten!
Jetzt scheint alles zu funktionieren :-)
Gibt es eigentlich noch mehr Register die gesichert werden sollten? (siehe Code unten)
Und was genau bewirken die vorletzten 2 Zeilen? (hat wohl was mit dem Stack zu tun)
Wäre es nicht sinnvoller interrupt_enable() direkt vor "iret" zu schreiben?
void int_test(){
interrupt_disable();
asm("push %eax");
asm("push %ebx");
asm("push %ecx");
asm("push %edx");
asm("push %esi");
asm("push %edi");
asm("push %ebp");
std::cout << 'x';
outportb(0x20, 0x20);
asm("pop %ebp");
asm("pop %edi");
asm("pop %esi");
asm("pop %edx");
asm("pop %ecx");
asm("pop %ebx");
asm("pop %eax");
interrupt_enable();
asm("mov %ebp,%esp");
asm("pop %ebp");
asm("iret"); //return to executing code
}
-
Wäre es nicht sinnvoller interrupt_enable() direkt vor "iret" zu schreiben?
Am sinnvollsten wäre es, dieses disable() und enable() ganz wegzulassen. Ersteres ist impliziert, weil es ein Interrupt Gate ist, letzteres wird dann mit dem iret erledigt.
-
Ich habe nirgendwo enable und disable erwähnt. Meint ihr damit "cli" und "sti ? Und welche Register der C/C++ Code jetzt verändert, damit dürft ihr euch dann rumschlagen. In ASM weis ich genau welche Register verändert werden. Aber zu not kannst du einfach alle Register sichern und wiederherstellen. Im Protected Mode gibt es ja noch das Befehlspaar pusha und popa. Falls du die Segmentregister noch veränderst, vergesse nicht diese zwischenzuspeichern.
bitmaster
-
Also ich muss nochmals sagen, dass es nicht sinnvoll ist eine C/C++ Funktion direkt als interrupthandler zu missbrauchen, da die zB das Register ebp bereits beim eintritt in die Funktion verändert wird und auch da eine C/C++ Funktion einfach ein bestimmtes Stacklayout vorsieht. Da kann man nicht einfach irgendwas auf den Stack pushen, da da C/C++ zB lokale Variablen anlegt.
-
Und welche Register der C/C++ Code jetzt verändert, damit dürft ihr euch dann rumschlagen. In ASM weis ich genau welche Register verändert werden.
Dann bewegt sich der Umfang deines Codes in Bereichen, die man allgemein als Mickey-Maus-Projekt bezeichnet.
-
@taljeth: Ach taljeth! Ich respektiere es das du in C/C++ codest. Ich glaube auch dass du Ahnung von OSDeveloping hast. Aber was ich bezweifle ist, dass du viel Ahnung von ASM hast. Ein guter ASM progger weis welche Register verändert werden, egal wie groß der Code ist bzw. wie viele Zeilen Code. Und lass es doch endlich. Ich weis das du meinst du seist der einzig Gute OSDever. Aber die Zeit wird kommen, in der du nicht mehr so denkst. In ASM weis man immer welche Register verändert werden (es sei denn man hat kA von den Befehlen). Und spar dir bitte einen weiteren Kommentar der Anzweifel zum Ausdruck bringt.
Ein guter ASM progger macht weniger Fehler als ein Hochsprachen progger.
bitmaster
-
Ein guter ASM progger weis welche Register verändert werden, egal wie groß der Code ist bzw. wie viele Zeilen Code.
Wenn der Umfang größer ist - so ziemlich alle? ;) So viel weiß ich dann auch noch über meinen C-Code. Ist ja nicht so, daß der Compiler schwarze Magie wäre.
Ich weis das du meinst du seist der einzig Gute OSDever. Aber die Zeit wird kommen, in der du nicht mehr so denkst.
Prophetische Worte. ;) Aber offensichtlich hast du mir nie recht zugehört. Ich halte mich unter anderem deswegen immer wieder zurück, weil ich einfach nicht genug Ahnung vom Thema habe. Und das gebe ich auch ganz offen zu.
-
Hi,
also interrupt_disable(); und interrupt_enable();
entsprechen "cli" und "sti"...
Hab sie nun aber wie empfohlen rausgenommen :wink:
Kann mir noch jemand die Frage zu den vorletzten 2 Zeilen beantworten? :-)
Hier mal ein link zum aktuellen IMG:
http://www.hib-elemente.de/OS.img
Das ding hat bisher keinen Namen und ich beginne ja auch erst mich mit OS development zu beschäftigen... aber was haltet ihr bis jetzt davon?
Also als nächstes werde ich nun versuchen Multitasking zu implementieren, und der Keyboard-Treiber sollte auch neu geschrieben werden damit zusätzlich das deutsche Tastatur-layout unterstützt wird ;-)
-
Kann mir noch jemand die Frage zu den vorletzten 2 Zeilen beantworten? :-)
Beim Einstieg in die Funktion erstellt der C/C++ Compiler einen neuen Stackframe, d.h. er pusht ebp und setzt ebp = esp. Dadurch kann der Compiler weiterhin auf den Stackpushen und gleichzeitig die Parameter über ebp+X adressieren, ohne das man X ständig anpassen müsste. Außerdem dient dieser Stackframe dem Debuggen, da dadurch stack backtraces erst möglich werden. Man kann das aber auch bei gcc über --fomit-frame-pointer abstellen. Dieser Stackframe muss natürlich danach wieder rückgangig gemacht werden.
Problem dabei ist nur, dass du keine Möglichkeit hast das register ebp zu sichern, aber ich red scheinbar eh momentan gegen ne Mauer :-P
-
Beim Einstieg in die Funktion erstellt der C/C++ Compiler einen neuen Stackframe, d.h. er pusht ebp und setzt ebp = esp.
Problem dabei ist nur, dass du keine Möglichkeit hast das register ebp zu sichern, aber ich red scheinbar eh momentan gegen ne Mauer :-P
Man möge mir verzeihen, wenn ich Unsinn rede, dann bin ich wohl nur noch nicht richtig wach... ;) Aber das push ebp, das der Compiler macht, ist doch ein Sichern? Nur darf man halt nicht auf die Idee kommen, -fomit-frame-pointer zu benutzen, wenn man sich darauf verlassen will.
-
Aber das push ebp, das der Compiler macht, ist doch ein Sichern?
Irgendwas sagt mir, dass du Recht hast und ich nicht :-D
-
Danke für die Erklärung! Habs jetzt so einigermaßen verstanden ;-)
Wie schon erwähnt versuche ich gerade "Software"-Multitasking zu implementieren... nur klappt das nicht so wirklich... kennt ihr ein gutes Tutorial das sich damit beschäftigt :?
Am besten wärs wenn es anhand eines "C" Kernels erklärt wird! :-P
Die Lowlevel-Magazin Ausgabe 7 beschäftigt sich ja lediglich mit Hardware-Multitasking!
-
osdever.net (http://www.osdever.net/tutorials/multitasking.php) & osdever.net (http://www.osdever.net/tutorials/soft_ts.php)
-
Okay, dieses Tutorial ist genau das was ich brauche ;-)
Allerdings der dort verwendete Assembler-Code ist im Intel-Syntax :-(
Ich nutze in meinem Projekt allerdings den AT&T... (NASM für Windows)
Gibt es hierfür Converter?
Leider sind meine ASM-Kenntisse begrenzt und reichen lediglich zum verstehen was der Code macht... (kurz gesagt mir fehlt einfach die praktische Erfahrung im Assembler coden) und ich möchte mir das implementieren nicht unnötig erschweren indem ich den Code falsch übersetze :-(
-
intel2gas (http://www.niksula.hut.fi/~mtiihone/intel2gas/) (hab den aber nicht getestet)
btw. der Code im zweiten Link is AT&T Syntax :wink:
-
@bluecode:
hast recht :wink:
und ich hab deine Empfehlung umgesetzt! halte es inzwischen auch für das einzigst sinnvolle die ISR in Assembler zu implementieren!
Assembler ist gar nicht zu übel wenn man sich näher damit beschäftigt^^
Habs so gemacht:
[BITS 32] ; protected mode
[GLOBAL _hwint0]
[GLOBAL _hwint1]
; this is in our C++ code
[extern _interrupt0]
[extern _keyboard_int]
; ***************************
%macro REG_SAVE 0
;save all registers
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
%endmacro
%macro REG_RESTORE 0
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
%endmacro
%macro CLEAR_MASTER_PIC 0
mov eax, 0x20
out 0x20, al
%endmacro
_hwint0:
REG_SAVE
call _interrupt0
CLEAR_MASTER_PIC
REG_RESTORE
iret
_hwint1:
REG_SAVE
call _keyboard_int
CLEAR_MASTER_PIC
REG_RESTORE
iret
extern "C" void interrupt0(void);
void interrupt0(void)
{
//std::cout << 'X';
}
@all:
Was mich jedoch interessieren würde... welchen Asm-Syntax nutzt ihr in euren Projekten? Intel oder AT&T?
Mir fiel nämlich auf dass ich beim Inline Assembler den AT&T nutze und wenn ich eine eigne SRC-Datei hab den Intel Syntax!
(Hab mir eine Entwicklungsumgebung aufgebaut mit Eclipse-CDT in verbindung mit DJGPP)
-
Ich nutze in meinem Projekt allerdings den AT&T... (NASM für Windows)
AT&T syntax? bist du dir sicher? Hab das gefühl du vertauchst da was. Nasm ist standartmäßig im Intelsyntax und dein Code im leztetn post auch.
Edit:
Ops. Hab den Teil unter dem Code überlesen. Hatte mich halt irritrt das du geschriben(bzw. ich dich so verstanden hab) hast du würdest AT&T in Nasm benutzen.
Ich benutze Intellsyntax(auch als inline)
-
Assembler ist gar nicht zu übel wenn man sich näher damit beschäftigt^^
Für kleinere Codestücke kann man schonmal Assembler hernehmen.
Denk daran an die Slave PIC auch einen EOI zu senden bei IRQs > 7.
Was mich jedoch interessieren würde... welchen Asm-Syntax nutzt ihr in euren Projekten? Intel oder AT&T?
Ich nutze mittlerweile ausschließlich AT&T Syntax und als Assembler AS. Ich find AT&T nach ner eingewöhnungszeit eigentlich auch nicht viel komplizierter als Intel Syntax...
-
So... häng leider immer noch am Multitasking :-(
Hab versucht das Prinzip der Tutorials in meinen Kernel einzubauen, jedoch komm ich mal wieder nicht weiter und wäre froh wenn ihr mir helfen könnt!
Hier ist mein aktueller Stand, vllt. hab ich ja etwas grundlegendes übersehen oder falsch verstanden:
Die ISR:
[GLOBAL _hwint0]
[GLOBAL _hwint1]
[extern _switch_task]
[extern _p]
; this is in our C++ code
[extern _keyboard_int]
; ***************************
_hwint0:
;save all registers
pushad
mov eax,[_p] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
call _switch_task
CLEAR_MASTER_PIC
;restore all registers
mov eax,[_p] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
popad
iret
Der C/C++ Code:
typedef unsigned char uchar_t; // -->Length: 8 bit
typedef unsigned short ushort_t; // -->Length: 16 bit
typedef unsigned int uint_t; // -->Length: 32 bit
typedef unsigned long ulong_t; // -->Length: 64 bit
typedef struct {
uint_t prozess_esp; //actual position of esp
uint_t prozess_ss; //actual stack segment.
uint_t prozess_kstack; //stacktop of kernel stack
uint_t prozess_ustack; //stacktop of user stack
uint_t prozess_cr3;
uint_t prozess_number;
uint_t prozess_parent;
uint_t prozess_owner;
uint_t prozess_group;
uint_t prozess_timetorun;
uint_t prozess_sleep;
uint_t prozess_priority;
uint_t prozess_filehandle;
//console_t *prozess_console;
//memtree_t *vmm_alloc; //memory management info concerning the process
//- all its allocated virtual memory
uchar_t prozess_name[32];
} prozess_t;
typedef void (*entry_t)(void);
extern "C" void switch_task(void);
extern "C" void hwint0();
extern "C" prozess_t *p;
prozess_t *p;
void switch_task(void)
{
kernel->tasks->switch_task();
}
class_multitasking::class_multitasking()
{
p=&prozess[0];
current_p=0;
task_count=1;
}
class_multitasking::~class_multitasking() {}
void class_multitasking::switch_task()
{
++current_p;
if(current_p >= task_count)current_p=0;
p=&prozess[current_p];
//debug
char buffer[32];
itoa(current_p,buffer,10);
std::cout
<< "\nTask: "
<< buffer
<< "\n";
}
prozess_t* class_multitasking::task_anlegen(entry_t entry)
{
++task_count;
//filling in the kstack for start up:
uint_t *stacksetup; //temporary pointer
stacksetup=((uint_t*)malloc(5000))+5000;
*stacksetup--;
*stacksetup--=0x0202;
*stacksetup--=0x08;
*stacksetup--=(uint_t)entry; //This is the adress of the process' entry point (z.b. main());
*stacksetup--=0; //ebp
*stacksetup--=0; //esp
*stacksetup--=0; //edi
*stacksetup--=0; //esi
*stacksetup--=0; //edx
*stacksetup--=0; //ecx
*stacksetup--=0; //ebx
*stacksetup--=0; //eax
//filling in the struct.
prozess[task_count-1].prozess_esp=(uint_t)stacksetup;
}
Der Code für das Task-switching (::switch_task() usw.) ist nicht besonders intelligent gemacht^^
soll ja aber auch nur zum test dienen und zumindest prinzipiell funktionieren;-)
Das Ergebnis:
Nach dem Start des Kernels wird natürlich dauerhaft "Task: 0" ausgegeben... funzt also soweit! wenn ich nun einen neuen Task anlege mit: kernel->tasks->task_anlegen(test_task);
Dann sehe ich auch noch einmal "Task: 1" danach kommt es zu:
"Virutal machine kernel stack fault (hardware reset"
"The virtual machine just suffered a stack fault in kernel mode. On a real computer, this would amount to reset of the processor...."
Wie ich schon glaube rausgefunden zu haben geschieht dies genau nach dem IRET also wenn der Code des neuen Tasks ausgeführt werden soll!
Der neue Task:
void test_task();
void test_task()
{
std::cout << "XXXXXXXXXXXX-NEWTASK-XXXXXXXXXXXXXXX";
}
Achja wenn es euch lieber ist dass ich für dieses Prob. ein eigenes Thema eröffne sagt es bitte :-)
-
möglicherweise gibt dein malloc einen NULL Zeiger zurück.
Außerdem ist
stacksetup=((uint_t*)malloc(5000))+5000;
nicht korrekt. Du legst damit den Stack 20000 Bytes über dem von malloc allokierten Bereich an. Korrekt wäre:
stacksetup=(uint_t*)(((char*)malloc(5000))+5000);
Obs daran liegt ... glaub ich nicht.
-
@PorkChicken: thx, da war ich wohl nicht richtig bei der sache :roll:
Aber wie vermutet... mit dem eigentlich Problem hat es nichts zu tun :-(
-
Hat niemand eine idee :? :cry:
-
Gescheiter Emulator und exception handler? Vmware ist halt beim debuggen nicht so toll. Ich würd da dann doch eher bochs empfehlen. Und bei den Exception handlern halt alles relevante ausgeben lassen.
-
Dachte bisher eben an einen Grundlegenden Fehler der euch gleich auffällt :-)
Also mit Bochs komm ich der Sache schon näher:
"iret: return CS selector null"
Dies wird direkt vor dem neustart protokolliert!
Könnt ihr damit etwas anfangen :?
-
Lass dir doch zB vor jedem Taskswitch so Sachen wie esp oder was man halt noch so abchecken sollte, ausgeben. Vllt kommst du so der Sache näher. Oder in bochs mal einen breakpoint vor das iret und bei jedem Taskswitch den stack mit dem was zu erwarten wäre vergleichen.
-
Also bei dieser Fehlerausgabe stimmt mit Sicherheit einfach was mit den Stacks welche für den Taskswitch notwendig sind nicht. Da kann entweder was verändert, die falsche Stackadresse gespeichert oder etwas falsch gemappt sein...Schau dir deshalb beim Debuggen auch das CR3, die PageTables und die Pages an und schau ob die erwartungsgemäss stimmen.
-
edit2: vergesst einfach was da stand ^^ :oops:
-
hey also hab da noch einen Fehler gefunden:
Richtig:
*stacksetup--;
*stacksetup--=0x0202;
*stacksetup--=0x08;
*stacksetup--=(uint_t)entry;
*stacksetup--=0; //ebp
*stacksetup--=0; //esp
*stacksetup--=0; //edi
*stacksetup--=0; //esi
*stacksetup--=0; //edx
*stacksetup--=0; //ecx
*stacksetup--=0; //ebx
*stacksetup=0; //eax
Hatte ein -- zuviel am Ende ;-)
Was zur Folge hatte das ESP eins zu klein war!
Falsch:
*stacksetup--=0; //eax
(An der Stelle möchte ich noch erwähnen dass im Tutorial auch die 16Bit Register auf den Stack gesichert werden, allerdings stürzt dann gleich der ganze Kernel ab weswegen ich den Teil weggelassen hab...)
Bochs gibt mir nun folgende Fehler aus:
...
IO write to 0020 = 20
00041422055d[PIC ] signalling IRQ(0)
00041422066d[CPU0 ] IRET PROTECTED
00041422066e[CPU0 ] fetch_raw_descriptor: LDT: index (fea7)1fd4 > limit (0)
00041422066d[CPU0 ] exception(0x0D)
00041422066d[CPU0 ] interrupt(): vector = 13, INT = 0, EXT = 1
00041422066d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422084e[CPU0 ] read_virtual_checks(): read beyond limit
00041422084d[CPU0 ] exception(0x0C)
00041422084d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422084d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422102e[CPU0 ] read_virtual_checks(): read beyond limit
00041422102d[CPU0 ] exception(0x0C)
00041422102d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422102d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422120e[CPU0 ] read_virtual_checks(): read beyond limit
00041422120d[CPU0 ] exception(0x0C)
00041422120d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422120d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422138e[CPU0 ] read_virtual_checks(): read beyond limit
00041422138d[CPU0 ] exception(0x0C)
00041422138d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422138d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422156e[CPU0 ] read_virtual_checks(): read beyond limit
00041422156d[CPU0 ] exception(0x0C)
00041422156d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422156d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422174e[CPU0 ] read_virtual_checks(): read beyond limit
00041422174d[CPU0 ] exception(0x0C)
00041422174d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422174d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422192e[CPU0 ] read_virtual_checks(): read beyond limit
00041422192d[CPU0 ] exception(0x0C)
00041422192d[CPU0 ] interrupt(): vector = 12, INT = 0, EXT = 1
00041422192d[CPU0 ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00041422210e[CPU0 ] read_virtual_checks(): read beyond limit
00041422210d[CPU0 ] exception(0x0C)
...
Ich hoffe dass ich den richtigen Log-Ausschnitt erwischt habe!
Mir ist nämlich noch nicht ganz klar wie ich Breakpoints speziell für IRET setze... :|
-
Mir ist nämlich noch nicht ganz klar wie ich Breakpoints speziell für IRET setze... :|
Du musst halt herausfinden an welcher adresse sich das iret in deiner kerneldatei befindet, dann machst du für die adresse einen breakpoint.
-
@bluecode
Ja schon, sorry dass ich mich so blöde anstelle... aber wie komme ich an die Adresse? :oops:
-
Man nehme den Disassembler seiner Wahl und disassembliere seinen Kernel. Dann suche man nach dem iret. Bei allen Disassemblern steht links vom disassemblierten Opcode die Adresse an welcher dieser Opcode zu finden war. Wenn dein Dateiformat Symbolnamen unterstützt, dann kannste auch nach dem Symbol suchen unter dem iret auftaucht, dann wirds ein bisschen einfacher.
-
in bochs kanst du auch mit dem komando "show int" alle iret's (mit addresse)auflisten lassen die auftreten
-
@M.Nemo: Genial, genau das hab ich gebraucht ;-) thx
Über den internen Disassembler kam ich dann an die folgenden Adressen:
00104c20: ( ): push eax ; 50
00104c21: ( ): push ebx ; 53
00104c22: ( ): push ecx ; 51
00104c23: ( ): push edx ; 52
00104c24: ( ): push esi ; 56
00104c25: ( ): push edi ; 57
00104c26: ( ): push ebp ; 55
00104c27: ( ): push esp ; 54
00104c28: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c2d: ( ): mov dword ptr ds:[eax], esp ; 8920
00104c2f: ( ): call .+0xffffdbaa ; e8aadbffff
00104c34: ( ): mov eax, 0x00000020 ; b820000000
00104c39: ( ): out 0x20, al ; e620
00104c3b: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c40: ( ): mov esp, dword ptr ds:[eax] ; 8b20
00104c42: ( ): pop esp ; 5c
00104c43: ( ): pop ebp ; 5d
00104c44: ( ): pop edi ; 5f
00104c45: ( ): pop esi ; 5e
00104c46: ( ): pop edx ; 5a
00104c47: ( ): pop ecx ; 59
00104c48: ( ): pop ebx ; 5b
00104c49: ( ): pop eax ; 58
00104c4a: ( ): iretd ; cf
Und hier nun endlich detaillierte Infos zum Problem :-)
Die Debug-Infos betreffen folgende Situation:
->neuer Task wurde angelegt!
->ISR0: Erster Task-Switch
(Code mit dem dazugehörigen Stack/Register Status)
_hwint0:
;save all registers
REG_SAVE
| STACK 0x06b0 [0x06b4]
| STACK 0x06b2 [0x0000]
| STACK 0x06b4 [0x06f8]
| STACK 0x06b6 [0x0000]
| STACK 0x06b8 [0x6940]
| STACK 0x06ba [0x0010]
| STACK 0x06bc [0x0784]
| STACK 0x06be [0x0000]
| STACK 0x06c0 [0x0000]
| STACK 0x06c2 [0x0000]
| STACK 0x06c4 [0x0000]
| STACK 0x06c6 [0x0000]
| STACK 0x06c8 [0x8f08]
| STACK 0x06ca [0x000b]
| STACK 0x06cc [0x0000]
| STACK 0x06ce [0x0000]
eax:0x00000000, ebx:0x000b8f08, ecx:0x00000000, edx:0x00000000
ebp:0x000006f8, esp:0x000006b0, esi:0x00000784, edi:0x00106940
eip:0x00104c28, eflags:0x00000046, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=5
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
mov eax,[_p] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
| STACK 0x06b0 [0x06b4]
| STACK 0x06b2 [0x0000]
| STACK 0x06b4 [0x06f8]
| STACK 0x06b6 [0x0000]
| STACK 0x06b8 [0x6940]
| STACK 0x06ba [0x0010]
| STACK 0x06bc [0x0784]
| STACK 0x06be [0x0000]
| STACK 0x06c0 [0x0000]
| STACK 0x06c2 [0x0000]
| STACK 0x06c4 [0x0000]
| STACK 0x06c6 [0x0000]
| STACK 0x06c8 [0x8f08]
| STACK 0x06ca [0x000b]
| STACK 0x06cc [0x0000]
| STACK 0x06ce [0x0000]
eax:0x00110b91, ebx:0x000b8f08, ecx:0x00000000, edx:0x00000000
ebp:0x000006f8, esp:0x000006b0, esi:0x00000784, edi:0x00106940
eip:0x00104c2d, eflags:0x00000046, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=5
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
call _switch_task
| STACK 0x06b0 [0x06b4]
| STACK 0x06b2 [0x0000]
| STACK 0x06b4 [0x06f8]
| STACK 0x06b6 [0x0000]
| STACK 0x06b8 [0x6940]
| STACK 0x06ba [0x0010]
| STACK 0x06bc [0x0798]
| STACK 0x06be [0x0000]
| STACK 0x06c0 [0x0000]
| STACK 0x06c2 [0x0000]
| STACK 0x06c4 [0x0000]
| STACK 0x06c6 [0x0000]
| STACK 0x06c8 [0x8f30]
| STACK 0x06ca [0x000b]
| STACK 0x06cc [0x0000]
| STACK 0x06ce [0x0000]
eax:0x00306934, ebx:0x000b8f30, ecx:0x00000000, edx:0x00000000
ebp:0x000006f8, esp:0x000006b0, esi:0x00000798, edi:0x00106940
eip:0x00104c34, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=5
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
CLEAR_MASTER_PIC
;restore all registers
mov eax,[_p] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
| STACK 0x11224d [0x0000]
| STACK 0x11224f [0x0000]
| STACK 0x112251 [0x0000]
| STACK 0x112253 [0x0000]
| STACK 0x112255 [0x0000]
| STACK 0x112257 [0x0000]
| STACK 0x112259 [0x0000]
| STACK 0x11225b [0x0000]
| STACK 0x11225d [0x0000]
| STACK 0x11225f [0x0000]
| STACK 0x112261 [0x0000]
| STACK 0x112263 [0x0000]
| STACK 0x112265 [0x0000]
| STACK 0x112267 [0x0000]
| STACK 0x112269 [0x0000]
| STACK 0x11226b [0x0000]
| STACK 0x11226d [0x029e]
| STACK 0x11226f [0x0010]
| STACK 0x112271 [0x0008]
| STACK 0x112273 [0x0000]
| STACK 0x112275 [0x0202]
| STACK 0x112277 [0x0000]
| STACK 0x112279 [0x0000]
| STACK 0x11227b [0x0000]
| STACK 0x11227d [0x0ee1]
| STACK 0x11227f [0x0011]
| STACK 0x112281 [0x46a7]
| STACK 0x112283 [0x001f]
| STACK 0x112285 [0x0000]
| STACK 0x112287 [0x0000]
| STACK 0x112289 [0x0000]
| STACK 0x11228b [0x0000]
| STACK 0x11228d [0x0000]
| STACK 0x11228f [0x0000]
| STACK 0x112291 [0x0000]
eax:0x00110be5, ebx:0x000b8f30, ecx:0x00000000, edx:0x00000000
ebp:0x000006f8, esp:0x0011224d, esi:0x00000798, edi:0x00106940
eip:0x00104c42, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=5
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
REG_RESTORE
| STACK 0x001c [0xff53]
| STACK 0x001e [0xf000]
| STACK 0x0020 [0xfea5]
| STACK 0x0022 [0xf000]
| STACK 0x0024 [0xe987]
| STACK 0x0026 [0xf000]
| STACK 0x0028 [0xff53]
| STACK 0x002a [0xf000]
| STACK 0x002c [0xff53]
| STACK 0x002e [0xf000]
| STACK 0x0030 [0xff53]
| STACK 0x0032 [0xf000]
| STACK 0x0034 [0xff53]
| STACK 0x0036 [0xf000]
| STACK 0x0038 [0xef57]
| STACK 0x003a [0xf000]
| STACK 0x003c [0xff53]
| STACK 0x003e [0xf000]
| STACK 0x0040 [0x0116]
| STACK 0x0042 [0xc000]
| STACK 0x0044 [0xf84d]
| STACK 0x0046 [0xf000]
| STACK 0x0048 [0xf841]
| STACK 0x004a [0xf000]
| STACK 0x004c [0xe3fe]
| STACK 0x004e [0xf000]
| STACK 0x0050 [0xe739]
| STACK 0x0052 [0xf000]
| STACK 0x0054 [0xf859]
| STACK 0x0056 [0xf000]
eax:0xf000ff53, ebx:0xf000ff53, ecx:0xf000ff53, edx:0xf000ff53
ebp:0xf000ff53, esp:0x0000001c, esi:0xf000ff53, edi:0xf000ff53
eip:0x00104c4a, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=5
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
iret
00022437138e[CPU0 ] fetch_raw_descriptor: LDT: index (fea7)1fd4 > limit (0)
00022437138: exception (not softint) 0008:001049e6 (0x001049e6)
00022437138: iret 0008:001049e6 (0x001049e6)
00022437156e[CPU0 ] read_virtual_checks(): read beyond limit
00022437156: exception (not softint) 0008:00104a0e (0x00104a0e)
00022437174e[CPU0 ] read_virtual_checks(): read beyond limit
00022437174: exception (not softint) 0008:00104a0e (0x00104a0e)
00022437192e[CPU0 ] read_virtual_checks(): read beyond limit
00022437192: exception (not softint) 0008:00104a0e (0x00104a0e)
00022437210e[CPU0 ] read_virtual_checks(): read beyond limit
00022437210: exception (not softint) 0008:00104a0e (0x00104a0e)
00022437228e[CPU0 ] read_virtual_checks(): read beyond limit
00022437228: exception (not softint) 0008:00104a0e (0x00104a0e)
...
-
Meiner Meinung nach müsste der Stack nach REG_RESTORE folgendermaßen aussehen:
| STACK 0x11226d [0x029e]
| STACK 0x11226f [0x0010]
| STACK 0x112271 [0x0008]
| STACK 0x112273 [0x0000]
| STACK 0x112275 [0x0202]
| STACK 0x112277 [0x0000]
und nicht:
| STACK 0x001c [0xff53]
| STACK 0x001e [0xf000]
| STACK 0x0020 [0xfea5]
| STACK 0x0022 [0xf000]
| STACK 0x0024 [0xe987]
| STACK 0x0026 [0xf000]
| STACK 0x0028 [0xff53]
| STACK 0x002a [0xf000]
| STACK 0x002c [0xff53]
| STACK 0x002e [0xf000]
| STACK 0x0030 [0xff53]
| STACK 0x0032 [0xf000]
| STACK 0x0034 [0xff53]
| STACK 0x0036 [0xf000]
| STACK 0x0038 [0xef57]
| STACK 0x003a [0xf000]
| STACK 0x003c [0xff53]
| STACK 0x003e [0xf000]
| STACK 0x0040 [0x0116]
| STACK 0x0042 [0xc000]
| STACK 0x0044 [0xf84d]
| STACK 0x0046 [0xf000]
| STACK 0x0048 [0xf841]
| STACK 0x004a [0xf000]
| STACK 0x004c [0xe3fe]
| STACK 0x004e [0xf000]
| STACK 0x0050 [0xe739]
| STACK 0x0052 [0xf000]
| STACK 0x0054 [0xf859]
| STACK 0x0056 [0xf000]
Hoffentlich könnt ihr dazu mehr sagen, ich bin Ratlos :|
Edit:
Glaube gerade noch auf die schnelle den oder einen Fehler gefunden zu haben... werde das heute Abend genauer untersuchen:
Natürlich darf ich esp nicht vom Stack popen! Sonst sitzt der Stack plötzlich auf Adresse 0 :wink: :roll: :roll: :roll:
wird hier deutlicher:
00104c20: ( ): push eax ; 50
00104c21: ( ): push ebx ; 53
00104c22: ( ): push ecx ; 51
00104c23: ( ): push edx ; 52
00104c24: ( ): push esi ; 56
00104c25: ( ): push edi ; 57
00104c26: ( ): push ebp ; 55
00104c27: ( ): push esp ; 54
00104c28: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c2d: ( ): mov dword ptr ds:[eax], esp ; 8920
00104c2f: ( ): call .+0xffffdbaa ; e8aadbffff
00104c34: ( ): mov eax, 0x00000020 ; b820000000
00104c39: ( ): out 0x20, al
| STACK 0x06b0 [0x06b4]
| STACK 0x06b2 [0x0000]
| STACK 0x06b4 [0x06f8]
| STACK 0x06b6 [0x0000]
| STACK 0x06b8 [0x6940]
| STACK 0x06ba [0x0010]
| STACK 0x06bc [0x07ac]
| STACK 0x06be [0x0000]
| STACK 0x06c0 [0x0000]
| STACK 0x06c2 [0x0000]
| STACK 0x06c4 [0x0000]
| STACK 0x06c6 [0x0000]
| STACK 0x06c8 [0x8f58]
| STACK 0x06ca [0x000b]
| STACK 0x06cc [0x0000]
| STACK 0x06ce [0x0000]
00104c3b: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c40: ( ): mov esp, dword ptr ds:[eax] ; 8b20
-> Hier ist der Stack so wie er sein sollte
| STACK 0x11224d [0x0000]
| STACK 0x11224f [0x0000]
| STACK 0x112251 [0x0000]
| STACK 0x112253 [0x0000]
| STACK 0x112255 [0x0000]
| STACK 0x112257 [0x0000]
| STACK 0x112259 [0x0000]
| STACK 0x11225b [0x0000]
| STACK 0x11225d [0x0000]
| STACK 0x11225f [0x0000]
| STACK 0x112261 [0x0000]
| STACK 0x112263 [0x0000]
| STACK 0x112265 [0x0000]
| STACK 0x112267 [0x0000]
| STACK 0x112269 [0x0000]
| STACK 0x11226b [0x0000]
| STACK 0x11226d [0x029e]
| STACK 0x11226f [0x0010]
| STACK 0x112271 [0x0008]
| STACK 0x112273 [0x0000]
| STACK 0x112275 [0x0202]
| STACK 0x112277 [0x0000]
| STACK 0x112279 [0x0000]
| STACK 0x11227b [0x0000]
| STACK 0x11227d [0x0ee1]
| STACK 0x11227f [0x0011]
| STACK 0x112281 [0x46a7]
| STACK 0x112283 [0x001f]
| STACK 0x112285 [0x0000]
| STACK 0x112287 [0x0000]
00104c42: ( ): pop esp ; 5c
-> Hier nichtmehr
| STACK 0x0000 [0xff53]
| STACK 0x0002 [0xf000]
| STACK 0x0004 [0xff53]
| STACK 0x0006 [0xf000]
| STACK 0x0008 [0xff53]
| STACK 0x000a [0xf000]
| STACK 0x000c [0xff53]
| STACK 0x000e [0xf000]
| STACK 0x0010 [0xff53]
| STACK 0x0012 [0xf000]
| STACK 0x0014 [0xff53]
| STACK 0x0016 [0xf000]
| STACK 0x0018 [0xff53]
| STACK 0x001a [0xf000]
| STACK 0x001c [0xff53]
| STACK 0x001e [0xf000]
| STACK 0x0020 [0xfea5]
| STACK 0x0022 [0xf000]
| STACK 0x0024 [0xe987]
| STACK 0x0026 [0xf000]
| STACK 0x0028 [0xff53]
| STACK 0x002a [0xf000]
| STACK 0x002c [0xff53]
| STACK 0x002e [0xf000]
| STACK 0x0030 [0xff53]
| STACK 0x0032 [0xf000]
| STACK 0x0034 [0xff53]
| STACK 0x0036 [0xf000]
| STACK 0x0038 [0xef57]
| STACK 0x003a [0xf000]
00104c43: ( ): pop ebp ; 5d
00104c44: ( ): pop edi ; 5f
00104c45: ( ): pop esi ; 5e
00104c46: ( ): pop edx ; 5a
00104c47: ( ): pop ecx ; 59
00104c48: ( ): pop ebx ; 5b
00104c49: ( ): pop eax ; 58
00104c4a: ( ): iretd ; cf
Edit2:
Der Fehler hat sich bestätigt! Ganz einfach, aber hab dies die ganze Zeit übersehen :oops:
Naja aufjedenfall bin ich ein Schritt weiter un der Stack sieht vor dem IRET endlich so aus wie "bisher" gewünscht...
Stack genau wie ich ihn der der Funktion class_multitasking::task_anlegen(entry_t entry) generiere :-) :
| STACK 0x11226d [0x029e]
| STACK 0x11226f [0x0010]
| STACK 0x112271 [0x0008]
| STACK 0x112273 [0x0000]
| STACK 0x112275 [0x0202]
| STACK 0x112277 [0x0000]
| STACK 0x112279 [0x0000]
| STACK 0x11227b [0x0000]
| STACK 0x11227d [0x0ee1]
| STACK 0x11227f [0x0011]
| STACK 0x112281 [0x46a7]
| STACK 0x112283 [0x001f]
| STACK 0x112285 [0x0000]
| STACK 0x112287 [0x0000]
| STACK 0x112289 [0x0000]
| STACK 0x11228b [0x0000]
Allerdings führt die CPU nun ein IRET aus bekomme ich wieder:
00019364120e[CPU0 ] iret: return CS selector null
00019364138e[CPU0 ] read_virtual_checks(): read beyond limit
00019364156e[CPU0 ] read_virtual_checks(): read beyond limit
00019364174e[CPU0 ] read_virtual_checks(): read beyond limit
00019364192e[CPU0 ] read_virtual_checks(): read beyond limit
00019364210e[CPU0 ] read_virtual_checks(): read beyond limit
00019364228e[CPU0 ] read_virtual_checks(): read beyond limit
00019364246e[CPU0 ] read_virtual_checks(): read beyond limit
...
:cry:
-
Wie im IRC besprochen habe ich hier nochmal eine Zusammenfassung des Problems!
Die ISR:
_hwint0:
;save all registers
pushad
push ds
push es
push fs
push gs
mov eax,[_p] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
;switch Task (C-Code)
call _switch_task
;clear PIC
CLEAR_MASTER_PIC
;refresh esp (Stack-Pointer)
mov eax,[_p] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
;restore all registers
pop gs
pop fs
pop es
pop ds
popad
iretd
Die ISR (Debugger):
00104c10: ( ): pushad ; 60
00104c11: ( ): push ds ; 1e
00104c12: ( ): push es ; 06
00104c13: ( ): push fs ; 0fa0
00104c15: ( ): push gs ; 0fa8
00104c17: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c1c: ( ): mov dword ptr ds:[eax], esp ; 8920
00104c1e: ( ): call .+0xffffdbaf ; e8afdbffff
00104c23: ( ): mov eax, 0x00000020 ; b820000000
00104c28: ( ): out 0x20, al ; e620
00104c2a: ( ): mov eax, dword ptr ds:0x306930 ; a130693000
00104c2f: ( ): mov esp, dword ptr ds:[eax] ; 8b20
00104c31: ( ): pop gs ; 0fa9
00104c33: ( ): pop fs ; 0fa1
00104c35: ( ): pop es ; 07
00104c36: ( ): pop ds ; 1f
00104c37: ( ): popad ; 61
00104c38: ( ): iretd ; cf
Code des neuen Tasks (soweit kommt es erst garnicht):
001000b0: ( ): push ebp ; 55
001000b1: ( ): mov ebp, esp ; 89e5
001000b3: ( ): cli ; fa
001000b4: ( ): hlt ; f4
001000b5: ( ): pop ebp ; 5d
001000b6: ( ): ret ; c3
Dump direkt vor IRETD (nur ein Task, kein Switch / ohne Fehler):
| STACK 0x070c [0x17c3]
| STACK 0x070e [0xff80]
| STACK 0x0710 [0x0008]
| STACK 0x0712 [0x0000]
| STACK 0x0714 [0x0246]
| STACK 0x0716 [0x0000]
| STACK 0x0718 [0x07d0]
| STACK 0x071a [0x0000]
| STACK 0x071c [0x0fff]
| STACK 0x071e [0x0000]
| STACK 0x0720 [0xcccd]
| STACK 0x0722 [0xcccc]
| STACK 0x0724 [0x0000]
| STACK 0x0726 [0x0000]
| STACK 0x0728 [0x0788]
| STACK 0x072a [0x0000]
eax:0x00000000, ebx:0x00000016, ecx:0x00000000, edx:0x000003d5
ebp:0x00000728, esp:0x0000070c, esi:0x00000fff, edi:0x000c3000
eip:0x00104c38, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
fs:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
gs:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
Dump direkt vor IRETD (erster Taskswitch, neuer Stack / Fehler):
| STACK 0x11226d [0x00b0]
| STACK 0x11226f [0x0010]
| STACK 0x112271 [0x0008]
| STACK 0x112273 [0x0000]
| STACK 0x112275 [0x0246]
| STACK 0x112277 [0x0000]
| STACK 0x112279 [0x0000]
| STACK 0x11227b [0x0000]
| STACK 0x11227d [0x0ee1]
| STACK 0x11227f [0x0011]
| STACK 0x112281 [0x46a7]
| STACK 0x112283 [0x001f]
| STACK 0x112285 [0x0000]
| STACK 0x112287 [0x0000]
| STACK 0x112289 [0x0000]
| STACK 0x11228b [0x0000]
eax:0x00000000, ebx:0x00000000, ecx:0x00000000, edx:0x00000000
ebp:0x00000000, esp:0x0011226d, esi:0x00000000, edi:0x00000000
eip:0x00104c38, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000fbff, dh=0x00cf9a00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
es:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
fs:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
gs:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00007dcc, limit=0x17
idtr:base=0x00106018, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x0009e000, cr4:0x00000000
Der Fehler (direkt nach IRETD):
00015057973e[CPU0 ] iret: return CS selector null
Danke für eure Hilfe :-)
-
Problem gelöst! :-) :-) :-) :-) :-)
Detaillierte Infos kommen demnächst...
-
Mehr Infos (LÖSUNG)
Wie mir empfohlen worden ist hab ich den Bootloader umgestellt, und zwar von bootf02 (www.osdever.net) auf Grub!
Die exakte Ursache weis ich leider nicht, aber hab inzwischen herausgefunden das der alte startcode paging aktiviert, und grub eben nicht, auserdem werden bei einem Stack-Dump nun 32Bit Werte angezeigt (bei den alten dumps, [siehe oben] waren es 16Bit??!!).... :|
Inzwischen kann ich Grub nur empfehlen da dieser auch z. B. Möglichkeiten bietet die RAM-Größe auszulesen!
Hier noch aktuelle Debug-Infos über Regsiter und Stack-Zustand direkt vor IRETD:
_hwint0:
cli
;save all registers
pushad
push ds
push es
push fs
push gs
mov eax,[_process] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
;switch Task (C-Code)
call _switch_task
;clear PIC
CLEAR_MASTER_PIC
;refresh esp (Stack-Pointer)
mov eax,[_process] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
;restore all registers
pop gs
pop fs
pop es
pop ds
popad
iretd
001031b0: ( ): cli ; fa
001031b1: ( ): pushad ; 60
001031b2: ( ): push ds ; 1e
001031b3: ( ): push es ; 06
001031b4: ( ): push fs ; 0fa0
001031b6: ( ): push gs ; 0fa8
001031b8: ( ): mov eax, dword ptr ds:0x106840 ; a140681000
001031bd: ( ): mov dword ptr ds:[eax], esp ; 8920
001031bf: ( ): call .+0xffffe472 ; e872e4ffff
001031c4: ( ): mov eax, 0x00000020 ; b820000000
001031c9: ( ): out 0x20, al ; e620
001031cb: ( ): mov eax, dword ptr ds:0x106840 ; a140681000
001031d0: ( ): mov esp, dword ptr ds:[eax] ; 8b20
001031d2: ( ): pop gs ; 0fa9
001031d4: ( ): pop fs ; 0fa1
001031d6: ( ): pop es ; 07
001031d7: ( ): pop ds ; 1f
001031d8: ( ): popad ; 61
001031d9: ( ): iretd ; cf
| STACK 0x00067d7c [0x00101f53]
| STACK 0x00067d80 [0x00000008]
| STACK 0x00067d84 [0x00000246]
| STACK 0x00067d88 [0x00067d02]
| STACK 0x00067d8c [0x00067da0]
| STACK 0x00067d90 [0x00101019]
| STACK 0x00067d94 [0x00000000]
| STACK 0x00067d98 [0x00067db8]
| STACK 0x00067d9c [0x001040f0]
| STACK 0x00067da0 [0x0011062d]
| STACK 0x00067da4 [0x00104054]
| STACK 0x00067da8 [0x00000019]
| STACK 0x00067dac [0x00000002]
| STACK 0x00067db0 [0x00000000]
| STACK 0x00067db4 [0x40067de4]
| STACK 0x00067db8 [0x00067e38]
| STACK 0x00067dbc [0x00101390]
| STACK 0x00067dc0 [0x0011061c]
| STACK 0x00067dc4 [0x00101019]
| STACK 0x00067dc8 [0x0000000a]
| STACK 0x00067dcc [0x20202020]
| STACK 0x00067dd0 [0x20202020]
| STACK 0x00067dd4 [0x00106884]
| STACK 0x00067dd8 [0x203a726f]
| STACK 0x00067ddc [0x20200a00]
eax:0x00000000, ebx:0x0011062d, ecx:0x000b8f9e, edx:0x000003d5
ebp:0x00067d98, esp:0x00067d7c, esi:0x00067e5c, edi:0x00067e24
eip:0x001031d9, eflags:0x00000006, inhibit_mask:0
cs:s=0x0008, dl=0x0000ffff, dh=0x00cf9a00, valid=1
ss:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
es:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
fs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
gs:s=0x0010, dl=0x0000ffff, dh=0x00cf9300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00008f5c, limit=0x27
idtr:base=0x00106028, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000011, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
Danke an alle die mir bei diesem Problem geholfen haben!
Wird sicher nicht lange dauern bis ich euch wieder belästige :roll: :-P