Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - BurningWave

Seiten: [1]
1
Lowlevel-Coding / Re: Paging und Multitasking
« am: 13. April 2012, 18:17 »
So mein kleines OS ist nach langer Arbeit endlich in einen ansehnlichen Zustand gekommen:

http://www.jbtechnologies.de/projects/programms/badmem-os.html

Danke nochmal für eure Hilfe.
2
Lowlevel-Coding / Re: Paging und Multitasking
« am: 18. March 2012, 16:21 »
Es funktioniert :) :)

Ich musste nur noch das PD des Tasks mit dem User-Flag und writeable mappen, sonst funktioniert es nicht. Bis man darauf kommt...
Auf jeden Fall vielen Dank für eure Hilfe.
3
Lowlevel-Coding / Re: Paging und Multitasking
« am: 17. March 2012, 17:37 »
Ring-3-Code braucht gar keinen Zugriff auf den Kernel, Ring-0-Code braucht ihn. Du hast Ring-0-Code, der mit dem PD des Tasks läuft, also musst du in diesem PD alle Pages gemappt haben, die dieser Ring-0-Code benutzt. Du musst das User-Bit für diese Pages aber nicht gesetzt haben, weil es ja schließlich Ring-0-Code ist, der auch auf Kernelpages zugreifen darf.

Genau das ist das Problem. Im PD des Tasks ist der komplette Kernel ohne User-Flag gemappt. Jetzt brauche ich den Speicherbereich der Task-Funktion, um in diesem Bereich das User-Bit zu setzen.
4
Lowlevel-Coding / Re: Paging und Multitasking
« am: 17. March 2012, 17:21 »
Das zweite Problem mit den Page Faults konnte ich endlich lösen :)

Doch zum ersten Problem: Es kann ja keine Lösung sein, den kompletten Kernel für User-Tasks writeable zu mappen (in diesem Fall wäre Paging komplett sinnlos). Wenn ich nun nur bestimmte Stellen für User-Tasks sichtbar machen möchte, ergibt sich das Problem, wie ich den Adressraum der Funktion des jeweiligen Tasks bekomme. Ein Funktionszeiger auf die Funktion sagt mir, wo diese anfängt, aber wie bekomme ich deren Länge?

Ich habe noch eine Frage: Ein return innerhalb eines Tasks lässt den Instruction Pointer doch irgendwo ins Nirvana springen. Wie kann man dieses Problem handhaben?
5
Lowlevel-Coding / Re: Paging und Multitasking
« am: 16. March 2012, 14:23 »
Vielleicht liegt es tatsächlich am TSS. Es beinhaltet eigentlich nur zwei Werte. SS0 ist 0x10 und bei ESP0 bin ich mir nicht ganz sicher. Ich muss ja diesen Wert bei jedem Task Change anpassen. Ich habe noch nicht ganz verstanden, was ich angegeben soll. Muss ich die Adresse des Stacks des aufzurufenden Tasks angeben?
6
Lowlevel-Coding / Re: Paging und Multitasking
« am: 15. March 2012, 23:02 »
Dieses Problem wäre auch gelöst. Es hatte nichts mit den Segmentregistern zu tun, diese dürften richtig gesetzt sein, sondern vielmehr mit einem Stückchen Assemblercode, das an der falschen Stelle stand. Aber geholfen hat das nichts. Jetzt bekomme ich wieder Pagefaults :S Zum einen bekomme ich beim Eintritt in den Ring 3 einen Page Fault, wenn der Kernel nicht zum Schreiben gemappt ist. Das ist das geringere Übel, ich muss eben noch herausfinden, welche Kernelbereiche für Ring 3 Tasks zum Schreiben gemappt sein müssen. Durch ein wenig Experimentieren müsste ich die Lösung finden. Das größere Übel besteht darin, dass es bei der Rückkehr in den Ring 0 crasht. Irgendwie werden die Kernelsegmente bzw. der Kernelstack nicht geladen.

Vielleicht wäre der Code des Interrupthandlers relevant:
extern "C" CPU_State *InterruptCallback(CPU_State *cpu)
{
    Task *task = NULL;

    if(cpu->intr <= 0x1f)
    {
        if(cpu->intr == 8 || cpu->intr == 18)
        {
            [...] Fehler behandeln
        }
    }
    else if(cpu->intr >= 0x20 && cpu->intr <= 0x2f)
    {
        if(cpu->intr == 0x20 && TaskMgr.GetSchedulingState())
        {
            task = TaskMgr.Schedule(cpu);
            gdt.TSSSetCPU(uint32_t(task->CPU + 1));     // void GDT::TSSSetCPU(uint32_t cpu) {tss[1] = cpu;}
        }

        if(cpu->intr >= 0x28)
            outportb(0xa0, 0x20);   // EOI an Slave-PIC
        outportb(0x20, 0x20);       // EOI an Master-PIC
    }
    else if(cpu->intr >= 255)
    {
        [...] Fehler behandeln
    }

    cpu = idt.callback(cpu);

    if(task)
    {
        cpu = task->CPU;
        if(task->MContext)
        {
            M.ActivateContext(task->MContext);
            asm volatile (          // User-Datensegmente laden
                "mov $0x23, %ax;"
                "mov %ax, %ds;"
                "mov %ax, %es;"
            );
        }
        else
            M.ActivateKernelContext();          // Kernel-Datensegmente wurden schon in Assemblerteil, der diese Routine aufruft, geladen
    }

    return cpu;
}

Ich bin so langsam wirklich am Verzweifeln -.-
7
Lowlevel-Coding / Re: Paging und Multitasking
« am: 15. March 2012, 18:05 »
Also es gibt neues: Das mit dem Pagefault konnte ich beheben. Es war noch ein Fehler bezüglich des Kontextwechsels im Code. Die 2 Stacks (Userstack und Interruptstack) der Tasks werden nun nur für den jeweiligen Task (NICHT für den Kernel) gemappt. Ist das in Ordnung oder muss der Kernel Zugriff auf den Interruptstack haben?
So weit, so gut, jetzt habe ich ein neues Problem: Ich bekomme einen General Protection Fault bei iret, bevor mein Task aufgerufen wird (Speicherkontext ist zu diesem Zeitpunkt schon gewechselt). Woran könnte das liegen (mein Interrupthandler (insbesondere der Assemblerteil) sieht im Wesentlichen so aus, wie der im Tutorial)?
8
Lowlevel-Coding / Re: Paging und Multitasking
« am: 12. March 2012, 23:08 »
Ja, das ist definitiv auch gesetzt.
9
Lowlevel-Coding / Re: Paging und Multitasking
« am: 11. March 2012, 21:21 »
Ich habe es jetzt mit objdump überprüft. Der Pagefault (Errorcode 5) tritt definitiv bei iret auf. Der Instruction Pointer zeigt auf die 1. Anweisung im User-Task. Woran kann das liegen? Eigentlich ist der komplette Kernel für den Task mit User-Berechtigung gemappt (also alles von der 1MB-Marke, wo der Kernel beginnt), bis zu der Stelle, an der zuletzt Speicher reserviert wurde, bevor Multitasking aktiviert wurde). Aus dem Error-Code schließe ich, dass die angeforderte Seite present ist, jedoch nicht mit dem User-Flag (0x4) gemappt wurde. Wie passt das zusammen?
10
Lowlevel-Coding / Re: Paging und Multitasking
« am: 07. March 2012, 23:24 »
Hm, mir ist schon klar, warum der Kernel und die verschiedenen Tasks je einen egenen Stack haben sollten, aber warum braucht ein Task nach dem Tutorial von hier zwei Stacks (User Stack und Stack)? Würde nicht einer reichen? Wenn ich schon beide brauche, für wen müssen diese jeweils gemappt sein?

Und ich hätte noch eine andere Frage. Wie kann ich möglichst einfach herausfinden, welche Codestelle zu einer bestimmten Adresse, die der Instruction Pointer beinhaltet, gehört? Welche Tools gibt es hierfür?

Sorry, falls meine vielen Fragen etwas nervig sein sollten, aber ich verzweifle echt an diesem Multitasking...
11
Lowlevel-Coding / Re: Paging und Multitasking
« am: 03. March 2012, 18:34 »
Gut, Paging sollte nun endlich funktionieren. Jedoch bekomme ich beim Wechsel Ring0 -> Ring3 einen Pagefault. Ich vermute, dass das irgendwie mit dem Userstack bzw. dem normalen Stack zu tun hat (wieso braucht man für einen Task eigentlich zwei? - Das habe ich noch nicht ganz verstanden). Mein Taskmanager orientiert sich an diesem Tutorial: http://www.lowlevel.eu/wiki/Teil_6_-_Multitasking

Hier ist die Funktion, die einen Task erstellt:
void TaskManager::CreateTask(TASK_FUNCTION f, const char *Name, VideoPipe *VPipe)
{
    Task t;
    t.ID = ++TaskRunCount;
    memcpy(t.Name, Name, 39);
    t.Name[39] = '\0';
    t.MContext = M.CreateContext(); // Speicherkontext für Task erstellen (Mapping des Kernelcodes und des gesamten Stacks werden in neus Mapping aufgenommen)
    t.Stack = (uint8_t *)M.alloc(t.MContext); // Ich vermute, dass der Fehler an dieser oder der fogenden Zeile liegt.
    t.UserStack = (uint8_t *)M.alloc(t.MContext); // Parameter gibt den Kontext an, für den der zu reservierende Speicher gemappt wird (hier also für den Task)
    t.VPipe = VPipe;

    CPU_State CPU;
    CPU.eax = CPU.ebx = CPU.ecx = CPU.edx = CPU.esi = CPU.edi = CPU.ebp = 0;
    CPU.esp = (uint32_t)t.UserStack + 4096;
    CPU.eip = (uint32_t)f;
    CPU.cs = 0x18 | 0x03;
    CPU.ss = 0x20 | 0x03;
    CPU.eflags = 0x200;
    t.CPU = (CPU_State *)(t.Stack + 4096 - sizeof(CPU));
    *t.CPU = CPU;

    TaskList.Append(t);
}

Wie soll der jeweilige Speicher für die Stacks gemappt werden? Für den Kernel oder den Task oder beide? Wo kann sonst ein Fehler liegen, wenn beim Rücksprung aus dem Interrupthandler, der den Task (Ring) gewechselt hat, ein Pagefault auftritt?
12
Lowlevel-Coding / Re: Paging und Multitasking
« am: 03. March 2012, 13:42 »
OK, danke. Soweit habe ich das nun verstanden. Doch bei meinem Kernel wird Speicher - auch für User-Tasks - nur vom Kernel selbst reserviert und freigegeben. Also die User-Tasks müssen eigentlich nichts an ihrem jeweiligen Pagedirectory oder dessen Tables ändern. Müssen diese trotzdem von dem jeweiligen Task selbst gemappt werden oder reicht es, wenn sie für den Kernel gemappt sind (da er ja der einzige ist, der sie verändern können muss)? Im Pagedirectory befinden sich nur physische Adressen der Tables, deshalb muss ich die Tables und das Directory eines Tasks nur für den Kernel und nicht für den jeweiligen Task mappen, oder?
13
Lowlevel-Coding / Re: Paging und Multitasking
« am: 24. February 2012, 17:11 »
Ich habe gedacht, dass der Speicherkontext (also Page Directory & Tables) eines Prozesses nicht von diesem Prozess selbst gemappt werden müssen, da dieser ja an dem Mapping nichts ändern soll (das soll nur der Kernel über Sys-Calls können). Dem ist wohl nicht so, oder? Page Directory und Tables des Kernelkontexts müssen den Tasks nicht bekannt sein?
Gibt es eine Möglichkeit, nur die relevanten Teile des Kernels in den Kontexten der einzelnen Tasks zu mappen oder muss immer der komplette Kernel gemappt werden. Falls ja, könnten so doch andere Tasks wieder Daten eines bestimmten Tasks und Systemdaten zumindest lesen.
Und noch eine Verständnisfrage: Das User-Flag muss also in jedem Eintrag einer Page Table eines User-Tasks gesetzt werden (selbst, wenn es sich um Kernel-Code handelt)?
14
Lowlevel-Coding / Paging und Multitasking
« am: 24. February 2012, 15:34 »
Hallo Forum,

ich bin gerade dabei, ein kleines OS zu schreiben. Vieles funktioniert schon zufriedenstellend, jedoch habe ich Probleme mit Paging in Verbindung mit Multitasking. Beides alleine funktioniert, jedoch bekomme ich Page Faults, wenn ich einen Ring 3 Task aufrufe (genauer: nachdem ich den Speicherkontext des Tasks für das Paging gesetzt habe). Meine Vermutung ist, dass ich nicht die richtigen Speicherbereiche für meinen Ring 3 Task mappe. Bis jetzt mappe ich eigentlich den gesamten Speicherbereich des Kernels, der bis zum Zeitpunkt, an dem der Task erstellt wird, reserviert ist. Dieser Speicherbereich sollte doch auf jeden Fall alles benötigte einschließen, oder? Welche Speicherbereiche sind für einen Ring 3 Task notwendig und mit welchen Rechten müssen diese gemappt sein?

Danke für Antworten und Grüße
BurningWave
Seiten: [1]

Einloggen