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

Seiten: [1] 2 3 4
1
Lowlevel-Coding / Re: Cursor setzen
« am: 18. May 2007, 13:41 »
Ja da hast du vollkommen recht.
2
Lowlevel-Coding / Re: PMode geht nicht
« am: 18. May 2007, 13:37 »
Oder Geh mal auf http://www.osdever.net/, dort gibt es viele Tutorials, wenn auch in English. Zur Einführung würde ich dir Bran's Kernel Development Tutorial (http://www.osdever.net/bkerndev/index.php) raten, dort wird ein kleiner Kernel bis hin zur Tastatureingabe entwickelt und gut erklärt.

Und warum der PMode hier nicht funktioniert... Das Problem hatte ich mal. Also, zuerst würde ich dir raten, den PMode nach dem laden des Kernels an eine Speicherstelle einzuschalten, also eigentlich vor dem Sprung.
Dann musst du bedenken, dass du bei aktiviertem PMode im 32-Bit modus bist. Also muss ein Jmp auch eine physische Adresse erhalten.
Mit anderen Worten, nicht
        jmp Pmode
Pmode:

sondern:
        jmp dword Pmode
Pmode:

Der Thread sollte noch irgendwo sein, find den aber nicht mehr.

Auch will ich dir eher raten, GRUB zu benutzen, macht hier fast jeder, und es gibt noch andere Vorteile.
3
Lowlevel-Coding / Re: Cursor setzen
« am: 17. May 2007, 10:15 »
Bochs sagt, das IOPL ist dann am Ende gleich 0. Soll das so sein?
Kann das auch was mit dem VME-Flag zu tun haben, in cr4? Die Infos die ich zu den Pentium-Registern finde sind eher dürftig.
Ich weiß auch immer nicht ob das OS nun CPL = 0 oder CPL = 3 ist... Mann bin ich blöd ^^
4
Lowlevel-Coding / Re: Cursor setzen
« am: 16. May 2007, 20:37 »
Auch auf die Gefahr hin, jetzt doof darzustehen... was'n ein IOFL flag?
5
Lowlevel-Coding / Re: Cursor setzen
« am: 16. May 2007, 15:01 »
Nee stimmt irgendwie nicht...

Egal, hab mich jetzt einfach kurzerhand vom OO-Design verabschiedet und in C gewechselt, wobei der Cursor immer noch nicht richtig gesetzt wird, ist es nicht lustig?
6
Lowlevel-Coding / Re: Cursor setzen
« am: 16. May 2007, 00:53 »
Ja... das & hab ich vergessen, mann war ich blöde... Dank an bluecode  :roll:
Den copy-constructor hab ich auch überschrieben, für den fall der Fälle... nur wenn ich einen destruktor deklariere, will der eine __cxa_atexit und den ganzen rest haben... obwohl ich eine dtors section haben will...

Der Cursor wird immer noch nicht richtig gesetzt... aber wenigstens kann ich erstmal weiterarbeiten, da er ja nicht mehr alles in eine Zeile schreiben will

Add: Tja... ich dachte an den inport liegt es dass der das Schreiben in die VGA-Ports nicht mehr zulässt, aber offenbar nicht... hab das gelöscht, der cursor wird immer nocht nicht gesetzt. Der Code ist aber zu 100% korrekt und wird auch aufgerufen, da bin ich mir sicher.
7
Lowlevel-Coding / Re: Cursor setzen
« am: 15. May 2007, 03:01 »
Ich hab jetzt mal ganz am anfang, noch vor dem mappen und alles sonst, etwas code zum nullen des Cursors hinzugefügt:
mov dx, 0x03d4
mov al, 0x0e
out dx, al

mov dx, 0x03d5
mov al, 0x00
out dx, al

mov dx, 0x03d4
mov al, 0x0f
out dx, al

mov dx, 0x03d5
mov al, 0x00
out dx, al

Und siehe da... es geht. Dann noch weiter an verschiedenen Stellen des Assemblerstarts. Der Punkt, ab dem es nicht mehr geht, ist gleich nach dem die Konstruktoren aufgerufen wurden. Der einzige Konstruktor ist der vom Singleton.

Ich vermute daher sehr sehr stark dass das auslesen des Cursors im Konstruktor einen Schreibzugriff irgendwie nicht mehr zulässt. Daher muss jetzt also entweder wissen warum nicht mehr, oder herausfinden wie ich ein immer wiederholendes Initialisieren des Singleton verhindern kann.
3. Möglichkeit: Ich schreib alles wieder in C.
8
Lowlevel-Coding / Re: Cursor setzen
« am: 14. May 2007, 18:22 »
Ja na gut... die Sache mit dem Singleton ist ja aus dem Game-Bereich übernommen, als ich noch so was gemacht hab... da hat es Größtenteils geklappt.

Hier die video.h (der relevante Teil jedenfalls)
#ifndef __VIDEO_H__
#define __VIDEO_H__

class CVideo
{
protected:
void putc(char c);
void putnum(int num);
void scroll();
void update_cursor();

CVideo();

unsigned short *m_pVideoMem;
unsigned char m_nColour;
unsigned short m_nCursor;
static CVideo m_Instance;
public:
static CVideo getInstance();

CVideo &operator << (const char c);
CVideo &operator << (const char *str);
CVideo &operator << (const int num);

void setColour(unsigned char colour);
void cls();
};

#endif

Und die Implementation, video.cpp (diesmal fast alles):

#include <system.h>
#include <video.h>

extern "C" void cursor(unsigned short crs);

const int COLS = 80;
const int ROWS = 25;

CVideo CVideo::m_Instance = CVideo();

CVideo::CVideo()
{
m_pVideoMem = (unsigned short*)(0xb8000);
m_nColour = 0x07;

outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
}

CVideo CVideo::getInstance()
{
return m_Instance;
}

void CVideo::putc(char c)
{
if(c == '\n')
{
m_nCursor = (m_nCursor + COLS) & ~(COLS - 1);
}
else if(c == '\b')
{
if(m_nCursor > 0) m_nCursor--;
}
else if(c == '\t')
{
m_nCursor = (m_nCursor + 8) & ~(8-1);
}
else if(c >= 0x20)
{
m_pVideoMem[m_nCursor] = c | m_nColour << 8;
m_nCursor++;
}

scroll();
update_cursor();
}

void CVideo::putnum(int num)
{
char tmp[8];
int i = 0;

if (num == 0) putc('0');
else
{
while (num > 0)
{
int j = num % 0x10;
if(j < 10) tmp[i++] = '0' + j;
else
{
j -= 10;
tmp[i++] = 'A' + j;
}
num /= 0x10;
}
while (i-- > 0)
{
putc(tmp[i]);
}
}
}

void CVideo::scroll()
{
if(m_nCursor >= (COLS * ROWS))
{
memcpy(m_pVideoMem,&m_pVideoMem[COLS],COLS * (ROWS-1));
memsetw(&m_pVideoMem[COLS * (ROWS-1)],0,COLS);
m_nCursor = COLS * (ROWS-1);
}
}

void CVideo::update_cursor()
{
outport(0x03d4,0x0f);
outport(0x03d5,m_nCursor & 0xff);
outport(0x03d4,0x0e);
outport(0x03d5,m_nCursor >> 8);
}

void CVideo::cls()
{
memsetw(m_pVideoMem,0,COLS*ROWS);
outport(0x03d4,0x0f);
outport(0x03d5,0x00);
outport(0x03d4,0x0e);
outport(0x03d5,0x00);
}

void CVideo::setColour(unsigned char colour)
{
m_nColour = colour;
}

CVideo &CVideo::operator <<(const char c)
{
putc(c);
return *this;
}

CVideo &CVideo::operator <<(const char *str)
{
while(*str != '\0') putc(*str++);
return *this;
}

CVideo &CVideo::operator <<(const int num)
{
putnum(num);
return *this;
}

Dazu noch der Assemblerteil für die Konstruktoren:

extern __ctors_start__, __ctors_end__, __dtors_start__, __dtors_end__

; call the constructors
static_ctors_loop:
mov ebx, __ctors_start__
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, __ctors_end__
jb .body

sti

; call kernel proper
mov eax, [multiboot]
push eax
call main
add esp, 4

; call the destructors
static_dtors_loop:
mov ebx, __dtors_start__
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, __dtors_end__
jb .body

cli
hlt

Das war's so weit...
9
Lowlevel-Coding / Re: Cursor setzen
« am: 14. May 2007, 00:33 »
Die Zeichenausgabe ist wunderschön, so funktioniert alles.

Hier die Ganze story: Der Kernel ist der neueste rewrite des Scén-Kernels. Hier wollte ich möglichst viel Objektorientiert arbeiten. Bisher hab ich es geschafft (siehe Topic), den Kernel an die Adresse 0xc0000000 zu mappen.
Die Klasse CVideo soll überall gleichermaßen zu benutzen sein. Um dies zu erreichen, wird eine statische Variable als Instanz definiert. Da allerdings ein statisches Objekt bei jedem Aufruf neu erzeugt wird (weshalb die Bezeichnung 'static' eher Schwachsinn ist), wird im Konstruktor der Hardware-Cursor ausgelesen. Somit ist es natürlich wichtig, dass der immer korrekt gesetzt ist.

Es passiert folgendes: Bochs setzt den Cursor irgendwo in die mitte des Bildschirms. Dann, bei jedem Aufruf, also
CVideo::getInstance() << "String";Wird das objekt erzeugt, der String wird dargestellt, aber der Cursor nicht gesetzt. Beim nächsten Aufruf startet er also wieder an der Adresse des Hardware-Cursors, der noch von Bochs stammt.
Die schreib-routine ist die selbe wie immer, gefunden im BKerndev und anderen Tuts bei Bona Fide. Hab's auch 3000mal kontrolliert.
Das schärfste: Hab auch disassmebliert und mit dem alten C-Kernel verglichen, wo es funktionierte. Exakt das selbe.

Was bisher implementiert ist: Paging, PSE (die einzige Neuerung zu vorher), Exceptions (also die ersten 32 interrupts), und die IRQs, aber nur definiert, noch nichts weiter.

also der einzige unterschied sind die Zeilen
mov eax, cr4
or eax, 0x11
mov cr4, eax
Für die 4MB-Pages, aber das isses nicht oder?
10
Lowlevel-Coding / Re: Cursor setzen
« am: 13. May 2007, 01:58 »
ich hab mit dem inline assembler etwas gemacht... und dann einfach, weil's mir so langsam reicht, alles komplett mit assembler gemacht, also due cursor-funktion:
        [GLOBAL cursor]
cursor:
push ebp
mov ebp, esp

mov ebx, [ebp + 8]

mov al, 0x0e
mov dx, 0x03d4
out dx, al

mov al, bl
mov dx, 0x03d5
out dx, al

mov al, 0x0f
mov dx, 0x03d4
out dx, al

mov al, bh
mov dx, 0x03d5
out dx, al

leave
ret

ABER: ES GEHT IMMER NOCH NICHT!!!

Ich raste bald aus, es ist doch DER SELBE CODE den ALLE ANDEREN und auch ich selbst benutzen, und der immer funktioniert... NUR HIER NICHT...
WARUM NUR??
11
Lowlevel-Coding / Re: Cursor setzen
« am: 12. May 2007, 20:41 »
Standardmäßig sahe sie so aus:
        [GLOBAL outport]
outport:
push ebp
mov ebp, esp

mov edx, [ebp+8]
mov eax, [ebp+12]

out dx, al

leave
ret

[GLOBAL inport]
inport:
push ebp
mov ebp, esp

mov edx, [ebp+8]

in al, dx

leave
ret
So hab ich sie immer genutzt... Als das auf einmal im C++ Kernel nicht funktioniert hat, hab ich versucht, das so zu machen:
unsigned char inport(unsigned short port)
{
unsigned char value;
__asm__ __volatile__ ("inb %1, %0" : "=a"(value) : "d"(port));
return value;
}

void outport(unsigned short port,unsigned char value)
{
__asm__ __volatile__ ("outb %b0,%w1" : : "a"(value), "d"(port));
}
(Gefunden in dem OSD Kernel Paket auf Bona Fide)

Edit: Vorher hab ich immer die ASM-Funktionen genutzt... Hat auch immer funktioniert. Nebenbei, der outport bei
outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
muss ja funktionieren, da der Cursor richtig ausgelesen wird. Nur nicht richtig gesetzt... Der steht im Konstruktor (weil statische Klasseninstanz), also wird die Variable initialisiert.

Der Code
outport(0x03d4,0x0e);
outport(0x03d5,0x00);
outport(0x03d4,0x0f);
outport(0x03d5,0x00);
geht ja auch nicht...

Nebenbei... von inline assembler von gcc hab ich keine ahnung... Versteht den überhaupt jemand? Der ist so kryptisch...
12
Lowlevel-Coding / Re: Cursor setzen
« am: 12. May 2007, 14:44 »
Nein, m_nCursor enthält die bereits berechnete Position, also eigentlich nur das Offset (m_nOffset wäre ein besserer Name, geb ich zu...) Somit muss die Berechnung ja nicht erfolgen. Um eins weiter zu gehen, inkrementiere ich diese Variable nur, ist einfacher als immer mit einem X- und einem Y-Wert zu rechnen und geht auch schneller.
In C hatte ich das schon einmal so gemacht, und es hat funktioniert. Geht es einfach nicht, weil ich C++ verwende, oder was?

Add: Hab jetzt mit X- und Y-Werten probiert, immer noch nicht...
13
Lowlevel-Coding / Cursor setzen
« am: 12. May 2007, 04:20 »
Ich schätze mal, jeder von euch hat diesen kleinen Abschnitt so in seinem Kernel zu stehen:
        outport(0x03d4,0x0f);
outport(0x03d5,m_nCursor & 0xff);
outport(0x03d4,0x0e);
outport(0x03d5,m_nCursor >> 8);
Oder zumindest sehr ähnlich. Also, dieser Code funktioniert bei mir auf einmal nicht mehr. Zuerst dachte ich, es wäre ein neuer Bug von Bochs. Nein. Es ist auch kein Compilerfehler, hab den Assmblercode überprüft. Ich habe auch die outport Funktion in Assembler und in C geschrieben, kein Unterschied. Ich hab jetzt keine Ahnung was ich hier machen soll, denn der Cursor wird einfach nicht gesetzt.
An einer anderen Stelle lese ich die Register um meine Cursor-Variable zu updaten, das klappt.
        outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
Auch der Versuch, den Cursor auf 0|0 zu setzen, also direkt 0x00 als Positionen zu übergeben, hat nicht funktioniert.
Nun sitz ich hier bis 4 Uhr nachts nur wegen diesem Fehler, und ich könnte schreien, weil ich nicht wieß, was es ist.

Was ist hier falsch? Ist das wiedermal so etwas, dass Code der sonst immer geht, nur bei mir wieder mal absolut nicht funktioniert? Hatte ich ja sch öfters...
14
Lowlevel-Coding / Re: CPU - Zyklen in eigenem Register?
« am: 09. May 2007, 03:15 »
und ab welchen prozessor ist dieses register implementiert?
Und man braucht doch nocht immer einen interrupt, der Kernel muss doch irgendwann rdtsc ausführen, um dann zum nächsten task zu springen, oder?
15
Lowlevel-Coding / Re: Virtualising
« am: 06. May 2007, 02:36 »
Mann wegen dem Abi hab ich kaum Zeit mich damit zu befassen...
Also, hab jetzt mal selbst versucht, mit dem mappen. Ich kriege eine fehlermeldung, jedes mal, wenn ich versuche, daten in dem gemappten kernelbereich, also 0xc0000000, anzusprechen. Soll heißen, irgendwie is da wohl was nicht gemappt. Ich hab aber keine ahnung, was ich hier noch vergessen habe.

[EXTERN main]
[EXTERN __phys_kernel_start__]
[EXTERN __phys_kernel_end__]

[GLOBAL start]
start:

cmp eax, 0x2badb002
je start1
failure:
cli
hlt

start1:
mov eax, multiboot
sub eax, DIFF
mov [eax], ebx

;clear the page directory
mov eax, 0x00200000
mov ecx, 0x1000 / 0x04
.0:
mov dword [eax], 0x02
add eax, 0x04
loop .0

;mirror-map 0x00000000 to 0x00100000
mov eax, 0x00201000
mov ebx, 0x00000000 | 0x03
mov ecx, 0x1000 / 0x04
.1:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
loop .1

;mirror-map 0x00100000 to 0x00200000
mov eax, 0x00202000
mov ebx, 0x00100000 | 0x03
mov ecx, 0x1000 / 0x04
.2:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
loop .2

;map the kernel
mov eax, 0x00203000
mov ebx, __phys_kernel_start__
or ebx, 0x03
.3:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
cmp ebx, __phys_kernel_end__
jle .3

;set the pages
mov dword [0x00200000], 0x00201000 | 0x03
mov dword [0x00200001], 0x00202000 | 0x03
mov dword [0x00200c00], 0x00203000 | 0x03

;set directory
mov eax, 0x00200000
mov cr3, eax

;activate paging
mov eax, cr0
or eax, 0x80000000
mov cr0, eax

lgdt [gdtp]
jmp OS_CODE_SEL:start2

start2:
mov ax, OS_DATA_SEL
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax

mov esp, stack

mov eax, [multiboot]
push eax
call main
add esp, 4

cli
hlt


[SECTION .data]

multiboot dd 0

was mache ich falsch?
16
Lowlevel-Coding / Re: nasm coding: kernel zu groß
« am: 30. April 2007, 21:52 »
Wisst ihr überhaupt was das Ziel ist?
Meld dich, ich mach bei eurem Team mit... wenn ich darf ;)
17
Lowlevel-Coding / Re: nasm coding: kernel zu groß
« am: 30. April 2007, 15:52 »
Linken is kompliziert wenn es ein 16 bit os ist, weil die meisten linker (ld usw.) erstellen schon automatisch 32 bit binaries aus den obj-dateien.

@Snake707: Einfach dranpappen ist zwar für den Anfang, wenn man einfach mal was zum laufen bringen will (sprich 'Hallo Welt') schön und schnell, aber wenn du und dein Team da was richtiges zustande bringen wollt, dann programmiert erstmal einen FAT12-Bootloader (oder nehmt den der hier in den wiki-links steht).
Ihr müsst bedenken dass 5 KB wirklich höchstens ausreichen um eine Konsole ohne Funktionalität zu erstellen. Dateioperationen, Speichermanagement und so weiter sind wichtige Funktionen die auch in Assembler viel Platz brauchen.
Wenn du willst kannst du dich mal mit mir in Verbindung setzen (messenger adressen stehen links) und dann kannst du mir mal erzählen was ihr machen wollt und ich helf euch mal ;)

(edit) Ein zu großer Kernel wäre im real mode alles was über 64 KB hinausgeht.
18
Lowlevel-Coding / Re: nasm coding: kernel zu groß
« am: 27. April 2007, 15:48 »
5 KB?  Ist das jetzt ein 16 bit/real mode Kernel?
Wenn man mal bedenkt, dass M$-DOS 1 schon mehr brauchte (und der Funktionsunfang war nicht so groß), solltet ihr etwas mehr voranschlagen als 5 KB.
Durch %include wird die datei nur verlinkt, soll heißen der nasm preprozessor fügt die datei ein also ob ihr den Code direkt dort geschrieben hättet, also erhöht höchstens die Lesbarkeit.
versuchen könntet ihr noch optimierung an einigen stellen, also zeilen sparen, oder halt variablen sparen.
19
Lowlevel-Coding / Re: Virtualising
« am: 24. April 2007, 12:28 »
Mal sehen ob ich den Assemblerstub jetzt richtig interpetiert habe (sorry, hat ne weile gedauert, abitur), ich hab so meine probleme mit der AT&T Syntax:
Zuächst wird die addresse für den header korrigiert und schon mal gepusht, damit ebx frei ist. Dann is was mit dem eflags register (keine ahnung was). Dann wird der header geparst und der speicherbedarf der von GRUB geladenen Module berechnet. Diese addresse, wo die module enden, wird dann auf die nächste Page aufgerundet.
Danach beginnt das mappen... Wobei ich da jetzt verwirrt bin, weil ich nich sehen kann was nun wohin gemappt wird und wo die pages und so liegen... Kannste das nochmal erklären?
20
Lowlevel-Coding / Virtualising
« am: 20. April 2007, 17:15 »
Tja...
Für Multitasking wäre es ja nützlich, den Speicher virtuell zu mappen. Auf Bona Fide wollte ich mich schlau machen. Da hab ich Beispielkernel gefunden und die Memory Management Tutorials von Tim Robinson. War ja ganz nett, aber als ich dann and Implementieren gehen wollte, stieß ich dann auf Probleme... Mappen bringt Fehler, ich hab lange an der Linkerfile rumgespielt, aber brachte nichts.
Was ich vorhabe: Der Kernel soll nach 0xf0000000 gemappt werden (256 MB sollten für ihn reichen), die Programme haben dann auch mehr Platz. Wie und wann soll ich dann im Kernel mappen? Ich will einen Stack für die Pages, wie krieg ich den aufgebaut?
Ich bräuchte irgendwie konkrete Hilfe oder Codestückchen, weil ich hier echt nicht mehr weiterkomme...
Wäre nett wenn mir jemand helfen könnte, danke ^^
Seiten: [1] 2 3 4

Einloggen