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

Seiten: [1]
1
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.
2
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
3
Lowlevel-Coding / Probleme mit dem FDC
« am: 12. November 2010, 13:39 »
Hallo zusammen,
ich habe ein Problem mit dem FDC. Wenn ich Daten von der Floppy einlesen will, bekomme ich
  • von QEMU folgende Meldung:
FLOPPY ERROR: fdctrl_start_transfer: dma_mode=0 direction=1
  • immer "S" zurück
Also Floppyimage habe ich ein einfaches Image ohne Dateisystem genommen, das ich mit echo "TEST" | dd of=floppy.img erstellt habe. Die Lesefunktion stammt von http://forum.osdev.org/viewtopic.php?t=17274.
floppy.h
/*
  +----------------------------------------------------------------------------------------+
  |                                                                                        |
  |                                     LionOS File                                        |
  |                                                                                        |
  +----------------------------------------------------------------------------------------+
  |                                                                                        |
  |                                        Floppy                                          |
  |                                                                                        |
  +----------------------------------------------------------------------------------------+
*/

#ifndef FLOPPY_H
#define FLOPPY_H

#define NUM_OF_FDD     1
#define NO_ERROR       0
#define ERROR_TIMEOUT  1

#define MSR 0x3F4
#define MSR_MASK_DATAREG 0x80
#define MSR_MASK_DIO2CPU 0x40
#define  CMD 0x3F5
#define MCMD 0x3F2
#define RDSR 0x3F4 //reg dsr
#define RDOR 0x3F2 //Reg dor
#define FLOPPY_MSR_DIO 0x40

#define DSR_SPEED_1MBPS 0x03
#define DSR_SPEED_500KBPS 0x00
#define DSR_SPEED_300KBPS 0x01
#define DSR_SPEED_250KBPS 0x02

#define CMD_WRITE_SECTOR (0x05 | 0x40)
#define CMD_READ_SECTOR (0x06 | 0x40)


#define CMD_SEEK 0x0F
#define FLOPPY_CMD_INT_SENSE 0x08
uint8_t fddDevice;
 
uint8_t error = NO_ERROR;
 
void send_cmd(uint8_t cmd);
void send_data(uint8_t data);
uint8_t read_data();

void initFDD();
void fdHandler(cpu_state *r);
void fddwaitForIRQ();

void resetFDD();
void fddMotor(int state);
void fddChooseDevice(uint8_t id);
int floppy_seek(uint8_t cylinder);
typedef struct fdd
{
int motor;
long la; //lastaccess
int irqRes;
int cylinder;
int head;
int sector;
int size;
uint8_t status;
} fdd;

fdd fd[NUM_OF_FDD];
void floppy_int_sense();
int transfer_sector(uint32_t lba, int write, void* buffer);
int fdc_read(unsigned char *data, unsigned int sector, unsigned int offset, unsigned int length);


#define CHANNEL_ADRESS 0x04
#define CHANNEL_COUNTER 0x05
#define CHANNEL_PAGE 0x81

#include "floppy.c"

#endif

floppy.c
/*
  +----------------------------------------------------------------------------------------+
  |                                                                                        |
  |                                     LionOS File                                        |
  |                                                                                        |
  +----------------------------------------------------------------------------------------+
  |                                                                                        |
  |                                        Floppy                                          |
  |                                                                                        |
  +----------------------------------------------------------------------------------------+
*/

#define CMD_WRITE_SECTOR (0x05 | 0x40)
#define CMD_READ_SECTOR (0x06 | 0x40)



uint8_t read_data()
{
uint8_t timeout;
for(timeout = 0; timeout < 200; timeout++)
{
if( (inb(MSR) & (MSR_MASK_DATAREG | MSR_MASK_DIO2CPU)) == (MSR_MASK_DATAREG | MSR_MASK_DIO2CPU))
{
error = NO_ERROR;
return inb(0x3F5);
}
sleepTicks(5);
}
error = ERROR_TIMEOUT;
return 0;
}
 
 
void send_cmd(uint8_t cmd)
{
send_data(cmd);
}
 
void send_data(uint8_t cmd)
{

fd[fddDevice].la    = getTime();
uint8_t timeout;
for (timeout = 0; timeout < 200; timeout++)
{
if ( (inb(MSR) & (MSR_MASK_DATAREG | MSR_MASK_DIO2CPU)) == MSR_MASK_DATAREG)
{
outb(CMD, cmd);
error = NO_ERROR;
return;
}
sleepTicks(1);  //5ms warten vor dem nächsten Versuch
}
error = ERROR_TIMEOUT;
return;
}
 

/**
  * Positioniert den Lesekopf ueber einen Bestimmten Zylinder.
  *
  * @param cylinder Zylindernummer
  * @return true wenn das Positionieren gelungen ist, sonst false
  */
int floppy_seek(uint8_t cylinder)
{
DEBUG_MSG("Kopf neu positionieren");
if(fd[fddDevice].cylinder == cylinder)
{
DEBUG_MSG("    Steht bereits richtig");
return true;
}


//floppy_set_motor(true);

//floppy_clr_irqcnt();

send_cmd(CMD_SEEK);
send_cmd(fddDevice);
send_cmd(cylinder);

/*if(floppy_wait_irq(1) == false)
{
return false;
}*/

floppy_int_sense();

sleepTicks(1);

while (inb(MSR) & 0x0F) {
DEBUG_MSG("Laufwerk ist noch beschaeftigt");
sleepTicks(1);
}

if (fd[fddDevice].cylinder != cylinder) {
DEBUG_MSG("Warnung: Floppy steht nach SEEK(%d) auf %d",
cylinder, fd[fddDevice].cylinder);
}

if(fd[fddDevice].status != 0x20)
{   
DEBUG_MSG("    false");
return false;
}
else
{
DEBUG_MSG("    true");
return true;
}
return true;
}



void fdHandler(cpu_state *r)
{
DEBUG_MSG("FDD Int!");
fd[fddDevice].irqRes++;
}

void resetFDD()
{
outb(MCMD, 0);
fddMotor(false);
}

void fddChooseDevice(uint8_t id)
{
fddDevice = id;
uint8_t tmp = inb(MCMD);
outb(MCMD, (tmp & (~0x03)) | fddDevice);
}

void fddMotor(int state)
{
fd[fddDevice].motor = state;
fd[fddDevice].la    = getTime();
uint8_t status = inb(MCMD);
//DEBUG_MSG("FDD: State: %d", status);
if (state==true)
{
outb(MCMD, (status & 0x0F) | (0x10 << fddDevice));
}
else
{
//DEBUG_MSG("FDD: Change state from %d to %d", status, status & ~(0x10 << id));
outb(MCMD, status & ~(0x10 << fddDevice));
}

sleepTicks(5);
//Hier muss eine Sleep funktion rein!!!!
//sleepTicks(10);
}

void fddwaitForIRQ()
{
int i = fd[fddDevice].irqRes;
DEBUG_MSG("Wait for IRQ6: Arrived IRQ: %d", i);
while(1)
{
asm("nop");
if (i == fd[fddDevice].irqRes-1)
{
return;
}
}
}

/**
 * Kalibriert das Laufwerk
 *
 * @return true wenn das Neukalibrieren gelungen ist, sonst false
 */
int FDDrecalibrate(void)
{
    DEBUG_MSG("Kalibriere Laufwerk neu");
fd[fddDevice].cylinder = 255;
fddMotor(true);

int i = 0;
while ((i < 5) && (fd[fddDevice].cylinder != 0))
{
//floppy_clr_irqcnt();
send_cmd(0x07);
send_cmd(fddDevice);
//floppy_wait_irq(1);
//fddwaitForIRQ();
//FIXME Wait for IRQ Here!!!!
//loppy_int_sense();
++i;
}
return (i < 5);
}




/**
 * Mir ist nicht bekannt, was diese Funktion genau macht. Sie schein aber
 * notwendig zu sein.
 */
void floppy_int_sense()
{
send_cmd(FLOPPY_CMD_INT_SENSE);
fd[fddDevice].status = read_data();
fd[fddDevice].cylinder = read_data();
}

void initFDD()
{
// asm("sti");
//int i;

fddChooseDevice(0);
uint8_t fdd = cmos_read(0x10);


uint8_t fd1 = fdd & 0xF;
uint8_t fd0 = (fdd & 0xF0) >> 4;

DEBUG_MSG("CMOS Floppy == %d\nfd0 == %d, fd1 == %d", fdd, fd0, fd1);

if (!(fd0 | fd1))
{ return; }

if(fd0==0)
{
DEBUG_MSG("No floppy 0!");
//return;
}
else
{
fddChooseDevice(0);
if(fd0==1)
{
DEBUG_MSG("Floppy 0 found... Size = 360 kB");
}
else if(fd0==2)
{
DEBUG_MSG("Floppy 0 found... Size = 1.2 MB");
}
else if(fd0==3)
{
DEBUG_MSG("Floppy 0 found... Size = 720 kB");
}
else if(fd0==4)
{
DEBUG_MSG("Floppy 0 found... Size = 1.44 MB");
}
}

if(fd1==0)
{
DEBUG_MSG("No floppy 1!");
//return;
}
else if(fd1==1)
{
DEBUG_MSG("Floppy 1 found... Size = 360 kB");
}
else if(fd1==2)
{
DEBUG_MSG("Floppy 1 found... Size = 1.2 MB");
}
else if(fd1==3)
{
DEBUG_MSG("Floppy 1 found... Size = 720 kB");
}
else if(fd1==4)
{
DEBUG_MSG("Floppy 1 found... Size = 1.44 MB");
}
/*
0000b = Laufwerk nicht vorhanden
0001b = 5 1/4 - 360 kB
0010b = 5 1/4 - 1.2 MB
0011b = 3 1/2 - 720 kB
0100b = 3 1/2 - 1.44 MB (sollte eigentlich heutzutage der Standard sein)
0101b - 1111b sind unbenutzt

*/

irq_install_handler(6, fdHandler);

resetFDD();
fd[fddDevice].irqRes = 0;

outb(RDSR, DSR_SPEED_500KBPS);
outb(RDOR, 0x0C);
//fddwaitForIRQ();
//FIXME Wait for IRQ here!!!
FDDrecalibrate();

DEBUG_MSG("Test");
//TEST
//int x;

//uint32_t lba = 109;

//int transfer_sector(uint8_t cylinder, uint8_t head, uint8_t sector, int write, void* buffer)
//if ( transfer_sector(lba, 0, (void *) &x) )
//{
// DEBUG_MSG("%d",x);
//}
//sleepTicks(20);
//resetFDD();
//char c = 'A';
//transfer_sector(109, 1, (void *) &c);

unsigned char c = 'A';
unsigned char *test = &c;
fdc_read(test, 0,0,1);
DEBUG_MSG("Readed: >%c<", *test);
}







int fdc_read(unsigned char *data, unsigned int sector, unsigned int offset, unsigned int length)
{
unsigned char st0, st1, st2, rcy, rhe, rse, bps;//, cyl;

fddMotor(true);


if(!floppy_seek(sector))
{
DEBUG_MSG(" failed seek! ");
return 0;
}

//send the read command
send_cmd(CMD_READ_SECTOR );
send_data( fddDevice | (fd->head << 2));   //head and drive
send_data( fd->cylinder);
send_data( fd->head);
send_data( fd->sector);
send_data( 2);                  // bytes per sector (2 = 512)
send_data( 1);   // "end of track" the final sector of this track (I have no idea what it does)
send_data( 0x1B);               //GAP3 length
send_data( 0xFF);               //data length (0xFF because bytes per sector != 0)

//get the data
//fddwaitForIRQ();//wait for it...
//GO!
int i = 0; unsigned char *tmp = data;
for(i = 0; i < 512; i++)
{   
*tmp = (unsigned char) read_data();
//write_hex(*tmp);

tmp++;
}

// read status information
st0 = read_data();
//write_hex(st0);
st1 = read_data();
st2 = read_data();
/*
* These are cylinder/head/sector values, updated with some
* rather bizarre logic, that I would like to understand.
*/
rcy = read_data();
rhe = read_data();
rse = read_data();
// bytes per sector, should be what we programmed in
bps = read_data();

fddMotor(false);

return 1;
}
Hat jemand eine Idee?
4
Lowlevel-Coding / Probleme mit Teil 8 des Tutorials
« am: 07. November 2010, 13:58 »
Hallo zusammen,
ich habe mal wieder ein Problem Im Teil 8 des Tutorials werden Programme geschrieben. Das klappte auch alles super - bis ich eine ganz einfache Funktion schreiben wollte, wie zum Beispiel
void a() {}Die Funktion macht zwar nichts, wird auch nicht aufgerufen, aber trotzdem stürzt QEMU mit folgender Meldung ab.
qemu: fatal: Trying to execute code outside RAM or ROM at 0x53f000ff

EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00001020
EIP=53f000ff EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 00000000 00000000
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0000 00000000 00000000 00000000
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00100042 00000017
IDT=     00126360 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=f000ff69 CCO=INCL   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Den kompletten Code gibt es hier: sesdll1.se.funpic.de/lowlevel/User_Space/. Ich wette, dass das ein ganz doofer Fehler ist, aber ich finde ihn trozdem nicht.

SpaceEmotion

PS: Der Ordner "core" heißt ".core" und "include" ".include".
5
Lowlevel-Coding / Probleme mit der ISR
« am: 24. October 2010, 12:35 »
Hallo,
ich habe ein Probelm bei der ISR. Erstmal wollte ich eine einfache Implementierung und habe mich an http://www.lowlevel.eu/wiki/ISR#Einfache_Implementierung gehalten. Sobald ich den Interrupt 0 mit
asm volatile("int $0x0");
aufrufe. Geht die mit QEMU visualisierte Maschine aus. Sämtliche Dateien finden sich hier:
sesdll1.se.funpic.de/lowlevel/

Vielen Dank
6
Lowlevel-Coding / Tastaturtreiber gesucht
« am: 15. April 2010, 12:09 »
Hallo alle zusammen,

wir wuerden gerne ein kurzes Beispiel fuer einen Tastaturtreiber zu sehen bekommen, um uns davon inspirieren zu lassen.  :wink:

Vielen Dank


SpaceEmotion

(PS. Wir haben das Problem mit der print-Funktion schon geloest)
7
Im Thread steht zwar, dass das Thema bereits gelöst ist, jedoch habe ich eine kleine Frage dazu, da ich im Moment an der gleichen Stelle festsitze.

Es geht um die erste Antwort:
Zitat
Also bei mir hat ein Deskriptor 8 Bytes, bei dir scheinen es eher 16 zu sein.

Ich verstehe nicht, woran man erkennt, wann er Diskriptor 8 Bytes oder 16 hat.

Wäre es möglich, dass wir den ganzen Code zusehen bekommen?

Danke schon einmal im vorraus


SpaceEmotion
8
Ich habe auch eine Frage zu dem Tutorial: http://lowlevel.brainsware.org/wiki/index.php/Teil_4_-_Hello_World#printf. In diesem Teil wird von einer console.h gesprochen.
Der Code darüber
typedef __builtin_va_list       va_list;
#define va_start(ap, X)         __builtin_va_start(ap, X)
#define va_arg(ap, type)        __builtin_va_arg(ap, type)
#define va_end(ap)              __builtin_va_end(ap)
funktioniert als console.h bei mir nicht.
Da habe Ich mir gedacht, dass der GCC Compiler die Datei aus dem System nimmt. Also habe ich auf meinem Linux System danach gesucht, aber mehr als eine console.h gefunden und alle durchprobiert. In einigen ist ein direkter Fehler in der .h-Datei und passiert der Fehler bei kprintf("Hello World!\n");
GCC gibt mir als Fehler: init.c:5: error: implicit declaration of function ‘kprintf’ Kann mit jemand helfen, warum bei mir die console.h nicht funktioniert?
Seiten: [1]

Einloggen