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.


Themen - RedEagle

Seiten: [1] 2 3
1
Hi
Das Multitasking, so wie ich es derzeit implementiert habe, gefällt mir nicht mehr :) Es ist meiner Meinung nach etwas umständlich, und sehr experimentell (habe einfach auf gut Glück drauf los programmiert  8-) ).
Maw.: Es wird Zeit es richtig zu machen… zumal ich derzeit mit einem recht fiesen Bug zu kämpfen habe der u.U. vielleicht sogar damit zusammenhängen könnte :D

Was mich am meisten belastet ist die Frage nach dem Timing. Mit welcher Frequenz sollten Taskwechsel stattfinden? Derzeit wird der Scheduler mit 1kHz aufgerufen. Er besteht aus etwa 80 Zeilen assembler-code.
Meine Frage ist jetzt, wie man das "Taskwechsel-Aufwand" - "Tasklaufzeit" - Verhältnis am besten wählt. Andere Kernel haben einen in C geschriebenen Scheduler. Ich mache mir sorgen dass dann 50% der Zeit nur für das Wechseln der Tasks verloren geht…

Des weiteren spiele ich mit dem Gedanken eine etwas komplexere Struktur für die Prozesse/Threads zu verwenden. Derzeit befindet sich Prozesse und Threads in einer liste die von Scheduler durchgearbeitet wird. Die einzige Beziehung zwischen Prozessen und deren Threads ist der Eintrag der parent-PID in der task-struktur des Threads. - Es ist also recht aufwändig herauszufinden ob zu einem Prozess noch Threads gehörten auf die gewartet werden muss...
Wie könnte man das am besten angehen? Einfach zu jedem Prozess/Thread eine Child-list hinzufügen? Dann hätte der Scheduler allerdings viel Arbeit.
Derzeit spiele ich mit dem Gedanken beides zu machen - also eine liste für den Scheduler, und eine für den Prozessmanager.

Wie sind eure Erfahrungen so? Wie macht ihr das?
2
Softwareentwicklung / call im RM in variables Segment
« am: 29. April 2010, 13:53 »
Hi
Ich erweitre gerade den Skrip-Interpreter meines Bootloaders und möchte gerne das Feature einbauen ein Segment, in welches vorher Daten geladen wurden, auszuführen.

Beispiel:
ld /reos/reos16.knl 3000
exec 3000
Die Datei reos16.knl wird in das Segment 0x3000 geladen, und soll anschließend ausgeführt werden

Bisher war das Ausführen hart im Code des Bootloaders - nach der Ausführung des Skriptes wurde call 0x3000:0x0000 ausgeführt.
Das würde allerdings in einem Chaos enden, falls jemand im Skript den Kernel in ein anderes Segment lädt.
Ein weiterer Nachteil ist, das nach dem Laden das Skript beendet werden muss, damit der call kommt. Beim runterfahren - also wenn der Kernel wieder verlassen wird, muss nun ein 2. Skript ausgeführt werden anstatt das 1. Skript nach einem exec weiter auszuführen.

Daher die Frage:
Wie kann ich in ein beliebiges Segment springen?

So sieht die Exec-Funktion aus:
[global _ExecSegment]
_ExecSegment:
    push bp
    mov  bp, sp
    push si
    push di
    push ds
    push es

    mov  ax, [bp+4]
    mov  ds, ax
    ; call

    pop  es
    pop  ds
    pop  di
    pop  si
    pop  bp
    ret
[bp+4] ist das Segment
3
Softwareentwicklung / lib in nasm / undefined reference
« am: 24. March 2010, 13:41 »
ich habe in nasm eine Bibliothek erstellt. Wenn ich aber Funktionen aus dieser lib nutzen möchte findet mein Linker diese nicht:

Header der lib
// ...
extern "C" int OpenPipe(PIPE *pipe, BYTE port, bool write, pipesig signal);
// ...

Code der lib
%macro APICALL 2
[global %1 %+ :function]
%1 %+ :
    push ebp
    mov  ebp, esp

    mov  eax, %2
    mov  ebx, ebp
    add  ebx, 2*4 ; eip, ebp
    int  0xFF

    leave
    ret
%endmacro

; ...
APICALL OpenPipe,           0x00020002
; ...

Bau der lib:
nasm -f elf -o capi.o capi.asm
ar qf libreos.a capi.o

Code eines Programms
#include <reos/reosapi.hpp>
#include <fnc/strex.hpp>
//...
error = OpenPipe(...);
//...

Bau des Programms
#kompilieren zu test.o
ld -static -s -o test -L $LIBDIR -lreos -lfnc test.o

Fehler:
./pipetest.o: In function `main':
pipetest.cpp:(.text+0x1c): undefined reference to `OpenPipe'



Es wird also das Symbol OpenPipe gesucht, aber nicht gefunden.
Nochmal zur Kontrolle ein blick in die .o des Programms:
readelf -s test.o
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND OpenPipe

Nun ein Blick in die libreos.a um zu gucken, ob es ein Symbol OpenPipe gibt:
readelf -s libreos.a
Symbol table '.symtab' contains 23 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    18: 0000012c     0 FUNC    GLOBAL DEFAULT    1 OpenPipe

Das Symbol ist vorhanden - aber warum findet der Linker es nicht?  :?
(Problem besteht bei allen Funktionen aus dieser lib)

Ich verwende in dem Programm eine andere Bibliothek welche ich in C++ geschrieben habe (libfnc.a) - Diese wird anstandslos gelinkt. Beide libs liegen im selben Verzeichnis.

Wo könnte mein Fehler liegen?
In der lib ist doch genau das gesuchte Symbol vorhanden.

Versionen:
nasm: "NASM version 2.07 compiled on Nov  6 2009"
ld: "GNU ld (GNU Binutils; openSUSE 11.2) 2.19.51.20090527-10.26.4"
4
Hi
Ich beschäftige mich jetzt schon einige tage mit der Frage, wie ich den im Treiber verarbeiteten Tastendruck zu dem richtige Programm bekomme.

Folgende Situation:
Programm A möchte eine Taste einlesen, Programm B ebenfalls.
Der User drückt 'x' - woher weiß ich jetzt zu welchen Programm das x gehört?

Das ganze mal anhand von Linux:
Linux läuft, mit KDE und 2 Terminal-fenster.

der User drückt 'x'
was passiert jetzt mit dem 'x'?
Wird 'x' jetzt erst zu dem entsprechenden tty geschickt, von tty7 dann nach KDE, von KDE dann zu dem im Vordergrund liegenden Terminal, und dieser dann an den zuletzt ausgeführten Prozess?

Demnach müssten ALLE Programme eine Art Fenster/Prozessverwaltung implementiert haben, damit diese wissen an welches Programm (child) das 'x' weiter zureichen ist!?

Mich quälen im Moment 2 Fragen:
1. Welche Methode? Taste senden, oder buffern (die Anwendung holt sich also die Taste selber)?
2. Woher weiß ich, welches Programm diese Taste bekommen soll?
5
OS-Design / Tabelle für Deutsche Scancodes?
« am: 18. February 2010, 11:20 »
Hi
Ich suche nun schon seit Stunden eine Tabelle mit den Scancodes für Deutsche Tastaturen - leider ohne Erfolg. Alle Tabellen, auch die, die angeblich deutsch sein sollen sind Englisch.

Kennt zufällig jemand nen Link, oder hat jemand 'ne pdf rumliegen?

btw: Sind die scancodes für shift/alt/strg/*lock und auch Sondertasten wie F1..F12, enter,space,... auf jeder Tastatur gleich? Die Positionen ändern sich ja eigentlich nicht
6
Softwareentwicklung / Globale, Initialisierte Variable in .bss!?
« am: 19. January 2010, 20:08 »
Hi
Ich habe ein Problem mit Globalen Variable

paging.cpp
//...

namespace paging
{
 DWORD PagingSpinLock = 0x00000000;

//...

Der Linker packt diese Variable in den .bss-Bereich:
mapfile
...
 .bss           0x0000000000a14818        0xc mem/paging.o
                0x0000000000a14818                paging::PagingSpinLock
...

Der Grund dafür: Der Compiler lässt sie in den .bss-Bereich packen:
objdump -x paging.o
...

00000000 g     O .bss   00000004 _ZN6paging14PagingSpinLockE

...

Warum wird diese Variable in den .bss-Teil gepackt?
Alle Globalen Variablen die mit 0 oder false initialisiert wurden befinden sich im .bss-Segment; die mit einem Wert ungleich 0 initialisiert wurde hingegen nicht.


Der Compiler kann doch nicht einfach davon ausgehen das diese Speicherbereiche =0 sind :? - Die Tatsache das sie !=0 sind sorgt nämlich für wirre Abstürze...

Meine Compiler-settings:
COMPILERSETTINGS="-I $HEADERS -DCPU=586 -m32 -c -Os -nostdlib -fno-builtin -fno-rtti -fno-exceptions"Compiler: g++ 4.4.1

Ich arbeite bereist seit einigen Jahren mit diesen Settings - aber bisher sind mir nie solche Probleme aufgefallen...
...erst seit wenigen Tagen

Meine Frage:
Was jetzt? Wie bringe ich den Compiler dazu initialisierte Variablen nicht in den .bss-Block zu packen?
Warum geht der überhaupt davon aus, dass das bss-segment mit Nullen gefüllt ist? Überall wird doch explizit erwähnt dass dieser Speicherbereich keine definierten Werte enthält...

Nochmal die g++-version im detail:
$ g++ -v
Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib
--enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4
--enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj
--disable-libmudflap --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch
--enable-version-specific-runtime-libs --program-suffix=-4.4 --enable-linux-futex --without-system-libunwind --with-arch-32=i586
--with-tune=generic --build=i586-suse-linux
Thread model: posix
gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux)
7
OS-Design / API: Wie realisiert man es am besten?
« am: 01. January 2010, 14:43 »
Hi
Ich beschäftige mich seit einigen Tagen mit der API meines Kernels. Leider bekomme ich mit jeder Lösung 1000 neue Probleme und alles ist irgendwie extrem aufwändig.

Meine bisherige Lösung, bzw. Lösungsansatz

Ein Prozess ruft eine C-Funktion auf - bsp.: APITEST("hello world");
APITEST selber ist aber in assembly realisiert - in APITEST werden nun die Argumente, welche sich ja auf dem Stack befinden, wiederum an eine neue Stackadresse kopiert (Als Argument der 0xFF-ISR), um dann int 0xFF aufzurufen.

Die "0xFF-ISR" erwartet die Argumente auf dem Stack, und ist ebenfalls in asm geschrieben, nur die Funktions-Nummer kommt per eax

Von dieser ISR geht es nun weiter: Die Argumente werden wieder an eine neue Position im Stack kopiert, und dann die eax - entsprechende C-Funktion aufgerufen.

kurz: C -----> ASM --int0xFF--> ASM -----> C

Dabei gibt es nun ein Probleme - der String "hello world" befindet sich im virtuellen Speicher des Prozesses, die Funktion zum ausgeben des Strings benötigt aber den virtuellen Speicher des Kernels (gut, das geht vielleicht auch ohne Kernelspeicher, aber spätestens bei Dateiarbeiten muss ich mit dem Speicher des Kernels arbeiten)

Lösung: ich wechsle auf das PD des Kernels und mappe die Page, auf der sich der String befindet.

Problem: Was ist, wenn mehrere Prozesse das gleiche vor haben - ich kann also nicht die Page an der selben virtuellen Adresse mappen, wie sie im Prozess liegt - dadurch muss ich also alle Pointer die ich bekomme umrechnen.


Meine Frage nun:
Wie realisiere ich eine API am besten, die ich sowohl von asm, als auch C aus gut ansprechen kann, und wie regle ich das mit den Speicherräumen?
8
Lowlevel-Coding / g++ entfernt trotz volatile relevanten code
« am: 05. August 2009, 14:33 »
Hi
Ich habe folgende Funktion:
volatile bool NewKOT = false; //global

void WaitForKOT_()
{
 while(!NewKOT); //NewKOT wird beim interrup gesetzt
 return;
}

mein g++ 4.3.1 macht da folgendes raus:

00000175 <_ZN3KOT11WaitForKOT_Ev>:
 175:   55                      push   %ebp
 176:   89 e5                   mov    %esp,%ebp
 178:   a0 00 00 00 00          mov    0x0,%al
 17d:   84 c0                   test   %al,%al
 17f:   74 f7                   je     178 <_ZN3KOT11WaitForKOT_Ev+0x3>
 181:   5d                      pop    %ebp
 182:   c3                      ret

Warum?
Ich habe doch durch volatile angegeben, dass sich der Wert von NewKOT unabhängig von der Funktion ändern kann.
Das sieht ohnehin so aus, als würde er NewKOT als Konstant annehmen, da der Wert nicht einmal aus dem Speicher geholt wird.

ps.: meine Compiler-einstellungen
[/i]COMPILERSETTINGS="-I $HEADERS -DCPU=586 -m32 -c -Os -nostdlib -fno-builtin -fno-rtti -fno-exceptions"[/i]
9
Lowlevel-Coding / iret problem (triple fault)
« am: 23. August 2008, 15:05 »
Hi
Momentan beschäftige ich mich mit multitasking, und möchte ertsmal testweise ein einzigen prozess starten. Dazu legen ich eine neue PD an, und mappe den speicher so, wie ich ihn brauche.
Alles liegt an der adresse, wo es hingehört.
Dann lade ich die neue PD und möchte in den code des prozesses springen. Da ich später taskwechsel per iret machen muss (damit mir keine flags verloren gehen) wollte ich auch für diesen test iret verwenden...
Leider endet das in einem triple fault :(

Testweise habe ich es dann mal mit ret versucht, und das funktioniert...
Warum funktioniert iret nicht?

aufbau mit ret
; *PD wechseln, und stack initialisieren*

mov eax, 0x00000002 ; Die flags
push eax
popf
mov eax, 0x00003000 ; Hier liegt der code
push eax
ret ; und prozess starten, Funktioniert

Der aufbau zum testen des stackinhaltes (in diesem fall des eflags-wertes)
; *PD wechseln, und stack initialisieren*

   pop eax ;eip    (0x00003000) > OK
   pop eax ;cs     (0x00000008) > OK
   pop eax ;eflags (0x00000002) > OK
   jmp fncprint
  hlt
;iret

Und so mach ichs mit iret
; *PD wechseln, und stack initialisieren*

iret

Wie man sieht, sind die werte auf dem stack korrect, und wenn ich manuell die flags ändere, und dann in den code springe funktionierts auch, nur mit iret gets nicht :(

qemu: fatal: triple fault
EAX=e0000011 EBX=00010ff4 ECX=00c02007 EDX=000003f8
ESI=009fff8f EDI=00a0d800 EBP=009fffa8 ESP=00010ff4
EIP=00a06948 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00012101 0000001f
IDT=     00a0f0d4 0000018f
CR0=e0000011 CR2=00012109 CR3=00c02007 CR4=00000010
CCS=00000010 CCD=e0000011 CCO=LOGICL 

Wo liegt das problem?

ps.: Ich habe interrupts deaktiviert. Aber wenn ich sie aktiviere, ändert sich nichts.
10
Offtopic / RedEagle-OperatingSystem
« am: 05. April 2008, 19:52 »
Nach über 2,5 jahrne ist RedEagle-OperatingSystem nun so weit, dass man es veröffentlichen kann.

Derzeitige Features
  • Monolithischer Kernel
  • PM
  • Paging
  • Arbeitet im Textmode (derzeit 80x50)
  • Senden von Debug-infos über die serielle Schnittstelle
  • Single-User - System

Geplante Features
  • Multitasking
  • Eigenes Dateisystem
  • Unterstützung weiterer Textmodes (80x25, 90x60, ...)
  • Auf ASCII-Zeichen basierendes GUI

Programmiersprachen
Bootloader: NASM
16-Bit abschnitt des Kernels: NASM
32-Bit Kernel: C / C++ (g++)
Wobei der Kernel aber nicht objekt-orientiert ist.

Einige screenshots



Image und Sources
www.redeagle-operatingsystem.de.vu
11
Lowlevel-Coding / paging: Wo muss ich den Fehler suchen?
« am: 22. March 2008, 12:32 »
Hi
Wenn ich in nachträglich reservierten Speicher schreibe, gibts nen pagefault.

Zu beginn (befor paging aktiviert wird) lege ich 3 4MB-Pages an, und der rest wird mit pagetables gefüllt. Nachdem ich dann paging aktiviert habe, kann ich an den entsprechenden stellen dann auch schreiben.
Wenn ich jetzt eine neue page reservieren möchte wird, eine freie gesucht, und alle PTs durchgegangen, bis ein freier Platz für diese page gefunden wurde.

Soweit zur theorie.

Nun zum genauen ablauf:
0x00000000 bis 0x00C00000 sind durch die 3 4MB-Pages reserviert (die adressen sind physikalisch als auch virtuell die selben)
Nun möchte ich eine neue 4KB-Page reservieren. Als freie Page bekomme ich 0x00C00000 - also die 1. Page nach dem 12MB-Block. Das ist soweit richtig. Nachdem ich die Page nun ihre position in der Pagetable gefunden hat, bekomme ich folgende virtuelle adresse: 0x00C00000 - Auch richtig. 4. Pagetable, 1. Eintrag.
Flags für die Pagetable und Page: (PG_PRESENT | PG_WRITEABLE | PG_USERACCRESS) - Flags müssen stimmen, da ich die auch bei den 4MB-Pages verwende.

Zusammengefasst:
Physikalische adresse passt.
Virtuelle adresse passt.

* Warum gibt es jetzt einen Pagefault?
* Ich habe der Pagetable die selben flags gegeben, wie einer presenten page. Das ist doch richtig oder?
12
Lowlevel-Coding / Globale daten mit nasm?
« am: 12. February 2008, 12:18 »
Hi
Ich habe folgenden Datenblock:
[global exp_regdump]
exp_regdump:
 rd_eip: dd 0
 rd_eax: dd 0
 rd_ebx: dd 0
 rd_ecx: dd 0
 rd_edx: dd 0
 rd_esp: dd 0
 rd_ebp: dd 0
 rd_esi: dd 0
 rd_edi: dd 0
 rd_eflags: dd 0
 rd_cr0: dd 0
 rd_cr1: dd 0
 rd_cr2: dd 0
 rd_cr3: dd 0
 rd_cr4: dd 0
und folgenden c-code:
DWORD *rptr;
 rptr=exp_regdump;

das Problem: exp_reddump enthält nicht die adresse von rd_eip, sondern den wert.

Wie komme ich an die Adresse dieses blocks??
13
Lowlevel-Coding / Problem mit KeyCode setzen
« am: 21. October 2007, 08:43 »
Hi
Ich möchte bei meinem Tastaturtreiber den ScanCode Set 2 Aktivieren:

int SetScanCode2()
{
 WaitToWrite();
 cpu::out(0x60, 0xF0); //Scancode �ndern
 WaitToRead();
 if(GetKeyboardBuffer() != 0xFA)return KBDERR_SETSCANCODE;

 WaitToWrite();
 cpu::out(0x60, 0x02); //Scancode 2
 WaitToRead();
 if(GetKeyboardBuffer() != 0xFA)return KBDERR_SETSCANCODE;

 return KBDERR_NOERROR;
}

/////////////////////////////////////////////////////////////////////////////////////

BYTE GetKeyboardBuffer()
{
 return cpu::in(0x60);
}

/////////////////////////////////////////////////////////////////////////////////////

void WaitToRead()
{
 DWORD timeout = KBD_MAXTIMEOUT;
 while(!(cpu::in(0x64) & 0x1) && timeout--);
 return;
}

/////////////////////////////////////////////////////////////////////////////////////

void WaitToWrite()
{
 DWORD timeout = KBD_MAXTIMEOUT;
 while((cpu::in(0x64) & 0x2) && timeout--);
 return;
}

Die Funktion gibt "KBDERR_NOERROR" zurück.
Aber bei den Interrupts bekomme ich immernoch die Set1-Codes...

Ich teste den Treiber mom unter bochs 2.2.1
leider habe ich momentan keine echten PCs zum testen...

Wo liegt der Fehler??

ps.: Zum Initialisieren:
* Keyboard deaktivieren
* Scancode setzen
* LEDs setzen/löschen
* Treiberumgebung initialisieren
* Interrupt installieren
* Keyboard aktivieren
14
Offtopic / IOPL, bochs -> was bedeutet das?
« am: 11. October 2007, 08:47 »
Hi
beim beenden von bochs bekommt man neben den registerinhalten auch eine liste mit abkürzungen:
IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cfWas haben die Abkürzungen zu bedeuten??
Habe schon auf der bochs-seite gesucht, aber nirgends was gefunden (wobei ich auch nicht weiß, wonach ich suchen muss ;) )
15
Lowlevel-Coding / Reboot nach lesen eines Registers?!?
« am: 25. August 2007, 11:55 »
Hi, wenn ich folgenden code ausführe gibts ein reboot:

DWORD cr4()
{
   unsigned int cr4;
    asm volatile ("movl %%cr4, %0" : "=a" (cr4));
   return cr4;
}

Der folgende code hingegen funktioniert:
DWORD cr0()
{
   unsigned int cr0;
    asm volatile ("movl %%cr0, %0" : "=a" (cr0));
   return cr0;
}

was ist oben falsch, was unten richtig ist??

CPU: Cyrix 6x86
16
Lowlevel-Coding / Paging debuggen??
« am: 22. August 2007, 11:24 »
Hi
ich habe mich jetzt mit paging beschäftigt, und habe den code fertig. Natürlich funktioniert noch nichts.
Leider fehlt mir momentan die Idee, wie ich dass debuggen könnte.
Das Problem liegt wahrscheinlich beim erstellen des PageDirectorys bzw der Tables.
Ich könnte jetzt die gesammten Daten per rs232 in eine html-Tabelle schreiben, und kontrolieren, was bei ca 4MB Daten allerdings ein enormer aufwand währe.
Wie habt ihr das gemacht??

Hier einfach mal der Code:
#define SIZEOF_PAGEDIRECTORY (1024*4) ////PD = 1024PT * 4B = 4096
#define SIZEOF_PAGETABLE     (1024*4) ////PT = 1024PF * 4B = 4096
#define SIZEOF_PAGE          (1024*4) ////1 Page-größe (4KB)

#define PG_PRESENT     0x01 //Vorhanden
#define PG_WRITEABLE   0x02 //Speicher auch beschreibbar
#define PG_USERACCRESS 0x04 //Für user zugreifbar (ring3)
#define PG_OUTOFRANGE  0x0200 //Existiert auf Physikalischer ebene nicht (z.B. 17.MB bei 16MB-RAM)
#define PG_REOSDEFAULT (PG_PRESENT | PG_WRITEABLE | PG_USERACCRESS)
#define PG_REOSNULL    (             PG_WRITEABLE | PG_USERACCRESS)

 DWORD *KernelPageDirectory = (DWORD*)0x701000; //Kernelspace (auch virtuell == physikalisch)
 DWORD *KernelPageTables    = (DWORD*)0x702000;

int InitKernelPageDirectory()
{
 int error=0;
 //1024 PageTables einfügen initialisieren
 DWORD currentPT = (DWORD)KernelPageTables;
 DWORD *PageDirectory = KernelPageDirectory;

 for(int i=0; i<1024; i++)
 {
  *PageDirectory = currentPT | PG_REOSDEFAULT;

  error = InitKernelPageTable(currentPT); //Das flag muss mit, um zu wissen, ob spätere tabels present sein müssen oder nicht
  if(error&(~PG_COMPLETE))return error;
  if(error == PG_COMPLETE) break;

  PageDirectory+=4;
  currentPT += SIZEOF_PAGETABLE;
 }

 return 0;

}

int InitKernelPageTable(DWORD PageTable)
{
 static DWORD paddr = 0;
 DWORD flag; //Flags, ob present und son scheiß
 if(paddr < 0xB00000) flag = PG_REOSDEFAULT;          //bis 11MB gehört dem Kernel
 else                {flag = PG_REOSNULL; paddr = 0;} //Danach ist frei und verboten

 //1024 Pages einfügen initialisieren
 for(int i=0; i<1024; i++)
 {
  if(paddr > MaxPhysicalMemory) flag |= PG_OUTOFRANGE; //Wenn die Andresse auserhalb des Vorhanden Arbeitsspeicher liegt

  *(DWORD*)PageTable = paddr | flag; //paddr enthält die physikalische addresse
  PageTable += 4;
  paddr     += SIZEOF_PAGE;
  if(paddr < 0xB00000) flag = PG_REOSDEFAULT;            //bis 11MB gehört dem Kernel
  else                {flag = PG_REOSNULL; paddr = 0;}   //Danach ist frei, und verboten
 }

 if(paddr == 0) return PG_COMPLETE;
 return 0;
}

Das setzten der Register wird wohl richtig sein:
#define CR0_PAGING 0x80000000

//...

 cpu::cr3((DWORD)KernelPageDirectory);
 cpu::cr0(cpu::cr0() | CR0_PAGING);
17
OS-Design / Fragen zu paging
« am: 18. August 2007, 12:15 »
Leider finde ich keine gescheitet tutorials. Ich habe mir zwar anhand von codes schon etwas aneignen können, aber einige Fragen gibt es noch:

1. Es gibt 1 PageDirectore, mit 1024 Pagetables. Ist das richtig (habe nehmlich auch schon 1PageDirectore mit nur einer Pagetable gesehen, dann hätte man aber nur 4MB...)??

2. Jeder Task verwendet dieses PageDirectore. Es wird nicht für jeden task ein eigenes Angelegt!?

3. Was sagt das present-bit aus?? Dass der speicher gemappt wurde, oder dass er generell an einen Prozess vergeben wurde (also aktiv und somit im Prozess vorhanden ist).

4. Wie erkenne ich, ob ein pageframe vergeben oder frei ist? (fals oben gemappter speicher gemeint ist)

Das wars erstmal... evtl kommt stäter noch was ;)
18
Lowlevel-Coding / memcpy wird nicht erkannt
« am: 16. August 2007, 11:56 »
Hi
Ich (bzw mein compiler) braucht die memcpy-funktion.
Soweit kein Problem.

Aber: sie wird nicht anerkannt.
Also ich habe eine Funktion memcpy aber die wird ja vom compiler in _Z6memcpy*irgendwas* umbenannt. Ist dass der grund? wenn ja, wie verhindere ich dass??

ps.: der Fehler:
rr.cpp:(.text+0xf2): undefined reference ro `memcpy'

(Es wird eine funktion aufgerufen, die eine Struktur zurückgibt)
19
Lowlevel-Coding / Problem beim lesen der Disk im RM
« am: 29. July 2007, 11:47 »
Ich habe folgenden Code:
   mov ax, 0x1000
   mov es, ax
   mov bx, 0      ; Zieladresse(es:bx) 0-2400
   mov ah, 2      ; Funktion 2 (Lesen)
   mov al, 18     ; Lese 36-18 Sektoren (maximum 36)
   mov cx, 0x0013 ; Cylinder=1, Sector=19
   xor dx, dx
   int 0x13       ; ES:BX = Daten vom Laufwerk
Nach ausführung steht in AH 04h -> "sector not found/read error"

wo muss ich das Problem suchen??
(Ich lasse den codeabschnitt 10 mal durchlaufen (im fehlerfall) und jedesmal der gleiche Fehler)
20
Lowlevel-Coding / Kann irgendwie nicht linken
« am: 19. June 2007, 10:53 »
Ich bin auf Linux umgestiegen, und muss jetzt meine build-scripte meines Systems umschreiben.
Damit bin ich jetzt fast fertig, aber natürlich macht die letzte Zeile wieder Probleme ;)

Also:
Der relevante auszug aus ~/reos/kernel/link.txt
INPUT( ~/reos/kernel/kernelexe.obj
       ~/reos/kernel/_oop.obj
       ~/reos/kernel/kernel.obj
     )
All 3 Dateien sind vorhanden.

Wenn ich jetzt
ld -T ~/reos/kernel/link.txt -o ~/reos/kernel/kernel.bin ausführe (unter bash) bekomme ich die Meldung:
ld: cannot find ~/reos/kernel/kernelexe.objwo liegt das Problem??

ps.: verwende openSuSE 10.1
Seiten: [1] 2 3

Einloggen