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

Seiten: [1]
1
Lowlevel-Coding / RPC geht unter bochs, aber nicht unter qemu
« am: 30. September 2009, 19:38 »
Also ich hab ein Problem(mal wieder).....

Wenn ein Task einen RPC zum Kernel ausführt, funktioniert das ganze ohne probleme, wenn ein Task aber einen RPC zu einem anderen Task macht bekomm ich eine GPF in Qemu und auf einem echten PC, debuggen kann ich das leider schlecht da es unter bochs ohne probleme funktioniert.
Komischerweise tritt dieses Problem nur dann auf wenn die Stackaddresse des callee(so heißt doch der aufgerufene RPC Handler dann, oder?) != 0xF0000000 ist oder BASE_STACK SIZE >= 0x4000, ansonsten funktioniert es ganz normal(jedenfalls im Emulator auf einem echtem Computer bekomm ich auch ne GPF).

Hier mal meine make_rpc Funktion:

// führt einen rpc-aus(zu einem RING0-Task)
void make_rpc(UINT32 callee_pid, rpc_data *data)
{
    //den task suchen, dessen rpc-handler afgerufen werden soll
    Task *callee = get_task_from_pid(callee_pid);
    if(callee == 0)
    {
        Console_putf("make_rpc: callee %i existiert nicht.\n");
        return;
    }
    // wenn kein rpc-handler vorhanden ---> ende
    if(callee->rpc_handler == 0)
    {
        Console_putf("make_rpc: callee %i hat keinen rpc-handler.\n");
        return;
    }
    UINT32 callee_stack;
    if(callee->pid != 0)
    {
        int i;
        for (i = 0; i <= BASE_STACK_SIZE; i+=0x1000)
        {
            UINT32 va = (VIRT_STACK_ADDR + i);
            UINT32 pa = mem_get_phys_addr(VIRT_STACK_ADDR + i, (page*)callee->page_dir);
            mem_map(kernel_pd, va, pa);
            if (mem_get_phys_addr(va, kernel_pd) != pa)
            {
                Console_putf("Fehler beim mappen des callee_stacks(i = %x)", i);
            }
        }
        callee_stack = callee->stack;
    }
    else
    {
        // ok, den kernel stack brauchen wir icht mappen, da das kernel_pd schon geladen ist
        callee_stack = callee->stack;
    }
    // jetzt dort einen weiteren irq-stack hinzufügen
    UINT32 *stack = (UINT32 *) callee_stack;
    data->caller_pid = current_task->pid;
    // vor den daten wird noch der alte stackpointer gespeichert
    data->callee_old_esp = (UINT32) callee_stack;
    // jetzt die daten auf den stack
    *(--stack) = (UINT32)data;
    // die rücksprungaddresse des rpc-hadnler, welche diesen beendet
    *(--stack) = (UINT32)rpc_end_stub;
    *(--stack) = 0x0202;
// das codesegment(kernel-task = 0x08)
*(--stack) = 0x08;
// der einstiegspunkt(eip)
*(--stack) = callee->rpc_handler;
// WICHTIG: die IRQ-nummer und error-code(weil der timer-interrupt zuständig ist für multitasking)
*(--stack) = 0x00;
*(--stack) = 0x00;
// Allzweckregister
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
*(--stack) = 0x00;
// jetzt die datensegment(kernel-task = 0x10)
*(--stack) = 0x10;
*(--stack) = 0x10;
*(--stack) = 0x10;
*(--stack) = 0x10;


    // jetzt den stack verschieben
    callee->stack = (UINT32)stack;
    callee->makes_rpc = 1;
    // ok jetzt den caller blocken und zum callee wechseln
    current_task->blocked = 1;
    callee->last_rpc_data = data;
    // ok wenn der callee, schläft, ihn jetzt aufwecken
    callee->sleeping = 0;
    //while(current_task != callee)
    while(current_task->blocked == 1)
    {
     multitasking_taskswitch();
    }
}

Hier die verwendeten Konstanten:

#define BASE_STACK_SIZE     0x2000
#define VIRT_STACK_ADDR     0xF0000000

Hoffe ihr könnt mir helfen...
2
Lowlevel-Coding / Compiler entfernt linefeeds
« am: 05. August 2009, 15:34 »
Wenn ich in meinem Code meine printf Funktion aufrufe entfernt gcc bei mir alle '\n' am Ende eines Strings.
Wenn ich statt printf meine puts Funktion aufrufe, oder das '\n' mitten inner halb eines Wortes schreibe(zum Beispiel: printf("Erf\nolgreich(Code %x)",0);) funktioniert alles problemlos.
Das Problem habe ich sowohl unter Windows als auch unter Linux.

Hier mal ein bisschen Code als Beispiel(Auszug aus meinem Tastaturtreiber, in dem das Problem auftritt):

void TestController()
{
printf("Teste Tastatur-Anschluss...");
// den befehl zum testen senden
writeCmd(0xAB);
// den rückgabewert holen
UINT8 err_code = readData();
// rückgabe überprüfen
switch(err_code)
{
case 0x00:
printf("Erfolgreich.\n");
break;
case 0x01:
printf("Fehler(Clock low).\n");
break;
case 0x02:
printf("Fehler(Clock high).\n");
break;
case 0x03:
printf("Fehler(Data low).\n");
break;
case 0x04:
printf("Fehler(Data high).\n");
break;
case 0xFF:
printf("Fehler(Komplettausfall).\n");
break;
default:
printf("Unbekannter Status(%x).\n", err_code);
break;
}
}

Wenn ich mir jetzt mit objdump oder einem Hexeditor das objectfile anschaue, kommt das Folgende:

Contents of section .rodata:
 0000 54657374 65205461 73746174 75722d41  Teste Tastatur-A
 0010 6e736368 6c757373 2e002e20 00457266  nschluss... .Erf
 0020 6f6c6772 65696368 2e004665 686c6572  olgreich..Fehler
 0030 28436c6f 636b206c 6f77292e 00466568  (Clock low)..Feh
 0040 6c657228 436c6f63 6b206869 6768292e  ler(Clock high).
 0050 00466568 6c657228 44617461 206c6f77  .Fehler(Data low
 0060 292e0046 65686c65 72284461 74612068  )..Fehler(Data h
 0070 69676829 2e004665 686c6572 284b6f6d  igh)..Fehler(Kom
 0080 706c6574 74617573 66616c6c 292e0055  plettausfall)..U
 0090 6e62656b 616e6e74 65722053 74617475  nbekannter Statu
 00a0 73282578 292e0a00 54657374 65205461  s(%x)...Teste Ta
 00b0 73746174 75722e2e 2e20004f 4b2e0046  statur... .OK..F
 00c0 65686c65 72282578 292e0a00 4b6f6e66  ehler(%x)...Konf
 00d0 69677572 69657265 20546173 74617475  iguriere Tastatu
 00e0 722e2e2e 2000

Ich habe auch schon alle moglichen Compileroptionen durchprobiert, die damit was zu tun haben könnten(Optimierungen, etc..) doch das hat auch nichts gebracht.

Vlt. weiß ja einer von euch woran das liegen könnte...
3
Lowlevel-Coding / problem mit globaler variable
« 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.
Seiten: [1]

Einloggen