Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: OS_3000 am 03. December 2012, 18:39
-
Also ich wollte mal nach langer Zeit mal wieder an meinem OS weiterarbeiten.
Das Problem ist, der Kernel löst nach dem 400 Timerinterupt beim Taskwechsel vom 1. Prozess zurück in den 0. eine Generall Protection Exception (13) aus.
Da das Multitasking aus mehreren größeren Dateien besteht, hab ich es angehängt.
Wäre um einen Tipp, wie ich dem Fehler zu Leibe rücken kann, sehr dankbar. :-)
Was mich so irritiert ist, dass der Taskwechsel vorher einigemale klappt.
Die Textdatei im Anhang ist eine falsche 7-Zip-Datei, damit ich sie hochladen kann.
Warum sind hier keine Zipdateien erlaubt? Finde ich ziemlich umständlich. :wink:
-
Weil du den Code erstmal selber debuggen sollst. ;)
Die erste interessante Frage wäre, welcher Code an eip = 0x1024a3 ist.
-
Wie kriege ich denn raus, welcher Code an 0x1024a3 liegt?
Debuggen algemein ist in der Betriebssystementwicklung ja generel eher schwer möglich.
Das einzige was ich sicher weiß ist noch, dass der Fehler nicht auftrit, wenn ich "Console_WriteChar" in den Multitaskthreads auskommentiere...
init.c
void Write0()
{
while(true)
{
//halt();
Console_WriteChar('0');
for(int i = 0; i < 0x6fffff; i++) nop10();
}
}
void WriteX()
{
while(true)
{
//halt();
Console_WriteChar('X');
for(int i = 0; i < 0x6fffff; i++) nop10();
}
}
void main(Multiboot_Info* MultibootInfo)
{
Time_Read(&StartTime);
Console_ClearScreen();
Console_WriteHeader("Kernel gestartet!");
Console_Write("Bootloader: ");
Console_WriteLine(MultibootInfo->BootloaderName);
Console_Write("Prozessorhersteller: ");
int Processorvendor = CpuId_ReadVendor();
Console_WriteVendor(Processorvendor);
Console_NewLine();
if (Processorvendor == CPUID_VENDOR_INTEL)
{
Console_Write("Prozessortype: ");
Console_WriteIntelProcName();
Console_NewLine();
}
Console_Write("Startzeit: ");
Console_WriteTime(&StartTime);
Console_NewLine(); Console_NewLine();
Console_WriteHeader("Lade Kernel");
Gdt_Init();
ProcessCount = 2;
Processes[0] = Process_New();
Processes[0].Threads[0] = Thread_New(Proc0Thread0Stack, THREAD_STACKSIZE, Proc0Thread0UserStack, THREAD_USERSTACKSIZE, &WriteX);
Processes[1] = Process_New();
Processes[1].Threads[0] = Thread_New(Proc1Thread0Stack, THREAD_STACKSIZE, Proc1Thread0UserStack, THREAD_USERSTACKSIZE, &Write0);
Intr_Init();
stop();
}
console.c
#define CONSOLE_LINELENGTH (80)
#define CONSOLE_LINECOUNT (25)
#define CONSOLE_CHARCOUNT (CONSOLE_LINECOUNT * CONSOLE_LINELENGTH)
#define CONSOLE_VIDEO ((uint16_t*) 0xb8000)
__attribute__((unused)) uint32_t Console_Curser = 0;
__attribute__((unused)) uint32_t Console_UsingLines = 23;
__attribute__((unused)) uint8_t Console_Format = 0x07;
__attribute__((unused)) bool Console_ShowCurser = true;
[...] //Sehr viel jetzt nicht relevanter Code
void Console_ShiftUp()
{
for(int i = 0; i < CONSOLE_CHARCOUNT; i++)
{
if (i < (CONSOLE_CHARCOUNT - CONSOLE_LINELENGTH))
{
//Untere Zeile nach oben kopieren
CONSOLE_VIDEO[i] = CONSOLE_VIDEO[i + CONSOLE_LINELENGTH];
}
else
{
//Unterste Zeile leeren
CONSOLE_VIDEO[i] = ((uint16_t)EMPTYCHAR) | (((uint16_t)Console_Format) << 8);
}
}
//Curser eine Zeile nach oben verschieben
Console_Curser -= CONSOLE_LINELENGTH;
Console_CurserMove();
}
void Console_NewLine()
{
//Zeiger platzieren
Console_Curser -= Console_Curser % CONSOLE_LINELENGTH;
Console_Curser += CONSOLE_LINELENGTH;
//Zeilen hochschieben wenn nötig
if (Console_UsingLines >= (Console_Curser * CONSOLE_LINELENGTH))
{
Console_ShiftUp();
}
}
void Console_WriteChar(const char Char)
{
//Zeiger platzieren
if (Char == NEWLINE)
{
Console_NewLine();
return;
}
//Zeilen hochschieben wenn nötig
if ((Console_Curser / CONSOLE_LINELENGTH) >= Console_UsingLines)
{
Console_ShiftUp();
}
//Zeichen schreiben
CONSOLE_VIDEO[Console_Curser++] = ((uint16_t)Char) | (((uint16_t)Console_Format) << 8);
}
-
objdump -dS kernel > kernel.txt
disasembliert deinen kernel.
dort nach 0x1024a3 suchen und dann weißt du es
-
Ok, danke für den Tipp. Werde ich versuchen.
Ich habe derweil meinen vorherigen Post "überarbeitet". :wink:
EDIT:
Das hat schonmal wirklich geholfen. :-)
Ein Geheimtipp den ich mir unbedingt merken sollte.
Den Assemblerausschnitt bei der Adresse:
00102490 <Console_CurserMove>:
102490: 55 push %ebp
102491: 89 e5 mov %esp,%ebp
102493: 80 3d 65 68 10 00 00 cmpb $0x0,0x106865
10249a: 74 22 je 1024be <Console_CurserMove+0x2e>
10249c: ba d4 03 00 00 mov $0x3d4,%edx
1024a1: b0 0e mov $0xe,%al
1024a3: ee out %al,(%dx) ;Hier kracht es...
1024a4: 8b 0d 30 69 10 00 mov 0x106930,%ecx
1024aa: 89 c8 mov %ecx,%eax
1024ac: c1 e8 08 shr $0x8,%eax
1024af: b2 d5 mov $0xd5,%dl
1024b1: ee out %al,(%dx)
1024b2: b2 d4 mov $0xd4,%dl
1024b4: b0 0f mov $0xf,%al
1024b6: ee out %al,(%dx)
1024b7: b2 d5 mov $0xd5,%dl
1024b9: 88 c8 mov %cl,%al
1024bb: ee out %al,(%dx)
1024bc: eb 17 jmp 1024d5 <Console_CurserMove+0x45>
1024be: ba d4 03 00 00 mov $0x3d4,%edx
1024c3: b0 0e mov $0xe,%al
1024c5: ee out %al,(%dx)
1024c6: b2 d5 mov $0xd5,%dl
1024c8: b0 07 mov $0x7,%al
1024ca: ee out %al,(%dx)
1024cb: b2 d4 mov $0xd4,%dl
1024cd: b0 0f mov $0xf,%al
1024cf: ee out %al,(%dx)
1024d0: b2 d5 mov $0xd5,%dl
1024d2: b0 d0 mov $0xd0,%al
1024d4: ee out %al,(%dx)
1024d5: 5d pop %ebp
1024d6: c3 ret
Es scheint es Probleme beim "out"-Befehl zu geben.
Aber nur im Multitasking. Im Kernel funktioniert es.
Liege ich mit meiner Vermutung richtig, dass ich zum Lösen des Problemes Syscalls einbauen müsste?
-
Du kannst vorläufig auch IOPL (I/O privilege level) auf 3 setzen, dann darf der Userspace in/out benutzen. Auf Dauer willst du das aber nicht haben, sonst könnte jedes beliebige Programm mit jeder Hardware herumhantieren. Nicht gut für die Sicherheit. ;)