Kernel wird nicht geladen


  • Mod

    nur die main() reinschreiben

    Ja, ich würde von etwas Funktionierendem ausgehen, und dann weitere Versuche machen. Fehlermöglichkeiten gibt es zuhauf, das führt zu nichts außer dem üblichen Abbruch der eigenen Versuche. Daher habe ich im Tutorial die Vorgehensweise so beschrieben, dass man sie praktisch exakt nachstellen kann. Da gehören auch die Tools dazu.


  • Mod

    Falls dir meine Vorgehensweise nicht gefällt, hier gibt es weitere praktische Anleitungen:

    http://www.lowlevel.eu/wiki/Teil_1_-_Entwicklungsumgebung (9 Teile; eher Linux-Fans)
    http://www.brokenthorn.com/Resources/OSDev1.html (über 20 Kapitel; MSVC++)



  • mein Problem ist auch irgendwie dass ich schon haufenweise Tutorials ausprobiert habe und es eigentlich fast immer zu dauerneustarts und fehlermeldungen in bochs gekommen ist.

    irgendwie scheint es am ckernel zu liegen.
    wenn ich schreibe:

    void _main()
    {
    asm("hlt");
    }
    

    dann schreibt BOCHS in die konsole:
    WARNING: HLT instruction with IF=0!

    aber er schreibt den Text nicht wenn ich das schreibe:

    void _main()
    {
    	char *Text = "Welcome to Protected Mode";  
    	char *VideoMem = (char*)0xA8000;  
    
    	while(*Text)  
    	{  
    		*VideoMem = *Text;  
    		*VideoMem++;  
    		*VideoMem = 7;  
    		*VideoMem++;  
    		*Text++;  
    	}
    for(;;){};
    }
    

    😕


  • Mod

    Probiere mal 0xB8000 anstelle 0xA8000, VideoMem++ anstelle *VideoMem++ und zum Schluss nur Text++ anstelle *Text++.
    Siehe: http://www.henkessoft.de/OS_Dev/OS_Dev1.htm#mozTocId483279 und http://www.henkessoft.de/OS_Dev/Bilder/Speicherbelegung.JPG



  • 🙂 danke funktioniert jetzt.

    //kann ich es eigtenltich erstmal vernachlässigen dass Qemu immernoch immer neustartet?



  • ok, wieder nen neues problem.
    wenn ich jetzt den video.c code vom PrettyOS-Tutorial in ckernel.c schreibe funktioniert dieser auch, aber wenn ich das wie im Tut. getrennt in die video.c schreibe und in der ckernel.c das mit

    extern...
    

    mache bleibt er wieder bei "now switching to protected mode(pm)..." stehen.

    void k_clear_screen()
    {
        unsigned long* vidmem = (unsigned long*) 0xb8000;
        unsigned long i=0;
        while(i<(40*25))
        {
            vidmem[i] = 0x0A200A20; // intensive green on black, Space (0x20)
            ++i;
        };
    };
    
    unsigned int k_printf(char* message, unsigned int line, char attribute)
    {
        char* vidmem = (char*) 0xb8000;
        unsigned int i = line*80*2;
    
        while(*message!=0)
        {
            if(*message=='\n') // check for a new line
            {
              line++;
              i=(line*80*2);
              *message++;
            }
            else
            {
              vidmem[i]=*message;
              *message++;
              ++i;
              vidmem[i]=attribute;
              ++i;
            }
        };
        return 1;
    };
    
    inline void outportb(unsigned int port,unsigned char value)
    {
        asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
    };
    
    void update_cursor(int row, int col)
    {
        unsigned short position=(row*80) + col;
    
        // cursor HIGH port to vga INDEX register
        outportb(0x3D4, 0x0E);
        outportb(0x3D5, (unsigned char)((position>>8)&0xFF));
        // cursor LOW port to vga INDEX register
        outportb(0x3D4, 0x0F);
        outportb(0x3D5, (unsigned char)(position&0xFF));
    };
    

  • Mod

    Ist doch schön, dass es nun bei dir klappt. Du solltest in kleinen Schritten experimentieren, damit Du die Fehlerursache selbst erkennen und beheben kannst.
    Coden und anschließend um Hilfe rufen ist bei OSDev nicht ernsthaft durchführbar. ;):D



  • wenn man das problem irgendwo erkennen könnte.. 😞
    egal ich probier mal weiter...



  • ruf ich clear_screen auf aus video.c wird der bildschirm geleert, aber wenn ich danach andere Methoden aufrufe passiert das nicht.
    In der Bochs-Konsole steht dann

    WARNING: HLT instruction with IF=0!

    aber es steht ja nirgendswo HLT bzw. asm("hlt"); in video.c
    das kommt halt auch wenn ich ne andere Methode aus video.c an den Anfang schreibe (nachdem diese ausgeführt wurde). 😕 ^^



  • *message++; <-- Bei sowas ist das * überflüssig (wie ehenkes sagte). Du willst den Pointer ja nur verschieben, nicht dereferenzieren.

    Ansonsten fehlts mir irgendwie an code... Ich hab nicht ganz den Überblick, wie dein OS jetzt aussieht. Wo steht jetzt ein hlt? Wie werden jetzt welche Funktionen aufgerufen und deklariert? Wann passiert jetzt was?

    wenn ich jetzt den video.c code vom PrettyOS-Tutorial in ckernel.c schreibe funktioniert dieser auch, aber wenn ich das wie im Tut. getrennt in die video.c schreibe und in der ckernel.c das mit
    extern...
    mache bleibt er wieder bei "now switching to protected mode(pm)..." stehen.

    Dann machst Du sicherlich was falsch. Aber wenn wir keinen Code zu sehen kriegen (der die entsprechenden Stellen zeigt), können wir dir nicht helfen 🙂



  • ckernel.c:

    extern void clear_screen();
    extern void update_cursor(int row, int col);
    extern void print(char* Text, char attribute);
    
    int _main()
    {
        clear_screen();
        print("Hallo", 0x07);
    
        for(;;);
        return 0;
    }
    

    video.c:

    #include "video.h"
    
    inline void outportb(unsigned int port,unsigned char value)
    {
        asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
    }
    
    void update_cursor(int row, int col)
    {
        position=(row*80) + col;
    
        // cursor HIGH port to vga INDEX register
        outportb(0x3D4, 0x0E);
        outportb(0x3D5, (unsigned char)((position>>8)&0xFF));
        // cursor LOW port to vga INDEX register
        outportb(0x3D4, 0x0F);
        outportb(0x3D5, (unsigned char)(position&0xFF));
    }
    
    void print(char* Text, char attribute)
    {
        while(*Text)
        {
            *vidmem = *Text;
            vidmem++;
            *vidmem = attribute;
            vidmem++;
            Text++;
        }
    }
    
    void clear_screen()
    {
        i = 0;
        while(i < 4000)
        {
            vidmem[i] = ' ';
            ++i;
            vidmem[i] = 0x07;
            ++i;
        }
    }
    

    video.h

    #ifndef VIDEO_H
    #define VIDEO_H
    
    char* vidmem = (char*) 0xB8000;
    unsigned int i;
    unsigned short position;
    
    inline void outportb(unsigned int port,unsigned char value);
    void update_cursor(int row, int col);
    void print(char* Text, char attribute);
    void clear_screen();
    
    #endif
    

    clear_screen(); macht er und dann steht da "warning: HLT..."
    und print("Hallo", 0x07); macht er nicht mehr.



  • Sooo... Jetzt weiß ich auch, worum es geht. (Auch wenn ich nicht genau weiß, warum dein Code nicht tut, was er soll.) 🙂

    Das Schlüsselwort "extern" ist übrigens in dem Zusammenhang. in dem Du es nutzt, nicht nötig, wenn auch nicht schädlich. Es ist nur bei Variablendeklarationen nötig, weil diese Variablen andernfalls bereits definiert sind und damit angelegt werden.
    Zudem solltest Du den Header video.h includieren, statt in main.c die Funktionen zu deklarieren 😉

    Allerdings hast Du an entscheidenden Stellen das Schlüsselwort "extern" vergessen, auch wenn das vermutlich bei deinem Code (noch) kein spürbares Problem darstellt. Du darfst _niemals_ in einem Header Variablen definieren (sondern nur mit extern deklarieren), weil dann in jeder Datei, die den Header includiert, eine eigene Variable angelegt wird. Das sollte dann zu Linkerfehlern führen. (GCC benimmt sich da eigenartig, ich empfehle, Code mit dem Flag -fno-common zu übersetzen, damit solche Fehler angezeigt werden)
    Von den Variablen, die derzeit global sind, solltest Du i aber zu einer lokalen Variable von clear_screen machen.

    Ansonsten fallen mir in deinem Code keine Fehler auf.


  • Mod

    Ich sehe auf die Schnelle auch keinen Grund, warum das stoppt. Hast du diese print-Funktion nicht schon erfolgreich verwendet? Wo genau steigt der Code aus?
    Teste mit bochs debugger.

    http://www.henkessoft.de/OS_Dev/OS_Dev2.htm#mozTocId939575



  • http://www8.pic-upload.de/26.02.11/oblbzbmdads.jpg

    der springt wohl nach clear_screen direkt ans/hinters ende vom ckernel, im asm-kernel der den ckernel läd steht nach dem call auch cli und hlt.

    wenn ich

    clear_screen();
    asm("hlt");
    print("Hallo", 0x07);
    

    schreibe, schreibt der Debugger das Gleiche (hält nicht bei asm("hlt"); ) und wenn ich das
    asm("hlt");
    ans Ende von void clear_screen() (nach der while-schleife) schreibe bleibt er da stehen. also hört er irgendwie nach clear_screen mit dem ckernel auf.

    //wenn ich das print("Hallo", 0x07); vor clear_screen() aufrufe schreibt er erst garnicht. nur son paar befehle:
    http://www8.pic-upload.de/26.02.11/x8cvyq5l6xw.jpg
    (nach leave kommt wieder cli, hlt)


  • Mod

    Das Problem sollte bei print oder in deinem makefile liegen.
    Verwende mal unsigned char (außer bei Text).
    char ist normalerweise signed char.
    Sollte aber eigentlich nicht der Grund sein.
    Immerhin kannst Du nun mit dem Debugger umgehen.
    Gehe schrittweise durch und analysiere genau.



  • ich hab das jetzt nochmal vereinfacht und nach meinem wissen ne "zeichnung"/screenshot gemacht (find ich wirklich verwirrend):

    http://www8.pic-upload.de/26.02.11/2nyfhxitfkvs.jpg


  • Mod

    http://www.henkessoft.de/C/C-Programming Under The Hood.htm
    Dort findest Du die Abläufe beim Aufruf einer C-Funktion.

    Ansonsten: Analytisch gehst du das Thema nun wirklich gut an. Auf diese Weise wirst Du es schaffen. Immer nur einen Schritt nehmen und alles checken.



  • ich weis aber nicht was der fheler sein sollte wenn ich in print() nichts reinschreibe oder nur return; und im ckernel nur print(); aufrufe und außer
    while(1){} bzw. for( ; ; ); nichts anderes schreibe 😕
    geht auch nicht. im debugger seh ich ja auch nur
    leave, ret, cli, hlt (das leave ist ja noch richtig)


  • Mod

    Ich kann momentan nicht beurteilen, warum die for- bzw. while-Endlosschleife nicht greift. Dazu müsste ich den Gesamtcode incl. makefile und linkerscript sehen.

    Du bist aber nun auf dem richtigen Weg, Fehler selbst zu finden und zu beheben. Starte von einem System, das funktioniert, und unternehme dann nur Einzelschritte, die Du vollständig analysierst und im Fehlerfall selbst beheben kannst. Vorbilder findest Du genügend bei lowlevel, osdev.org, brokenthorn.com oder bei meinen Tutorials.

    Hier hast Du einen Überblick über beachtenswerte Hobby-OS (z.Z. Stand 1.9.2010):
    http://www.c-plusplus.net/forum/273023



  • ich benutz grad kein makefile nur batchdateien. (dasproblem sollte da nicht liegen oder?) und das image mach ich mit sonem Programm (BFI).
    ich hab das ganze einfach mal hochgeladen:
    http://store.markusfrohne.de/files/OsDev.zip

    EDIT:
    mit C++ löst sich das auch nicht. Wenn ich da als Klasse CVideo habe und nur

    int main(){
    CVideo video;
    while(1){}
    return 0;
    }
    

    schreibe, bleibt er bei while zwar stehen aber nicht wenn ich dann noch video.print(); aufrufe


Anmelden zum Antworten