[OSDev]Problem ze zmienną liczbą parametrów w funkcji

0

Witam,

Zmapowałem sobie kernela pod 3GB i zaczęłem pisać obsługę wirtualnych ekranów. Wszystko było OK, ale dodanie funkcji printf wywala całego kernela.

static char buf[1024];
 
extern int vsprintf( char *buf, const char *fmt, va_list args );
 
void printf(const char *fmt, ...)
{
    va_list args;
    int i;
 
    va_start( args, fmt );
    i = vsprintf( buf, fmt, args );
    va_end( args );
 
    for ( i = 0; i < 1024; i++ )
    {
        if ( buf[i] == '\0' ) break;
        putc( buf[i] );
    }
}

Po dodaniu tego kodu, instrukcja skoku po załączeniu stronnicowania powoduje page fault... Kod odwołuje się do adresu 0x00000040, który teoretycznie jest zmapowany fizyczny = wirtualny (pierwsze 4mb odmapowuję później), ale mimo to otrzymuje komunikat że strona nie istnieje. Cały błąd wywołuje dokładnie jedna linijka: i = vsprintf( buf, fmt, args );, a błąd pokazuje w tej funkcji:

GLOBAL enable_paging
enable_paging:
  mov eax, cr0
  or eax, 0x80010000
  mov cr0, eax
  jmp .enabled ; <- tu występuje błąd
  .enabled:
  ret

Link do biblioteki z vsprintf i makrami: http://rapidshare.com/files/48556209/lib.tar.gz.html

Ten sam kod działał w starej wersji kernela, zmapowanej fizyczny = wirtualny.

Czemu błąd powoduje akurat ta linijka, czemu w takim dziwnym miejscu no i jak to naprawić?

0

Sprawdź adres GDT. Musi być podany wirtualny a nie fizyczny w GDTR. Do tego nie jestem pewien czy po włączeniu stronnicowania nie powinno się wykonać skoku dalekiego? (jmp segment:offset). Sprawdź też czy kod mapowania jest poprawny.
PS.: Sorry że tak mętnie pisze, ale jestem nie wyspany ;)

0

Kod mapowania jest jak najbardziej poprawny, a adres GDT jest wirtualny (czyli z 3GB; zaraz po zmapowaniu fizyczny = wirtualny i pod 3GB ładuje do GDTR adres wirtualny tablicy). Daleki skok nic nie zmienił.

0

zaraz po zmapowaniu fizyczny = wirtualny i pod 3GB ładuje do GDTR adres wirtualny tablicy

Ciężko mi to zrozumieć tak więc zadam parę pytań.

Odwołanie do jakiej strony pamięci powoduje wyjątek PF ?
I jaką wartość ma error code (na stosie podawany po wyjątku) ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1