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 - sebi2020

Seiten: [1] 2 3 ... 7
1
Lowlevel-Coding / Re: Paging
« am: 13. October 2011, 20:15 »
Achso das meinst du. Stimmt... Aber eine Frage wäre immer noch offen...  was mache ich mit dem Context? der muss vor und nach dem Paging erreichbar sein... ein 1 zu 1 mapping?
2
Lowlevel-Coding / Re: Paging
« am: 13. October 2011, 19:23 »
Zitat
Bei Paging an und existierender PT vergisst du das Mappen komplett
...
vmm_context->virtPageDir[pageDirNumber] = create_page_table_entry(flags,pageTableAdress);
...
pageTableAdress[pageTableNumber] = create_page_table_entry(flags,pAdress);
Wo vergesse ich hier das Mapping?!!!!

Hast recht, sollte jeweils ne page table vor gehn, aber wo vergesse ich den hier das Mappen?!
3
Lowlevel-Coding / Re: Paging
« am: 13. October 2011, 17:56 »
Ja klar, aber danach muss ich ja auch für die nächsten Tasks ein PD erstellen. Wie mache ich das dann? Und zudem muss ich die Mappings dann auch noch für jeden Task gleich halten...
Ist diese Funktion jetzt so richtig?
int vmm_map_page(struct vmm_context*, void* pAdress, void* vAdress, uint16_t flags)
{
uint16_t pageNumber = (uint16_t) ((uint32_t) vAdress / 0x1000);
uint16_t pageDirNumber = pageNumber / 1024;
uint16_t pageTableNumber = pageNumber % 1024;
uint32_t* pageTableAdress;
// uint32_t* page;
if(use_phys_addr)
{
// Ist schon eine PageTable im Directory ?
if(vmm_context->pageDir[pageDirNumber] > 0) {
pageTableAdress = vmm_context->pageDir[pageDirNumber] & 0xFFFFF000;
} else { // Nein? Dann erstelle eine neue
pageTableAdress = pmm_alloc();
memset(pageTableAdress,0x1000);
vmm_context->pageDir[pageDirNumber] = create_page_table_entry(flags, pageTableAdress);
}
// Page in die PageTable eintragen
pageTableAdress[pageTableNumber] = create_page_table_entry(flags, pAdress);
} else { // Paging ist aktiviert
if(vmm_context->virtPageDir[pageDirNumber] > 0) {
pageTableAdress = vmm_context->virtPageDir[pageDirNumber] & 0xFFFFF000;
} else {
pageTableAdress = pmm_alloc(); // Speicher allozieren
vmm_context->virtPageDir[pageDirNumber] = create_page_table_entry(flags,pageTableAdress);
// 0xFFC0 0000 (Hier sind die PageTables als Pages gemappt)
pageTableAdress = (VIRT_PAGE_ADDR + (sizeof(uint32_t) * pageDirNumber));
memset(pageTableAdress,0x1000);
pageTableAdress[pageTableNumber] = create_page_table_entry(flags,pAdress);

}
}
// Transaction Locate Buffer invalidieren (löschen)
asm volatile("invlpg %0" : : "m" (*(char*) vAdress));
return 0;
}
4
Lowlevel-Coding / Re: Paging
« am: 13. October 2011, 15:40 »
Also nochmal um das zu verständlich zu machen.
Ich möchte eine Funktion, die bei JEDEM neuen Task kernel-Mappings erstellt. Das bedeutet, ich habe noch kein PD. Ich alloziere speicher, muss diesen aber sofort mappen, was aber noch nicht geht, weil ich kein PD im neuen Context habe, also was machen?!
5
Lowlevel-Coding / Re: Paging
« am: 13. October 2011, 13:07 »
Ja, aber damit sind doch dann nur bestehende Pages gemappt. Irgendwie ist es jeztt außerhalb von meinem Vorstellungsvermögen gerade, wie ich dann die anderen Mappe. Kp. Sagen wir ich hab 2 PageTables die bereits im Directory drin sind. Wie füge ich dann eine neue ein?! Ich verstehs grad nicht -.- Ich lege PageTables eigentlich bei bedarf an, heißt wenn ich für eine bestimmte Adresse eine brauche. Ihr habt doch nich 1024 PageTables von anfang an angelegt, oder?
Ich meine, ich denke ich benutze die Virtuelle-Adresse des PD
dann mach ich ein pmm_alloc() für eine PageTable, trage diese ins PD ein und kann dann über das "virtuelle PD" (nenn ich jetzt mal so) die PageTable bearbeiten?! Also ich meine die liegen also jetzt in den letzten 4 MB die PageTables. Die PageTables sind doch jetzt als Pages gemappt, oder?
das heißt pt_virt_addr[pageTableIndex] sucht mir nun sozusagen jetzt die eben allozierte PageTable und mit pt_virt_addr[pageTableIndex][pageIndex] müsste ich doch dann Pages eintragen können.

Ich werd aus dem Tutorial nicht sehr schlau. Es ist am ende sehr knapp gehalten. Man weis nicht was man mit seinem vorherigen Code machen soll.
Ich kann nicht einfach all pmm_alloc aufrufe durch vmm_alloc ersetzen, schließlich arbeite ich vorher mit physischen adressen und ich kann keine virtuellen Adressen benutzen solange Paging noch nicht aktiv ist. So müsste ich es mir explizit verkneifen mir speicher zu holen, solange noch kein Paging nicht aktiviert ist. Ich muss vor dem Paging schon Speicher für den Context holen, muss diesen aber erstmal physisch haben. So nun verflucht, alle Pointer für die KOntexte sind momentan alle physisch. Jetzt brauch ich aber eine virtuelle Adresse für sie... Was nun?!
6
Lowlevel-Coding / Paging
« am: 13. October 2011, 11:23 »
Sorry, hab ausversehen das Thema gelöscht (das kommt davon wenn ich unbedingt mit Lynx surfen muss :P)
Jetzt versteh ich auch was du meinst. Ja, die funktion war jetzt erstmal auch nur bis vorm Paging ausgelegt. Weil ich da irgendwie ein Problem sehe.
Ich brauche physischen Speicher für ne neue PageTable, kann sie aber nur über eine virtuelle Ansprechen. Ja, aber ich habe doch gar kein Mapping für die physikalische Adresse der PageTable, also wie soll ich sie ansprechen?
7
Lowlevel-Coding / Re:TSS aus Tutorial Multitasking
« am: 29. June 2011, 11:12 »
Aber ich allozier doch für jeden Task ein extra Stack... oO
Bei Ring 0 Tasks nur ein Kernelstack, bei Usermode Tasks ein Kernelstack und einen Userstack... Oder meinst du mit Ring0 Code, der im Kernel läuft? Weil ich hab ja eine Init funktion. Da ist der esp noch auf 0x200000 gesetzt. Aber sobald ich in die Multitasking Funktion springe, hab ich ja einen neuen Stack.
8
Lowlevel-Coding / Re:TSS aus Tutorial Multitasking
« am: 29. June 2011, 10:49 »
Hm, aber das heißt der Kernelstack für jeden Prozess ist nur für die CPU strukturen und Interrupts zuständig, oder? Also bei den Userspace Tasks mein ich.
9
Lowlevel-Coding / Re:TSS aus Tutorial Multitasking
« am: 29. June 2011, 10:33 »
Wenn jetzt in Ring 3 ein Interrupt ausgelöst wird. Auf welchem Stack liegt den dann das ganze? Auf dem Userstack?
Also ich bin verwirrt, weil ich lade den ESP doch selber ... : mov esp, eax
Also ich glaub ich habs verstanden. Moment.
Wenn ich jetzt in nen Ring 3 Task bin, hab ich den Userstack-Pointer geladen, und weil er bei einem wechsel von ring 3 nach ring 0 sich den esp nicht vom stack holt, muss ich ihn in esp0 sichern, so wie er vorher war, der kernel stack. So?
10
Lowlevel-Coding / Re:TSS aus Tutorial Multitasking
« am: 29. June 2011, 09:58 »
Also, um dir folgen zu können ( ich weis ich stell mich manchmal ziemlich dumm an...) aber versuch ich jetzt noch mal aus meinem Verständnis das ganze zu beschreiben...

Ich hab den normalen Kernel-Stack erstmal. Wenn nun der Interrupt auftritt sicher die CPU ein paar Register (äh EIP, ESP usw. ??) von selbst, dann sicher ich ja im Assemblercode noch die Interrupt Nummer und bei Exceptions die Fehlernummer, die bei einem Timerinterrupt allerdings einfach null ist. So weit so gut. Dann push ich noch den aktuellen esp auf den Stack als Parameter für die Interuptbehandlungsfunktion... Die Sachen die ich jetzt auf dem Stack liegen habe, bilde ich ja mit der cpu struct ab. soweit richtig?!

Dann bin ich nun im Interrupt. Mein Scheduler holt den nächsten Task, der sagen wir jetzt mal ein Ring0 Task ist und der vorher war ein Userspace Task... nun trag ich im TSS bei esp0 den neuen Task ein und gehe ans ende dieser Struktur... so nun geb ich die Adresse des neuen Taskzustandes zurück. Setze den Stack-Pointer auf die neue Taskstruktur nehm noch den Fehlercode und die Interrupt nummer vom Stack, lade die Segmentregister neu und springe nun mit iret aus dem Interrupt. Das müsste doch dann meine Taskstruktur vom Stack nehmen und EIP (wie in deinem Beispiel jetzt auf 0x1000) liegen. Soweit wieder richtig?

Nun müsste doch der ESP = dem ESP im TSS sein... aber ab wann spielt den dann jetzt der ESP - Pointer im TSS eine Rolle. Ich hab grad einen Ringwechsel gemacht, aber was tut jetzt hier der ESP aus dem TSS, das hab ich irgendwie noch nicht ganz verstanden. Oder ich hab hier nur kompletten blödsinn geschrieben :)
11
Lowlevel-Coding / TSS aus Tutorial Multitasking
« am: 29. June 2011, 09:14 »
Ich weis, Köpft mich, wenn ich dafür jetzt ein extra Thread aufmache (könnt ihn ja wieder löschen)... aber eine Sache würde mich zum Multitasking Tutorial noch intressieren.

Dort steht irgendwo:
.esp0 = (new_cpu +1)
Der Stack wächst doch nach unten, oder? und ein pop erhöht doch die adresse, oder? Wenn dem so ist, warum dann + 1.  Ich dachte die CPU möchte den Zustand vielleicht auch noch mal vom Stack holen. Aber gerade mit diesem Plus 1 würde das doch verhindert, oder? oO

Oder geht es darum, den Taskzustand auf den Stack zu schieben? bzw ihn in new_cpu abzuspeichern... ?
12
Lowlevel-Coding / Re:IPC - Implementierungsansätze
« am: 28. June 2011, 15:27 »
Hm, habt ihr vielleicht eine gute Adresse wo solche Dinge erklärt werden?
Ich hab mir mal z.B. das mit den unamed Pipes angeschaut. Ich verstehe nciht wie das Funktionieren soll...
Ich meine diesen teil hier:
int main(void)
{
int fd[2];
int status = pipe(fd);
...
return 0;
}
Wie soll den die pipe Funktion die handles zurückliefern, wenn fd so übergeben wird. Oder verweist fd auf eine Adresse weils nen Array ist, und die pipe funktion kann so die elemente belegen? Ich frag mich halt, weil ich jetzt gewettet hätte, das man einen Pointer übergeben muss. Aber bei diesem Aufruf wird im Grunde ein Pointer übergeben, oder? Weils ein Array ist...

EDIT: Also ich gucke sehr oft auf dieser Seite nach:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/contents.html
13
Lowlevel-Coding / Re:IPC - Implementierungsansätze
« am: 28. June 2011, 14:51 »
Und wo wir gerade dabei sind, ein read bekommt einen Pointer wo es die Daten hinlegen soll und liefert nicht einen Pointer wo die Daten liegen. Das ist ein sehr wesentliches Detail...
Jetzt bin ich aber verwirrt, ein Read liest doch die Daten aus und sollte selber bestimmen können, was mit den ausgelesenen daten gemacht werden (also wo sie hin sollen. vor allem liest es doch und schreibt nicht, jetzt bin ich verwirrt was das mit "Daten irgendwo hinlegen" zu tun hat. Ich dachte eig, dass ein read einen Puffer bekommt, die mittels write dort reingeschrieben wurden...
14
Lowlevel-Coding / Re:IPC - Implementierungsansätze
« am: 28. June 2011, 13:51 »
Lass Dich nicht vom Multithreading abschrecken, das taljeth in threadsicheren Programmen ein Problem sieht liegt wohl daran das tyndur und die zugehörige libc in der Vergangenheit nicht threadsicher war und das nun geändert werden muss, so das jetzt eben das Problem einer nachträglichen Konzeptänderung entsteht. Wäre tyndur von Anfang an threadsicher gebaut worden wäre der Gesamtaufwand sicher ein klein wenig geringer ausgefallen.
Davor schrecke ich im Moment zurück, da ich 1. bis jetzt nur Prozesse habe, keine Threads und 2. die Fehlersuche noch aufwändiger wird.
Mein erstes Ziel ist es immer es einfach zu implementieren. Mein zweites ist die Performance. Das beste Beispiel ist mein Task Scheduler, ich hab im Moment einen Round Robin (oder wie heißt der?) im System. Nur das der erste Task der ausgeführt wird derjenige ist, der als letztes in die Liste aufgenommen wurde. Das zweite ist die Speicherverwaltung. Es ist ziemlich "Ressourcenfressend", wenn er jedesmal 32768 * 32 Bits durchgeht um zu schauen, ob irgendwo freier Speicher gibt (okay, dass tut er nicht, weil meistens nach 1,2 MB oder so eine freie beschreibbare Speicherstelle ist), aber ihr wisst schon was ich meine.

Wenn ich ehrlich bin, habe ich mich noch nie mit IPC beschäftigt, was davon herrührt, das ich noch nie wirklich Programme die sowas nutzen geschrieben habe. Zu dem Konzept mit den SIGNALS...
Wenn ich das richtig verstanden habe ist es doch so, dass ein Programm diese Signals mit der Funktion signal() nutzt. Dabei wird doch das Signal festgelegt, an welches reagiert werden soll und eine callback Funktion, oder? Und mit raise() wird ein bestimmtes Signal für den Prozess ausgelöst. Stimmt das soweit?
15
Lowlevel-Coding / Re:IPC - Implementierungsansätze
« am: 28. June 2011, 12:14 »
Ja klar hat er Zugriff, aber wo sollen die Nachrichten den genau dann hin?`Also das mit dem mappen der adressen in zweier Prozesse find ich nachvollziehbar. Aber der Kernel weis doch nicht genau, wo er Nachrichten hinschreiben kann. Man könnte per Konvention ne Adresse festlegen, wo die Nachrichten dann liegen. Das würde mir z.B. einfallen. Ich meine mit dem virtuellen Adressraum ist das leichter zu bewerkstelligen, weil jeder Prozess dann z.B. seine Nachrichten bei 1 MB liegen haben könnte, oder so ähnlich. Die muss er sich dann aktiv rausfischen. So nach dem FIFO Prinzip hatte ich mir das gedacht.
16
Lowlevel-Coding / IPC - Implementierungsansätze
« am: 28. June 2011, 11:50 »
Hallo erstmal :)
Ich bin jetzt an dem Punkt, wo ich Paging implementiere und werde damit auch zwangsläufig dazu kommen müssen irgend eine Art von IPC zu implementieren.

In dem Wiki-Artikel find ich es sehr abstrakt. Es ist klar wie das Model aussieht, aber wie man das Softwäretechnisch implementiert, hab ich keine Ahnung, wie das gehn soll. Als Beispiel nenn ich jetzt mal die Message Queue die ich gern für mein System hätte.
Was ich mich nun Frage ist, wie ich es Umsetzte, dass ein Programm Daten emfpängt und ein anderes sendet, ohne den Programmfluss zu stören, aber trotztdem auf die Ereignisse reagieren zu können... Aber das halt so, das es zu keinen Seiteneffekten kommt. Ich versteh noch nicht ganz, wie das überhaupt gehen soll, wenn die Programme Speichermäßig und auch vom CPU Zustand völlig abgekoppelt sind.
So ein paar Zeilen Pseudo-Code würden mir vielleicht auf die Sprünge helfen.

Lieben Gruß,
Sebi2020
17
Ich hab das mal überprüft, aber ich glaube nicht, das es daran liegt... Ich hab die Pointer mal ausgeben lassen:

Task 1 (stack) : 0x123000
Task 1 (tasklist) :  0x126000

Task 2 (stack) : 0x127000
Task 2 (tasklist) : 0x128000

Task 3 (stack) : 0x129000
   Userstack: 0x12A000
Task 3 (tasklist) : 0x12B000

Task 4 (stack): 0x12C000
Task 4 (tasklist) : 0x12D000

cstring (1. Aufruf) : 0x12E000
cstring (2. Aufruf) : 0x12F000
Der ESP zeigt allerdings auf ne komische Stelle. Er wächst doch nach unten, oder nicht? Also müsste er im Grunde unter 0x12A000 liegen und nicht bei 0x12AF44

EDIT: DAs ist jetzt eine komische Ironie!
Ich hab den Fehler gefunden. pmm_alloc() funktioniert. Viel intressanter ist, was passiert wenn man den stack und userstack pointer als uint32_t* pointer festlegt und da mal 0x1000 drauf addiert. :)
18
Hm, Okay, aber ist irgendwas auffälliges? weil komischer weise klappt ja alles beim ersten aufruf, nur beim zweiten meckert er.
19
Lowlevel-Coding / Stack Fault Exception bei memset Funktion.
« am: 26. June 2011, 11:27 »
hallo erstmal,
Ich habe letztens versucht die strcmp Funktion zu implementieren, was dann ungefähr so aussieht:
char* cstring = pmm_alloc();
memset(cstring,0,0x1000);
...
Wenn ich diese Funktion nun einmal aufrufe klappt auch alles. Beim zweiten Aufruf bekomme ich einen Stack Fault ( 0xd ). Im Wiki heißt es das es an ein Falsch geladenem Stack Segment Register liegen kann. Ich bin im Moment ratlos woher der kommen kann. Wenn ich Memset z.B. nur 100 Bytes schreiben lasse geht wieder alles, aber ich wollte eigentlich schon eine ganze Page löschen.
Diese Funktion hab ich einmal in einem Ring0 Task ausprobiert und zum Testen wegen dem SS Register auch einmal in einem Ring3 Task.
Kann es an dem SS Register liegen? Hab hier mal die Ausgabe von QEMU
check_exception old: 0xffffffff new 0xd
     6: v=0d e=0000 i=0 cpl=0 IP=0008:00100a3d pc=00100a3d SP=0010:0012af44 EAX=03da0620
EAX=03da0620 EBX=001021e9 ECX=00000001 EDX=0012af5c
ESI=0010059a EDI=0000001a EBP=0000000c ESP=0012af44
EIP=00100a3d EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0028 00102160 00068fff 00c08900 DPL=0 TSS32-avl
GDT=     00102220 00000030
IDT=     00102260 000007ef
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=0012af44 CCO=ADDL    
EFER=0000000000000000
Was mich leicht wundert, dass die SS und CS Register DPL 0 haben und die anderen beiden DPL 03. Müssten die bei einem Ring 3 Task nich alle DPL 3 haben?

EDIT:
Zumindest sind da nur meine Ring0 Selektoren geladen. (also 0x8 und 0x10)
Gruß Sebi2020
20
Lowlevel-Coding / Re:Task nach ausführung beenden
« am: 25. June 2011, 18:11 »
Ich hatte erst nur den -L parameter verschoben. Aber das wars. ich hab die bib nach die mod.o hingeschrieben und jetzt gehts!
Super! Danke
Seiten: [1] 2 3 ... 7

Einloggen