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

Seiten: [1] 2 3
1
Lowlevel-Coding / Re:Executable Loader
« am: 22. April 2011, 18:44 »
Du erstellst für jeden Task eine Page? Dann wird der GPF wohl daher kommen, dass die zweite Page nicht oder falsch gemappt ist. Üblicherweise sind Programme nämlich größer als eine Page...

Gruß,
Svenska
So, das habe ich jetzt gelöst. Ich mappe genausoviel wie ich brauche. Ich mappe genau soviel wie mein Task braucht.
und Programme (also eigenständige Prozesse) benötigen nicht nur eigene Pages sondern ein komplettes eigenes Paging-Directory das dann diese eigenen Pages verwaltet. ;)
Und hier meinte ich eigentlich auch Pagedirectory und nicht Page. Danke für den Hinweis

Mein Loader funktioniert jedenfalls so wie ich das sehe. Vielen Dank, an alle die sich Gedanken gemacht haben
2
Lowlevel-Coding / Re:Executable Loader
« am: 19. April 2011, 20:40 »
Tut mir leid, dass ich solange nicht geschrieben haben. Ich musste sehr viel für meine Entwicklungsumgebung tun.
Ich mache jetzt gerade weiter. Die Datei ist komplett korrekt eingelesen. Die Adler32-Summen sind gleich.
Nachdem ich Paging eingebaut habe, erstelle ich für diesen Task (wie für jeden anderen auch) eine eigene Page. Nachdem Wechsel zum neuen Task, gibt es einen GPF.

Wäre nett, wenn sich nochmal jemand melde, obwohl ich solange nicht online war
3
Lowlevel-Coding / Re:Executable Loader
« am: 14. December 2010, 09:04 »
@taljeth: Die ELF Magic ist aber immer noch funktionsfähig. Sonst er ja hier abstürzen:if (header->magic != ELF_MAGIC) {
   kprintf("Keine gueltige ELF-Magic!\n");
   return 0;
}
Aber er kann ja auch später abstürzen.
@erik.vikinger: Der gesammte hexdump liegt hier. Ist die ELF Datei evt. korrupt?

S.
4
Lowlevel-Coding / Executable Loader
« am: 13. December 2010, 20:39 »
Hallo zusammen,
nachdem ich meinen Floppy / Fat Treiber fertig hatte, wollte ich jetzt auch mal Dateien in laden und starten. In Teil 8 des Tutorials, wurde ein ELF-Loader erklärt. Den habe ich auch funktionsfähig (zumindest bei von GRUB übergebenen Modulen) implementiert. Jetzt habe ich vor, die Daten, die ich von der Floppy gelesen habe, als ELF zu starten.
Das Problem ist, dass ich bekomme, wenn ich die ELF Datei starte, einen Invalid Opcode bekomme.
char app[size]; //Speicher reservieren
kmemset((void*) &app[0], 0x0, size);//Speicher zu sicherheit putze
readFile( f, size, &app[0] ); //Von der Floppy einlesen
char *appP = &app[0]; //Sonst funktioniert es nicht....
initELF( (void*) appP, 20); //ELF Datei laden
Dazu der ELF Loader:

void *initELF(void* image, int pri)
{
    /*
     * FIXME Wir muessen eigentlich die Laenge vom Image pruefen, damit wir bei
     * korrupten ELF-Dateien nicht ueber das Dateiende hinauslesen.
     */
 
    struct elf_header* header = image;
    struct elf_program_header* ph;
    int i;
 
    /* Ist es ueberhaupt eine ELF-Datei? */
    if (header->magic != ELF_MAGIC) {
        kprintf("Keine gueltige ELF-Magic!\n");
        return 0;
    }
 
    /*
     * Alle Program Header durchgehen und den Speicher an die passende Stelle
     * kopieren.
     *
     * FIXME Wir erlauben der ELF-Datei hier, jeden beliebigen Speicher zu
     * ueberschreiben, einschliesslich dem Kernel selbst.
     */
    ph = (struct elf_program_header*) (((char*) image) + header->ph_offset);
    for (i = 0; i < 2/*header->ph_entry_count*/; i++, ph++) {
        void* dest = (void*) ph->virt_addr;
        void* src = ((char*) image) + ph->offset;
 
        /* Nur Program Header vom Typ LOAD laden */
        if (ph->type != 1) {
            continue;
        }
 
        kmemset(dest, 0, ph->mem_size);
        kmemcpy(dest, src, ph->file_size);
    }
 initTask( (void *)header->entry, pri);
    return (void*) header->entry;
}
Ich musste
header->ph_entry_count gegen 2 austauschen, weil der Wert bei ungefähr 30 000 liegt.

Die ELF Datei lädt er auch, aber sobald ich einen Syscall von dem ausgeführten Programm aufrufe, geschieht der Invalid Opcode.

Hat einer von euch eine Idee?
S.
5
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 28. November 2010, 09:48 »
Also komme ich für Cluster 3(test1.txt) auf 0xfff und für Cluster 4(test2.txt) auch auf 0xfff.
Das verstehe ich nicht so ganz:
  • Eintrag 0: 0xF0F
  • Eintrag 1: 0xFFF
  • Eintrag 2: 0x00F
  • Eintrag 3: 0x0FF
  • Eintrag 4: 0xFF0
  • Eintrag 5: 0xF00
Das müsste doch eigentlich richtig sein, oder? Wie kommst du denn an deine 0xFFF?
Aus den Einträgen 0x11 0x21 0x22 bekommt  man 2 Cluster: 0x111 und 0x222.
Muss man die Einträge auch andersherum lesen? Also so muss ich, wenn in der FAT "f0 ff ff 00 f0 ff ff 0f  00" steht, jedes Byte umdrehen, und dann hintereinander schreiben:
  • 0xF0 -> 0x0F
  • 0xFF -> 0xFF
  • 0xFF -> 0xFF
  • usw.
Dann hätte ich:
  • Eintrag 0: 0x0FF
  • Eintrag 1: 0xFFF
  • Eintrag 2: 0x000
  • Eintrag 3: 0xFFF
  • Eintrag 4: 0xFFF
  • Eintrag 5: 0x000
Das sieht erstmal ganz vielversprechend aus: Ich habe viele Werte zwischen 0xFF8 und 0xFFF, also das Ende einer Clusterkette. Ich glaube ich hab es jetzt verstanden:
Den Wert aus dem Verzeichniseintrag (=0x300 -> 0x001) schlage ich in der FAT nach (0xFFF) und stelle fest das die Datei zu Ende ist. Dann Lese ich den 0x001-sten Datensektor (=0x22), wo die Datei liegt.

Vielen Dank für die Denkanstöße

PS: Zu dem Patent von MS hab ich bei meinen Recherchen dies hier gefunde: Bundespatentgericht erklaert FAT Patent von Microsoft fuer nichtig.


EDIT:
Mein FAT Treiber funktioniert jetzt  :-D
6
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 26. November 2010, 17:00 »
Super! Vielen Dank, aber: Jetzt habe ich 0x00F (=15). Was bedeutet das jetzt? Ist das der Startsektor? Der ist aber 0x22 (=36). Gibt es eine Verschiebung oder wie kann ich jetzt den Startsektor 0x22 berechnen?
7
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 26. November 2010, 15:23 »
Also: Ich habe ein FAT-12 Floppy Image ( http://sesdll1.se.funpic.de/lowlevel/fdc/floppy.img ). Der Hexdump liegt unter http://sesdll1.se.funpic.de/lowlevel/fdc/floppy.hex. Wir wollen jetzt erstmal nur Datei 1 ("TEST1.TXT") betrachten:
  • Laut hexdump, beginnt die Datei bei Cluster 0x0300. Also (weil in der Rootdirectory der Cluster als Little Endian steht) beginnt die Datei 0x1.
  • Im ersten (0x1) FAT Eintrag steht: 0xF0F.
  • Die Datei beginnt tatsächlich bei dem Byte 0x4400, also bei Cluster (bzw. Sektor) 0x22.
Wie komme ich jetzt von dem FAT-Eintrag (0xF0F) auf den Cluster (0x22)?
8
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 25. November 2010, 14:27 »
Gut, jetzt habe ich zwar den richtigen FAT Eintrag. Der ist für die erset Datei laut hexdump 0xF0F. Ich glaube ich muss den EIntrag mit 2 subtrahieren. Also habe ich 0xF0D. Wie komme ich jetzt von 0xF0D bzw. 0xF0F auf die Dateiadresse 0x0004400?
Danke
9
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 24. November 2010, 17:36 »
Also die Konvertierung zwischen dem, was die FAT mir gibt, und dem, was ich brauche, hab ich jetzt:
akfile->clusterID = ( akfile->clusterID >> 8 ) | ( (akfile->clusterID & 0xF0)  ) | ( (akfile->clusterID & 0xF)  << 8 ) ;

Die Zahl steht in akfile->clusterID drin. Beispiel:
akfile->clusterID = 0x345;
akfile->clusterID = ( akfile->clusterID >> 8 ) | ( (akfile->clusterID & 0xF0)  ) | ( (akfile->clusterID & 0xF)  << 8 ) ;
//                =   0x003                    |     0x04                        | (   0x005                    << 8 ) ;
//                =   0x003                    |     0x04                        |     0x500                           ;
//                =   0x543                                                                                            ;
10
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 24. November 2010, 16:17 »
Funktioniert bei mir leider nicht.  :cry:
Folgende Situation:
const int sysbuffer = 0x1000; //Fuer DMA notwendig
#define GANZVIEL 224*0x20
...
kmemset((void*) sysbuffer, 0x0, 0x2400); //Systembuffer loeschen
readSector(19); // start at 0x2600: root directory (14 sectors)

uint8_t buf[GANZVIEL];
kmemcpy( (void *) buf, (void *) sysbuffer, GANZVIEL);
akfile->clusterID = (uint16_t*) &buf[0x20*i + 0x1A];
...
So wie ich das jetzt habe, funktioniert es nicht. Ich habe jetzt Werte wie 0x22FA statt 0x3 bzw. vom FAT 0x0300. Wie hängt das alles zusammen?
11
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 23. November 2010, 19:33 »
x86-Prozessoren arbeiten auch mit Little Endian, du brauchst also gar nichts besonderes zu machen, sondern musst einfach nur einen uint16_t* darauf zeigen lassen und den auslesen. Das kannst du dir auch schonmal merken, falls du dir den RAM irgendwann mal byteweise dumpen lässt. Dann musst du auch "falschrum" lesen.
Gut, muss ich jetzt also schreiben?
uint16_t x = ...; //Clusternummer laut Root directory
uint16_t *p = &x;
//Und in *p ist jetzt die Variable, wie ich sie brauche?
Also, das ist definitiv falsch. Ich glaube ich habe dich nicht ganz verstanden, taljeth.
12
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 22. November 2010, 20:49 »
Das klärt für mich vieles auf. Was ich euch gepostet habe, war ein Eintrag in die Root Directory. Wie benutze ich den einen Little Endian in C?
13
Lowlevel-Coding / Re:FAT Dateiadressierung
« am: 22. November 2010, 19:40 »
Ich glaube, ich habe die Lösung selber gefunden: Der Cluster bezieht sich schließlich auf den Eintrag in der FAT  :-D
14
Lowlevel-Coding / FAT Dateiadressierung
« am: 22. November 2010, 18:31 »
Hallo zusammen,
ich habe ein Problem mit der FAT12 Dateiadressierung. Das Image und der Hexdump ist wie immer unter http://sesdll1.se.funpic.de/lowlevel/floppy.img bzw. http://sesdll1.se.funpic.de/lowlevel/floppy.img.hex zu finden. Hier der wichtigste Teil:
Zitat
00002620  54 4d 50 30 20 20 20 20  54 58 54 20 00 64 43 6b
00002630  73 3d 73 3d 00 00 43 6b  73 3d 03 00 06 00 00 00
Es handelt sich um die erste Datei. Der Hexdump sagt mir, dass die Datei am fett hinterlegtem Cluster 0x0300 beginnt. Weil bei FAT12 ein Cluster einem Sektor entspricht, und weil bei einer Floppy (zumindest so wie ich meine formatiert habe) ein Sektor 512 byte (=0x200) groß ist, sollte die Datei bei 0x300*0x200 = 0x60000 liegen. Laut Hexdump liegt die Datei aber schon bei 0x4400 byte bzw. Sektor 0x22.
Wie kann ich jetzt aus dem Cluster des Hexdumps (=0x300) den Sektor nach LBA berechnen?

Spaceemotion
15
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 19. November 2010, 14:46 »
Wie auch immer. Ich hab den Code neu geschrieben und er funktioniert.

S.
16
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 15. November 2010, 15:15 »
Als ich den die Zeile auskommentiert und eine while(1); danach eingebaut. Der Fehler trat nicht mehr auf. Also hat er etwas mit dem sendPara() zu tun.

Hmm… ich weiß jetzt nicht genau wo du das "while" hingesetzt hast, aber wenn mit 'while' kein Fehler Auftritt dann liegt der Fehler eindeutig hinter dem 'while', das ist dir aber wahrscheinlich klar und du hast dich nur nicht genau ausgedrückt.

Zu deinem code: 
Wo der Wiki-Code 'send_cmd' benutzt, benutzt du 'out', auch wenn das bei QEMU vermutlich nichts ausmachen sollte, könnte das spätestens bei echter HW zu Problemen fuhren wenn du nicht wartest bis der FDC bereit ist.
Ich glaube, dass ich hier ein paar Missverständnisse beseitigen muss:
  • outb ist eine ganz Normale Funktion um einen Wert in einen Port zu schreiben
  • Das while(1); ab ich wie folgt positioniert:
....
//sendPara( fdc.acDrive | (H << 2) ); //H = head, fdc.acDrive = aktueller Drive
while(1);
So tritt kein Fehle auf.

S.
17
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 14. November 2010, 12:57 »
Als ich den die Zeile auskommentiert und eine while(1); danach eingebaut. Der Fehler trat nicht mehr auf. Also hat er etwas mit dem sendPara() zu tun.
taljhet hat allerdings recht, was seine "Fehlerdifinition" angeht.

S.
18
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 14. November 2010, 11:29 »
Oh, ja. Sorry. Ich hatte in der Funktion wohl ein falsches Bitflag. Das hab ich jetzt behoben. Jetzt bekomme ich von QEMU diese Meldung: FLOPPY ERROR: fdctrl_unimplemented: unimplemented command 0x96Also sende ich ein Befehl ab, den es nicht gibt, aber das mache ich eigentlich garnicht. Hier der Codeauszug:
void sendPara( uint8_t para )
{
while( (inb( MSR) & 0xC0) != 0x80 ); //MSR = 0x3F4
outb( DATA_FIFO, para );  //DATA_FIFO = 0x3F5
}
...
uint8_t cmd = (0x05 | 0x40);
outb(DATA_FIFO, cmd );
sendPara( fdc.acDrive | (H << 2) ); //H = head, fdc.acDrive = aktueller Drive
sendPara( C ); //Cylinder
sendPara( H );
sendPara( S ); //Sektor
sendPara( 2 );
sendPara( (int) size/512. );
sendPara( 0x1B );
sendPara( 0xFF )

Der Fehler liegt in der ersten Parameterübergabe, also hier: sendPara( fdc.acDrive | (H << 2) ); Qemu sagt mir ja, dass ich 0x96 sende, ich weiß aber nicht wo.  :?
19
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 14. November 2010, 08:24 »
Ja, die Funktion habe ich getestet. Das Programm kommt bis zur Executionphase der Schreibfunktion, wo ich auch den Fehler vermute. QEMU meckert rum: FLOPPY ERROR: fdctrl_start_transfer: dma_mode=0 direction=1. Die Executionphase war auch der Teil den ich am schlechtesten verstanden habe. Code wieder auch oben genanntem Link. Ich wollte die ganze Aktion ohne DMA machen, weil mit PIO einfacher erschien.

S.
20
Lowlevel-Coding / Re:Probleme mit dem FDC
« am: 13. November 2010, 13:13 »
Genau das habe ich jetzt getan. Ich bin mir allerdings unsicher bei einigen Punkten:
  • Wo fehlen noch welche Wartezeiten?
  • Bei der Lesefunktion habe ich bestimmt irgendeinen Fehler gemacht, weil ich die Anleitung von OSDev.org zu diesem Punkt nicht ganz verstanden habe.
Ich habe diese (http://wiki.osdev.org/Floppy_Disk_Controller) Anleitung benutz. Den Code findet ihr auf http://sesdll1.se.funpic.de/lowlevel/fdc/

S.
Seiten: [1] 2 3

Einloggen