Autor Thema: problem mit globaler variable  (Gelesen 2760 mal)

AcidIO

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« am: 14. April 2009, 00:18 »
Hey Leute, erstmal möchte ich euch sagen das das hier ein sehr gutes forum ist.

So jetzt aber zu meinem problem:

in meinem datesystemtreiber habe ich die folgende stuktur:

struct Drive
{
char *name; // der name(z.b fd0 für erste floppy oder hd0 für erste festplatte
long start_sec; // der sektor an dem die Partition beginnt
char fstype; // der FS-Type 0 = FAT12; 1 = FAT16; 2 = FAT32
struct BiosParameterBlock *bpb; // der Bios-Parameter-Block
int fat_cnt;    // anzahl der FAT's
void *fats; // der zeiger zur fat(zeiger weil noch unbaekant ist waqs für ein dateisystemtyp das ist)
int root_entrys_cnt; // anzahl der einträge im root directory
void *root_entrys; // zeiger auf root dir
unsigned int data_sec; // erster datensektor
};

diese möchte ich als globale variable definieren, da viele funktionen diese daten benötigen.
allerdings habe ich dabei das problem das sich nach einigen funktionen die addressen ändern.

wenn ich die variable so

struct Drive drives[5];
oder so

struct Drive *drives;
definiere ändert bleibt die adresse beim initialisieren des treiber, und beim einlesen der laufwerksinfo's und fat's glecih(z.b 0x0074B06B).
wenn jetzt allerdings eine andrere methode vom kernel aus aufgerufen wird ist die addresse der varaible auf einmal zu hoch(0x6D64B06B).
wenn ich die variable als static definiere ändert sich die addresse sogar sagor nachdem ich die addresse ausgegeben habe.
Wer nichts wagt kann nichts verlieren...

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 14. April 2009, 18:02 »
allerdings habe ich dabei das problem das sich nach einigen funktionen die addressen ändern.
hm, passiert dazwischen irgendwie ein Taskswitch (bei welchem die Register nicht richtig gespeichert werden) oder wird die Struktur mit den Registern eventuell überschrieben? Werden deine Treiber eventuell falsch geladen (Relocations, etc...)?
Ansonsten fällt mir nicht wirklich was ein und ich denke nicht, dass man mit den spärlichen Informationen den Fehler finden kann. Wahrscheinlich braucht man dazu den ganzen Source...
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

AcidIO

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 14. April 2009, 20:46 »
also ein taskswitch kanns nicht sein da ich "noch" kein multitasking habe, relocatet & geladen werden die treiber auch richtig, da die andren treiber(floppy, hdd, dma, usw.) fehlerfrei funktionieren( und die haben auch fast alle globale variablen).

#include "G:\KOV1\libc\system.h"

#define ATTR_READ_ONLY 0x01
#define ATTR_HIDDEN         0x02
#define ATTR_SYSTEM         0x04
#define ATTR_VOLUME_ID      0x08
#define ATTR_DIRECTORY      0x10
#define ATTR_ARCHIVE        0x20

#define DT_FAT12 1
#define DT_FAT16 2
#define DT_FAT32 3


struct BiosParameterBlock
{
unsigned char jmp[3]; // jmp befehl(für bootloader)
unsigned char name[8]; // Der Name (k.p. wofür)
unsigned short bytes_per_sector; // bytes pro sektor
unsigned char sectors_per_cluster; // sektoren pro cluster(kleinste ansprechbare einheit)
unsigned short sectors_reserved; // reservierte sektoren
unsigned char fat_cnt; // anzahl der fats
unsigned short root_entry_cnt; // anzahl der root entrys
unsigned short sectors_cnt_16; // 16-bit angabe der anzahl an sektoren
unsigned char media_type; // typ des mediums
unsigned short fat_size_16; // 16-bit größe der fat
unsigned short sectors_per_track; // wieviele sektoren auf einem track
unsigned char heads_cnt; // anzahl der köpfe
unsigned long hidden_sectors_cnt; // anzahl der versteckten sektoren
unsigned long sectors_cnt_32; // 32-bit anzahl der sektoren
unsigned char drvnum; // welches laufwerk(diskette == 0) is aber eig. egal
unsigned char reserved_for_nt; // für windows nt reserviert
unsigned char boot_signature; // gibt an ob die nächsten 3 felder vorhanden sind(sollte 0x29 sein);
unsigned long volume_id; // identifizierungsnummer meist eine zusammenfassung aus datum und zeit
//unsigned char reserved; // reserviert für kp was
unsigned char volume_label[11]; // die bezeichnung des mediums( der name der unter windoof annezeigt wird)
unsigned char file_sys_name; // name des Dateisystems !! ACHTUNG !! ----> SAGT NICHT WELCHES DATEISYSTEM DA IST!!!
} __attribute__((packed));

struct Fat12_struct
{
char drive_num; // was für ein laufwerk
char reserved1; // reserviert
long  volume_id; // identifizierungsnummer des laufwerks
char  fs_type[8]; // name des Dateisystems(sollte immer "FAT12   " sein, muss aber nicht)
}__attribute__((packed));

struct Fat12_Entry
{
unsigned char name[11];   // der datei name  8 zeichen name + 3 zeichen endung !!!Punkt ist nicht dabei!!!
unsigned char attr;                     // das attribute (siehe oben (#define ATTR_*))
unsigned char reserved;                 // unwichittig
unsigned char crt_time_ms;              // erstellungszeit millisekunden, muss noch * 10 gerechnet werden
unsigned short foo;   // unwichtig
unsigned short    crt_time;                 // erstellungszeit
unsigned short foo2;                     // unwichtig
unsigned short wrt_time;                 // änderungszeit
unsigned short wrt_date;                 // änderungsdatum
unsigned short foo3;                     // unwichtig
unsigned short start_sector;             // nummer des anfangsclusters
unsigned long size;                     // die dateigröße
}__attribute__((packed));

struct Fat12_fat
{
unsigned int size; // die größe der Fat
unsigned char  *entrys; // die addresse
};

struct Fat32_struct
{
long fat_size; // 32-bit angabe der fat-länge
short flags; // flags
short version; // version
long root_cluster; // das erste cluster
short fs_info; // unwichtig glaub ich
short boot_sector; // bootsektor (sollte 6 sein)
char  reserved[12]; // reserviert
char drive_num; // was für ein laufwerk
char reserved1; // reserviert
char  boot_signatur; // bootsignatur
long  volume_id; // identifizierungsnummer des laufwerks
char  volume_label[11]; // name des laufwerks
char  fs_type[8]; // name des Dateisystems(immer "FAT32   ")
} __attribute__((packed));

struct Drive
{
char *name; // der name(z.b fd0 für erste floppy oder hd0 für erste festplatte
long start_sec; // der sektor an dem die Partition beginnt
char fstype; // der FS-Type 0 = FAT12; 1 = FAT16; 2 = FAT32
struct BiosParameterBlock *bpb; // der Bios-Parameter-Block
int fat_cnt;    // anzahl der FAT's
void *fats; // der zeiger zur fat(zeiger weil noch unbaekant ist waqs für ein dateisystemtyp das ist)
int root_entrys_cnt; // anzahl der einträge im root directory
void *root_entrys; // zeiger auf root dir
unsigned int data_sec; // erster datensektor
};

volatile struct Drive drives[5];


struct FileHandle // speicher die momentan geöffneten dateien
{
unsigned int start_cluster; // das anfangscluster
unsigned int cur_cluster; // der cluster der gelesen werden muss
};

struct FileHandle files[100];
int last_file;


struct BiosParameterBlock bpb;

void scan_drive(int id) // liest ein laufwerk ein id = nummer des laufwerks in drives und readfunc = funktion zum lesen
{
// der Buffer für die daten eines sektors
char buf[512];
// Meldung an benutzer
writestringf("Analysiere Laufwerk \"");
writestring(((struct Drive*)drives)[id].name);
writestring("\".\n");
// den ersten sektor einlesen
SendMessage("hdd", CTLCODE_IO_READSEKTOR, 0, ((struct Drive*)drives)[id].start_sec, buf);
// speicher für biosparamterblockanlegen
((struct Drive*)drives)[id].bpb = mem_alloc((int)sizeof(struct BiosParameterBlock));
// den biosparameterblock nach struct drive kopieren
mem_copy(((struct Drive*)drives)[id].bpb, buf, (int)sizeof(struct BiosParameterBlock)); //readBPB(((struct Drive*)drives)[id].bpb, buf);
// testen ob bpb in ordung ist
/*if(((struct Drive*)drives)[id].bpb->jmp[0] != 0xEB)
{
writestringf("Fehler im Bootsektor!\nDas Laufwerk ist entweder defekt oder unformatiert! %x %x %x %x\n", ((struct Drive*)drives)[id].bpb->jmp[0], ((struct Drive*)drives)[id].bpb->jmp[1], ((struct Drive*)drives)[id].bpb->jmp[2], ((struct Drive*)drives)[id].bpb->jmp[3]);
int t;
char *b = (char *)((struct Drive*)drives)[id].bpb;
for(t = 0; t < 512; t++)
{
writestringf("%x", b[t]);
}
b = buf;
for(t = 0; t < 512; t++)
{
writestringf("%x", b[t]);
}

return;
}*/
// ausgeben des datenträgernamens
writestring("Datenträgerbezeichnung ist ");
int dni;
for(dni = 0; dni < 11; dni++)
{
writechar(((struct Drive*)drives)[id].bpb->volume_label[dni]);
}
writestring("\n");
// die anzahl der cluster( zur bestimmung welches dateisystem)
long clus_cnt;
// üerprüfen ob 32 oder 16 bit wert genommen werden muss
if(((struct Drive*)drives)[id].bpb->sectors_cnt_32 == 0)
{
clus_cnt = ((struct Drive*)drives)[id].bpb->sectors_cnt_16;
}
else
{
clus_cnt = ((struct Drive*)drives)[id].bpb->sectors_cnt_32;
}
// die reservierten sektoren abziehen
clus_cnt -= ((struct Drive*)drives)[id].bpb->sectors_reserved;
// die größe der fat abziehen
clus_cnt -= (((struct Drive*)drives)[id].bpb->fat_cnt * ((struct Drive*)drives)[id].bpb->fat_size_16);
// die größe vom root-dir abziehen
clus_cnt -= (((struct Drive*)drives)[id].bpb->root_entry_cnt * 32) / 512;
// meldung das teil eins fertig ist
writestring("Dateisystem ist ");
// anhand von anzahl der cluster den dateisystemtyp bestimmen
if(clus_cnt > 65525)
{
// FAT32
((struct Drive*)drives)[id].fstype = DT_FAT32;
// meldung
writestring("Fat32\n");
}
else if((clus_cnt < 65525) && (clus_cnt > 4085))
{
// FAT 16
((struct Drive*)drives)[id].fstype = DT_FAT16;
// meldung
writestring("Fat16\n");
// zur fat 12 auslesung gehn

}
else if(clus_cnt < 4085)
{
// FAT 12
((struct Drive*)drives)[id].fstype = DT_FAT12;
// meldung
writestring("Fat12\n");
}
if((((struct Drive*)drives)[id].fstype == DT_FAT12) || (((struct Drive*)drives)[id].fstype == DT_FAT16))
{
// anzahl der fats eintragen
((struct Drive*)drives)[id].fat_cnt = ((struct Drive*)drives)[id].bpb->fat_cnt;
// temporärer verweis auf die fat( weil in drive struktur ein void pointer is und ich zu faul bin jedesmal ((struct Fat12_fat *)((struct Drive*)drives)[id].fat) zu schreiben)
struct Fat12_fat *fat_tmp;
// speicher für FAT's reservieren
fat_tmp = mem_alloc(sizeof(struct Fat12_fat) * ((struct Drive*)drives)[id].fat_cnt);
// begin der ersten fat suchen
int fat_begin = ((struct Drive*)drives)[id].bpb->sectors_reserved;
// index zum durchgehen der fats
int i = 0;
// meldung                                    
writestringf("Lese FAT");
// fats durchgehen und laden
for(i = 0; i < ((struct Drive*)drives)[id].fat_cnt; i++)
{
// die größe festlegen (in 512 byte blöcken)
fat_tmp[i].size = ((struct Drive*)drives)[id].bpb->fat_size_16;
// speicher für die einträge reservieren
fat_tmp[i].entrys = mem_alloc((fat_tmp[i].size * 512));
// einträge nullen
mem_set(fat_tmp[i].entrys, 0, (fat_tmp[i].size * 512) );
// der buffer für das einlesen der fat
unsigned char *fatbuf = mem_alloc((fat_tmp[i].size * 512));
// den buffer leeren
mem_set(fatbuf, 0, (fat_tmp[i].size * 512));
                                                 


// der index des aktuellen sektors
int j;
// die schleife zum einlesen
for(j = 0; j < (fat_tmp[i].size); j++)
{
// einlesen in den buffer
SendMessage("hdd", CTLCODE_IO_READSEKTOR, 0, ((struct Drive*)drives)[id].start_sec + fat_begin + j + (fat_tmp[i].size * i)  , fatbuf+(j*512));
writestring(".");
}

if(fatbuf[0] != 0xF0)
{
writestring("Ungültige fat\n");
return;
}

if(fatbuf[1] != 0xFF)
{
writestring("Ungültige fat\n");
return;
}

if(fatbuf[2] != 0xFF)
{
writestring("Ungültige fat\n");
return;
}
mem_copy(fat_tmp[i].entrys, fatbuf, (fat_tmp[i].size+1) * 512);
   
           /*
// momentaner fat eintrag
int pos = 0;
// index initialisieren
j = 0;
// temporärer wert
unsigned short tmp;
// die 12 bit werte in 16 bit werte konvertieren
for(j = 0, pos = 0; j < (fat_tmp[i].size * 512); j++, pos++)
{
tmp = *((unsigned short *) &fatbuf[j]);
  // *((unsigned short *) ((fatbuf + j)));
    if((j & 0x0001))
{
tmp = tmp >> 4; // bei ungeraden wert
}
else
{
tmp = (tmp & 0x0FFF); // bei geraden wert
}
//writestringf(" %i", tmp);
fat_tmp[i].entrys[pos] = tmp;
    //writestringf(" = %i", fat_tmp[i].entrys[pos]);

/*fat_tmp[i].entrys[pos++] = (((int)fatbuf[j]) << 4) | ((int)((fatbuf[j+1]) & 0xF0));
j++;
fat_tmp[i].entrys[pos++] = (((int)((fatbuf[j]) & 0x0F)) << 8) | ((int)((fatbuf[ + 1])));
j++;
*/
//fat_tmp[i].entrys[pos++] = (*ft) & 0xFFF0;
/*
fat_tmp[i].entrys[pos++] = ((((unsigned short)fatbuf[j+0])) << 4) + (fatbuf[j+1] & 0xF0);
fat_tmp[i].entrys[pos++] = (((((unsigned short)fatbuf[j+1]) & 0x0F)) << 8) + (fatbuf[j+2]);
*/
//writestringf("%i ", (unsigned long)tmp);
// eintragen in fat
//fat_tmp[i].entrys[pos++] = c2;

}

/*if(fat_tmp[i].entrys[0] != 0xF0F)
{
writestringf("\nFehlerhafte FAT!!!\nEintrg 0 ist %i", fat_tmp[i].entrys[0]);
}
if(fat_tmp[i].entrys[1] != 0xFFF)
{
writestringf("\nFehlerhafte FAT!!!\nEintrg 1 ist %i", fat_tmp[i].entrys[1]);
}*/
//}
// meldung
writestring("OK.\n");
// in die drive struktur eintragen
((struct Drive*)drives)[id].fats = fat_tmp;
// fat1 mit fat 2 abgleichen um fehler  zu finden
for(i = 0; i < fat_tmp[0].size; i++)
{
if(((struct Fat12_fat*)((struct Drive*)drives)[0].fats)[0].entrys[i] !=  ((struct Fat12_fat*)((struct Drive*)drives)[0].fats)[1].entrys[i])
{
  writestring("Fehler in FAT!( Eintrag ");
  writestringf("%i", i);
  writestring(")\n");
  break;
}
        }
// anzahl der RootDir einträge in die Drive struktur packen
((struct Drive*)drives)[id].root_entrys_cnt = ((struct Drive*)drives)[id].bpb->root_entry_cnt;
// speicher für root-dir anlegen
struct Fat12_entry *rootdirs = mem_alloc(((struct Drive*)drives)[id].root_entrys_cnt * 32);
// anzahl der belegten sektoren
int root_dir_secs = (((struct Drive*)drives)[id].root_entrys_cnt * 32) / 512;
// tempörärer buffer
char *rdbuf = mem_alloc(root_dir_secs * 512);
// startsektor
int rd_begin = ((struct Drive*)drives)[id].bpb->sectors_reserved + ( ((struct Drive*)drives)[id].fat_cnt * ((struct Drive*)drives)[id].bpb->fat_size_16);
// meldung
writestring("Lese RootDir");
// schleife zum einlesen
for(i = 0; i < root_dir_secs; i++)
{
            // meldung
writestring(".");   
// einlesen in den buffer
SendMessage("hdd", CTLCODE_IO_READSEKTOR, 0, ((struct Drive*)drives)[id].start_sec + rd_begin + i, rdbuf+(i*512));
}
// buffer nach rootdirs casten
rootdirs = (struct Fat12_entry*) rdbuf;
// in struct drive übertragen
((struct Drive*)drives)[id].root_entrys = rootdirs;
// beginn des datensektors eintragen
((struct Drive*)drives)[id].data_sec = (((struct Drive*)drives)[id].bpb->fat_cnt * ((struct Drive*)drives)[id].bpb->fat_size_16) + 13;
// meldung
writestring("OK.\n");

}
}

char *name;

char *getName()
{
name = "fs";
return name;
}

int getType()
{
return 1;
}

int getClusterValueFAT12(int id, int cn)
{

  unsigned short cv = 0;
  unsigned char *ba = ((unsigned short*)((struct Fat12_fat*)((struct Drive*)drives)[id].fats)[0].entrys);
  int of = (cn * 3) / 2;
  cv = *((unsigned short *)(ba + of));
  /*writestringf("GCV: %i", cn);
  writestringf(" %i", of);
  */
  if((cn % 2) != 0)
  {
cv = cv >> 4;  
    }
    else
    {
  cv = cv & 0x0FFF;
    }
    return cv;
}

int getClusterValueFAT16(int id, int cn)
{
unsigned short *ba = ((struct Fat12_fat*)((struct Drive*)drives)[id].fats)[0].entrys;
ba += cn;
return *(ba);
}

int fread(int id, char *buf)
{
writestringf("DA: %X", drives);
int did = 0;
if(((struct Drive*)drives)[did].fstype == DT_FAT12)
{
if(files[id].cur_cluster == 0x0FFF)
{
//writestring("OK(Letzter)\n");
return 0;
}
if(files[id].cur_cluster == 0)
{
writestring("Fehler: Datei belegt ein als Frei markiertes Cluster!!!\n");
return -1;
}
if(files[id].cur_cluster == 0x0FF7)
{
writestring("Fehler: Datei belegt ein als Defekt markiertes Cluster!!!\n");
return -1;
}
if(files[id].cur_cluster > 2880)
{
  writestring("Fehler: Datei belegt ein Cluster, welches zu groß ist!!!\n");
  return -1;
    }
}
if(((struct Drive*)drives)[did].fstype == DT_FAT16)
{
if(files[id].cur_cluster == 0xFFFF)
{
writestring("OK(Letzter)\n");
return 0;
}
if(files[id].cur_cluster == 0)
{
writestring("Fehler: Datei belegt ein als Frei markiertes Cluster!!!\n");
return -1;
}
if(files[id].cur_cluster == 0xFFF7)
{
writestring("Fehler: Datei belegt ein als Defekt markiertes Cluster!!!\n");
return -1;
}
if(files[id].cur_cluster > 2880)
{
  writestring("Fehler: Datei belegt ein Cluster, welches zu groß ist!!!\n");
  return -1;
    }
}
if((((struct Drive*)drives)[did].fstype != DT_FAT12) && (((struct Drive*)drives)[did].fstype != DT_FAT16) )
{
writestringf("Ungueltiges Dateisystem(lw: %i fstype: %i)\n", did, ((struct Drive*)drives)[did].fstype);
return -1;
}
//writestringf("Lese Block %i\n", (unsigned int)files[id].cur_cluster);
    SendMessage("hdd", CTLCODE_IO_READSEKTOR, 0, ((struct Drive*)drives)[did].start_sec + ((struct Drive*)drives)[did].data_sec + files[id].cur_cluster, buf);


switch(((struct Drive*)drives)[did].fstype)
{
case DT_FAT12:
writestringf("%i", files[id].cur_cluster);
writestringf("-->%i ", getClusterValueFAT12(0, files[id].cur_cluster));
files[id].cur_cluster = getClusterValueFAT12(0, files[id].cur_cluster);
break;
case DT_FAT16:
writestringf("%i", files[id].cur_cluster);
writestringf("-->%i ", getClusterValueFAT16(0, files[id].cur_cluster));
files[id].cur_cluster = getClusterValueFAT16(0, files[id].cur_cluster);
break;


}
return 1;
}

int fopen(char *path, unsigned long *size)
{
writestringf("DA: %X ", drives);
char *path83 = convert_to83(path);
int did = 0;
((struct Drive*)drives)[did].fstype = DT_FAT16;
if((((struct Drive*)drives)[did].fstype != DT_FAT12) && (((struct Drive*)drives)[did].fstype != DT_FAT16) )
{
writestringf("Konnte Datei \"%s\" nicht finden. Ungueltiges Dateisystem(lw:%i fstype: %i)\n", path, did, ((struct Drive*)drives)[did].fstype);
return -1;
}
//writestring("Suche Datei");
int i;
for(i = 0; i < ((struct Drive*)drives)[did].root_entrys_cnt; i++)
{
 
if(((struct Fat12_Entry*)((struct Drive*)drives)[did].root_entrys)[i].name[0] == 0x0E)
{
continue;
}
if(((struct Fat12_Entry*)((struct Drive*)drives)[did].root_entrys)[i].name[0] == 0xE5)
{
continue;
}
if(cmp_filename(path83, ((struct Fat12_Entry*)((struct Drive*)drives)[did].root_entrys)[i].name) == 0)
{
//writestring("found");
struct Fat12_Entry ent = ((struct Fat12_Entry*)((struct Drive*)drives)[did].root_entrys)[i];
*size = ent.size;
long ss = ent.start_sector; 
last_file = 1;
/* writestringf("Datei beginnt in cluster %i", ss);
writestring("\n");*/
files[last_file].start_cluster = ss;
files[last_file].cur_cluster = ss;
last_file++;
return last_file-1;
}
}
return -1;
}


// finden den anfang einer partition, durch lesen des MBR
long GetPartitionStart(int did, int pid)
{
// buffer für mbr
char *mbrbuf = mem_alloc(512);
// lesen
SendMessage("hdd", CTLCODE_IO_READSEKTOR, 0, 0, mbrbuf);
// anfang berechnen
long s = *((long *)(((mbrbuf + 0x01BE) + ( pid * 16)) + 0x8 ));
return s;
}


int init()
{
//writestring("Dateisystem Treiber 0.1 - geschrieben von Florian Reinhard\n");
name = "fs";
//drives = mem_alloc(sizeof(struct Drive) * 5);
writestringf("DA: %X ", drives);
writestringf("DA: %X ", drives);

((struct Drive*)drives)[0].name = "hd0";
((struct Drive*)drives)[0].start_sec = GetPartitionStart(0, 0);
scan_drive(0);
last_file = 0;
writestringf("DA: %X ", drives);
writestringf("DA: %X ", drives);

//writestring("\nInit fertig!!!\n");
return 0;
}

die funktioien init, getName, GetType, fopen und fread werden vom Kernel aufgerufen. ein paar funktionen hab ich rausgelassen, weil der text snst zu lang geworden wäre, diese haben aber nur dateinamen nach 8.3 konvertiert etc.
Wer nichts wagt kann nichts verlieren...

 

Einloggen