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

Seiten: 1 2 3 [4] 5 6 ... 20
61
Lowlevel-Coding / Anfängerfrage
« am: 17. January 2006, 14:45 »
32 Bit Code im Realmode ist durchaus möglich (ab dem 386, die Prozessoren darunter hatten ja keine 32 Bit Register). Nur wird dann jedem Befehl ein Prefix vorangestellt, und man kann weiterhin nur 20 Bit Addressieren (4 Bit Segmente, 16 Bit Offsets).
62
Hier ist ist Beispiel für den lokalen APIC Timer und dem Timestamp Counter (TSC):
Der lokale APIC bietet den genausten Timer des x86, da er von der Prozessor Busgeschwindigkeit abhängt. Daher muss er vorher kalibriert werden, um die Busgeschwindigkeit herauszubekommen.
Der TSC gibt die Anzahl der vergangenen Taktzyklen zurück, seitdem man den Prozessor eingeschaltet hat. So kann man ihn auch für Delays benutzen.

Der folgende Code ist in C, ich hoffe mal, dass du ihn selbst in Assembler umsetzen kannst.
#define LAPIC_REG_ID 0x020
#define LAPIC_REG_VERSION 0x030
#define LAPIC_REG_TPRI 0x080
#define LAPIC_REG_EOI 0x0b0
#define LAPIC_REG_SIVR 0x0f0
#define LAPIC_REG_ESR 0x280
#define LAPIC_REG_ICR1 0x300
#define LAPIC_REG_ICR2 0x310
#define LAPIC_REG_LVTT 0x320
#define LAPIC_REG_LINT0 0x350
#define LAPIC_REG_LVT3 0x370
#define LAPIC_REG_ICRT 0x380
#define LAPIC_REG_CCRT 0x390
#define LAPIC_REG_TDCR 0x3e0

// der lokale APIC befindet sich _normalerweise_ an 0xFEE00000
// das kann unterschiedlich sein, steht in einem MSR und wird vom BIOS programmiert
// wenn man den wert auslesen will, müsste man die multiprozessor informationen lesen, den code dafür poste ich nicht, da er viel zu lang wäre
// der apic ist aber in allen mir bekannten system an 0xFEE00000 also kann man sich normalerweise darauf verlassen
// bochs emuliert den apic code nur, wenn es dafür kompiliert wurde, qemu garnicht.
// für deine zwecke ist rdtscll() warscheinlich besser geeignet.
unsigned long *g_mp_lapic = (unsigned long *)0xFEE00000;

unsigned long long g_cpu_speed;
unsigned long long g_cpu_speed_temp;

unsigned long g_lapic_tempcount;
volatile unsigned long g_lapic_divisor;

// isr_lapic_timer() macht garnichts (nur IRET), isr_lapic_calibrate() ruft ruft lapic_calibrate_irq() auf
extern void isr_lapic_timer();
extern void isr_lapic_calibrate();

void lapic_calibrate() {
unsigned char byte;

g_lapic_tempcount = 0;
g_lapic_divisor = 0;
g_cpu_speed = 0;
g_cpu_speed_temp = 0;

// setup real time clock
// unmask IRQ 8
outByte(0x21, 0xFB);
outByte(0xA1, 0xFE);

// set interrupt gate
// interrupt gate an 0x28/0x80 setzen, mit pl 0
interrupt_setentry(0x28, isr_lapic_calibrate, 0);
interrupt_setentry(0x80, isr_lapic_timer, 0);

// set real time clock frequency
outByte(0x70, 0xA);
byte = inByte(0x71) & 0xF0;
outByte(0x70, 0xA);
outByte(0x71, byte | 0xF);

// setup apic timer
lapic_write(LAPIC_REG_LVTT, 0x80);
lapic_write(LAPIC_REG_TDCR, 0xA);
lapic_write(LAPIC_REG_ICRT, 0xFFFFFFFF);

// enable interrupt
outByte(0x70, 0xB);
byte = inByte(0x71);
outByte(0x70, 0xB);
outByte(0x71, byte | 0x40);

outByte(0x70, 0xC);
inByte(0x71);

while(g_lapic_divisor == 0) {
asm volatile ("nop");
}

// disable apic timer
lapic_write(LAPIC_REG_ICRT, 0);
lapic_write(LAPIC_REG_TDCR, 0xB);

// disable real time clock interrupt
outByte(0x70, 0xB);
outByte(0x71, byte & 0xBF);

debug_info("bus speed: %u hz\n", g_lapic_divisor);
// meine debug_info funktion kann keine long longs verarbeiten
debug_info("cpu speed: %u hz\n", (unsigned long)g_cpu_speed);
}

unsigned long long rdtscll() {
unsigned long long result;
asm volatile ("rdtsc" : "=A" (result));
return result;
}

void lapic_calibrate_irq() {
// read status register c
outByte(0x70, 0xC);
inByte(0x71);

unsigned long bus = lapic_read(LAPIC_REG_CCRT);
unsigned long long cpu = rdtscll();

if(g_lapic_tempcount == 0) {
g_lapic_tempcount = bus;
}else if(g_lapic_divisor == 0){
g_lapic_divisor = (g_lapic_tempcount - bus) * (128 / 2);
}

if(g_cpu_speed_temp == 0) {
g_cpu_speed_temp = cpu;
}else if(g_cpu_speed == 0) {
// wir haben nur eine halbe sekunde gewartet, daher * 2
// wenn du nicht weißt, wie du long longs multiplizieren und subtrahieren kannst in assembler, kann ich dir dafür einen codeschnippsel geben.
g_cpu_speed = (cpu - g_cpu_speed_temp) * 2;
}
}

// usecs microsekunden warten (1000 microsekunden = 1 millisekunde)
void lapic_delay(unsigned long usecs) {
unsigned long ticks = g_lapic_divisor / 1000000;

lapic_write(LAPIC_REG_ICRT, ticks * usecs);

while(1) {
if(lapic_read(LAPIC_REG_CCRT) == 0)
break;

asm volatile ("nop");
}
}

void lapic_write(unsigned short reg, unsigned long value) {
*(unsigned long*)((unsigned long)g_mp_lapic + reg) = value;
}

unsigned long lapic_read(unsigned short reg) {
return *(unsigned long*)((unsigned long)g_mp_lapic + reg);
}


Nach einem Aufruf von lapic_calibrate() steht in g_lapic_divisor der Bus Speed in HZ und in g_cpu_speed die Taskfrequenz in HZ.
Mit RDTSC kannst du dann solange warten, bis eine bestimmte Anzahl an Taken vergangen ist. Du musst warscheinlich viele Funktion an dein OS anpassen.^^
Der APIC hat den Vorteil, dass er auch Interrupts generieren kann. Den APIC kann man aber nur im PM benutzen, da er sich an einer Addresse befindet, die man im RM nicht ansprechen kann. Wenn du ihn nicht verwenden willst, kannst du einfach alle LAPIC spezifischen Codeteile löschen, er wird nicht zur Kalibrierung benötigt.
63
Lowlevel-Coding / Ring0 -> Ring3
« am: 11. January 2006, 21:28 »
cr3 muss man nicht in das TSS eintragen.
Bei einem Interrupt wird cr3 nicht getauscht.
64
OS-Design / Mit GRUB Module laden lassen
« am: 11. January 2006, 21:26 »
mods_count ist die Anzahl der Module und mods_addr ist ein Pointer auf ein Array von Strukturen, die Infos über das Modul enthalten. (Steht in der Multiboot Spezifikation, der Beispielkernel in der Spezifikation ist evt. auch ganz nützlich.)
65
OS-Design / Mit GRUB Module laden lassen
« am: 11. January 2006, 20:16 »
Ja, mit der Modul Anweisung kann man ein Modul laden lassen, die Position des Modules steht dann in der MB Info Struktur. Allerdings kann man die Addresse nicht selber angeben, Module werden immer hinter den Kernel geladen. Module können auch gegzippt sein, dann werden sie automatisch entpackt.
66
OS-Design / Mit GRUB Module laden lassen
« am: 11. January 2006, 19:01 »
Nein, Module werden in GRUB immer direkt über dem Kernel geladen, soweit ich weiß.
67
Lowlevel-Coding / Kernel startet nicht
« am: 10. January 2006, 07:39 »
Unter Linux wird nicht zwischen Binär und Textdateien unterschieden.
68
OS-Design / HAL
« am: 09. January 2006, 21:20 »
Userlevel Programme nutzen die Treiber und den Kernel, die Treiber und der Kernel nutzen das HAL.
So muss man nicht den Kernel für jede Architektur neu schreiben (oder zumindest kann man große Teile davon zwischen den Archtitekturen teilen (Scheduler usw.)), nur die Gerätetreiber (Filesystem Treiber z.B. nicht) und das HAL.
69
OS-Design / ein Datensegment für User und System?
« am: 09. January 2006, 21:17 »
Naja, das kann man ja durch Paging verhindern.
70
OS-Design / ein Datensegment für User und System?
« am: 09. January 2006, 20:31 »
Er meint, das der Kernel eh immer auf alle Daten zugreifen kann (solange CPL < 3 ist). Der Kernel kann auch auf Kerneldaten zugreifen, wenn man einen PL3 Descriptor hat.
71
OS-Design / ein Datensegment für User und System?
« am: 08. January 2006, 16:55 »
Laut den Intel Manuals hängt das Privileglevel von CS und SS ab, ich weiß zwar nicht genau auswendig, wie das von SS abhängt, aber ich würde vorsichtshalber mal einen eigenen Descriptor für jede Privilegstufe anlegen, der eine Eintrag in die GDT schmerzt ja auch nicht.
72
OS-Design / Idee für Kernelmodule
« am: 08. January 2006, 15:01 »
Der Speicherbereich von meinem Kernel und meinen Modulen geht von 0x0 bis 0x20000000, und ist also 512 MB groß. Darein werden alle Module gemappt. Da sie eh Just-In-Time compiliert werden sollen, kann ich sie gleich an eine freie Stelle laden und linken. Wenn du deine Module nicht Just-In-Time linkst, kannst du ja z.B. ELF Relocateables benutzen, und sie zur Laufzeit linken. Alle Module nutzen die selben Segmente, ich nutze nur 4 Segmente, jeweils eins für Kernel Code und Kernel Daten und eins für Usermode Code und Usermode Daten. Ich versuche aber, möglichst viel in Kernelmode Threads auszulagern, was nicht so Performancekritisch ist, um so Kernelspeicher zu sparen.
73
Lowlevel-Coding / Eigene Bytecodebasierte Sprache
« am: 07. January 2006, 14:36 »
Ja, ich hatte auch daran gedacht, einen eigenen Parser zu schreiben.
Ich verstehe aber noch nicht ganz, wie das jetzt funktionieren soll. Kannst du mir das Prinzip eines Recursive-Descent Parsers erklären, oder hast du irgentein Dokument, das es beschreibt?
EDIT: Ich habe bei Google eine ganz gute Beschreibung gefunden, ich werde sie mir mal ansehen :)
74
Lowlevel-Coding / Eigene Bytecodebasierte Sprache
« am: 07. January 2006, 13:04 »
Hm, ja, ich werde mal sehen, ob ich mir ein Buch kaufe.
Am meisten Probleme macht mir eigentlich der Parser, die Codegenerierung, die lexikalische Analyse usw. ist kein Problem.
Ich denke aber, das ich mit dem Projekt erst in einem Monat oder so anfangen werde.
75
Wenn die Treiber Programme/Prozesse sind, bräuchtest du wohl Spinlocks oder Semaphoren.
76
Lowlevel-Coding / Eigene Bytecodebasierte Sprache
« am: 06. January 2006, 20:31 »
Hi,
IMHO gibt es heute keine wirklich gute universelle Bytecode basierte Sprache. Java ist ganz gut, aber es hat keine Structs und keine unsigned Typen. Daher muss man bei der Eingabe/Ausgabe immer zwischen signed und unsigned umwandeln und verbraucht unötig viel Speicherplatz. .NET/C# behebt diese Probleme, jedoch hat es nur eine kleine Standardbibliothek und man muss häufig nativen Code einsetzen, was ich verhindern möchte. Ausserdem ist es intern nicht wirklich gut aufgebaut, .NET baut auf eine Art PE auf. .NET sollte zwar portabel sein, aber große Teile der Bibliotheken funktionieren nur unter Windows und sind proprietär. Hinzukommt, dass alle Sprachen bisher noch Wünsche beim Multithreading und bei der Speicherverwaltung offen lassen.

Deshalb habe ich mich entschlossen ein eigenes Bytecode Format und eine eigene Sprache zu entwickeln, das diese Features ergänzt.

Bei der Syntax hatte ich an eine Art C/C++/Java gedacht, da diese Syntax den meißten bekannt sein sollte.

Ich wollte jetzt mit einem Compiler für eine solche Sprache anfangen (der Compiler wird warscheinlich in Java geschrieben sein), und wollte fragen, ob jemand schon Erfahrungen im Compilerdesign hat. Wenn sich jemand beteiligen möchte, würde ich mich sehr freuen. Ich aber im Moment aber nicht so viel Zeit, da ich hauptsächlich an Legends und meinen Java-JIT Compiler arbeite. Dieser JIT ist ausserdem so flexibel, das meine eigene Sprache später, wenn der Compiler funktioniert, darin eingebettet werden könnte.

Naja, wie gesagt, hat jemand schon Erfahrungen im Compilerbau oder möchte jemand mitmachen?
77
Lowlevel-Coding / Make- u. Brakecodes ?
« am: 06. January 2006, 10:19 »
Hm, ich habe mich noch nicht so stark mit der Tastatur beschäftigt, aber ich glaube, du musst warten, bis noch ein Interrupt auftritt.
78
Lowlevel-Coding / Make- u. Brakecodes ?
« am: 06. January 2006, 10:12 »
Soweit ich weiß musst du dir selber im Tastaturtreiber merken, ob STRG, ALT usw. gedrückt wurden, die Scancodes werden nicht automatisch verändert, wenn STRG, ALT, SHIFT usw. gedrückt werden.
79
Lowlevel-Coding / Make- u. Brakecodes ?
« am: 06. January 2006, 09:58 »
void irq1_handler() {
unsigned char scancode = inb(0x60);

if(scancode & 0x80) {
// taste wurde losgelassen
}else{
// taste wurde gedrückt
}
}
80
Lowlevel-Coding / Make- u. Brakecodes ?
« am: 06. January 2006, 09:52 »
Toaster bezog sich auf Windows, Windows verarbeitet aber die Codes auch erstmal, bevor es die Messages sendet.

Die Brakecodes sehen genauso aus wie die Makecodes, nur haben sie das Bit 0x80 gesetzt,
Seiten: 1 2 3 [4] 5 6 ... 20

Einloggen