Eigenes OS?



  • Erhard Henkes schrieb:

    Schaltet man sti() vorher ein, so kracht es sofort. Man sieht keine einzige Meldung

    Dann prüf mal wo genau es kracht:

    void paging_install()
    {
     ULONG mem_end_page = PHYSICAL_MEMORY;
     nframes = mem_end_page/PAGESIZE;
     frames  = (ULONG*)kmalloc(INDEX_FROM_BIT(nframes)); // <- hier?
     k_memset(frames, 0, INDEX_FROM_BIT(nframes));       // <- oder hier?
    (...)
    

    Oder bereits vor dem Aufruf von "paging_install ()" (i.S.v. wenn sti() ausgeführt wird)?



  • @+fricky:

    auch "stinknormale" c-anwendungen lassen sich bauen, wenn man die anwendungen ereignisgesteuert macht.
    wie die tastatureingabe beim "keyget" ankommt hat damit überhaupt nichts zu tun.

    in jeder anwendung aber dieses polling zu haben ist, meiner meinung nach, einfach nicht sinnvoll.

    Eine Speicherverwaltung zu bauen ist aus meiner Sicht noch viel zu früh.

    Lieber einen Scheduler und mehrere Anwendungen.

    jenz


  • Mod

    Eine Speicherverwaltung zu bauen ist aus meiner Sicht noch viel zu früh.
    Lieber einen Scheduler und mehrere Anwendungen.

    Noch liegt nichts fest, bin nur am Austesten. Ich habe mich bei der Reihenfolge des Aufbaus von folgender Aussage James Molloy's inspirieren lassen:

    Dynamic memory allocation is one of the few things that it is very difficult to do without. Without it, you would have to specify an absolute maximum number of processes running (static array of pids), you would have to statically give the size of every buffer - Generally making your OS lacklustre and woefully inefficient.

    "glanzlos und beklagenswert ineffizient", das hört sich nicht gerade anziehend an. 😃
    Daher schlage ich mich im Hintergrund mit dem Pagigng/Heap-Mechanismus von James Molley herum. Das muss auch alles noch simplifiziert werden, derart unverständlicher Code kommt mir in kein Tutorial.


  • Mod

    +gjm+ schrieb:

    Erhard Henkes schrieb:

    Schaltet man sti() vorher ein, so kracht es sofort. Man sieht keine einzige Meldung

    Dann prüf mal wo genau es kracht:

    void paging_install()
    {
     ULONG mem_end_page = PHYSICAL_MEMORY;
     nframes = mem_end_page/PAGESIZE;
     frames  = (ULONG*)kmalloc(INDEX_FROM_BIT(nframes)); // <- hier?
     k_memset(frames, 0, INDEX_FROM_BIT(nframes));       // <- oder hier?
    (...)
    

    Oder bereits vor dem Aufruf von "paging_install ()" (i.S.v. wenn sti() ausgeführt wird)?

    Guter Vorschlag.

    TEST:
    ckernel:

    #include "os.h"
    
    int main()
    {
        k_clear_screen();
    
        // GDT, IDT, ISRS, IRQ, timer, keyboard
        gdt_install();
        idt_install();
        isrs_install();
        irq_install();
        timer_install();
        keyboard_install();
        sti();
        paging_install(); //TEST
    //...
    

    ..

    Das ganze ist einfach ein riesiger Wirrwarr, macht so als Tutorial keinen Sinn, weil niemand irgendetwas nachverfolgen und damit experimentieren kann. Ich stehe selbst wie vor einem Berg und weiß noch nicht, wie ich den Tunnel bohren soll.

    Wenn ich so auf kmalloc(...) schaue, frage ich mich gerade, wo eigentlich der heap erzeugt wird, denn vorher ist kheap = 0.

    ..


  • Mod

    TEST1:

    #include "os.h"
    
    int main()
    {
        k_clear_screen();
    
        // GDT, IDT, ISRS, IRQ, timer, keyboard
        gdt_install();
        idt_install();
        isrs_install();
        irq_install();
        timer_install();
        keyboard_install();
        sti();
        k_memset(44880, 0, 512);
        //paging_install(); //TEST
    

    ergibt reset.

    #include "os.h"
    
    int main()
    {
        k_clear_screen();
    
        // GDT, IDT, ISRS, IRQ, timer, keyboard
        gdt_install();
        idt_install();
        isrs_install();
        irq_install();
        timer_install();
        keyboard_install();
        //sti();
        k_memset(44880, 0, 512);
        //paging_install(); //TEST
    
        set_cursor(0,0);
        printformat("   ************************************************\n");
    	printformat("   *          Welcome to PrettyOS 0.06            *\n");
    	printformat("   *          Paging is activated                 *\n");
    	printformat("   ************************************************\n");
    

    läuft durch bis zum Titel-Ausdruck.
    Analyse passt also.
    Jetzt brauchen wir die Diagnose und das Heilmittel.


  • Mod

    Ich habe mal

    sti();
        k_memset(65536, 0, 512);
        //paging_install(); //TEST
    

    probiert, also mal 65536 (10000h) als Ziel. Das geht ohne Reset.
    Also sollte es doch an diesem 44880 (AF50h) liegen. Liege ich da mit meinen Gedanken richtig?
    Versuche gerade nachzuvollziehen, warum bei der Paging-Install-Routine gerade 44880 heraus kommt.

    Diese Bitset-Geschichte (vielleicht kann man das einfacher machen) läuft wie folgt:

    INDEX_FROM_BIT(nframes) 
    
    // Macros used in the bitset algorithms.
    #define INDEX_FROM_BIT(a)   (a/(8*4))
    #define OFFSET_FROM_BIT(a)  (a%(8*4))
    

    Also INDEX_FROM_BIT(16384) ==> (16384/(8*4)) = 512



  • jenz schrieb:

    @+fricky:
    auch "stinknormale" c-anwendungen lassen sich bauen, wenn man die anwendungen ereignisgesteuert macht.
    wie die tastatureingabe beim "keyget" ankommt hat damit überhaupt nichts zu tun.

    also willst du, dass jede anwendung event-handler (für key events) implementieren muss, oder wie meinst du das?

    jenz schrieb:

    in jeder anwendung aber dieses polling zu haben ist, meiner meinung nach, einfach nicht sinnvoll.

    polling in dem sinn, dass die cpu, wegen vieler missglückter abfragen, zyklen verbrät, kann ja schon durch eine blocking 'getchar' umgangen werden (oder durch mein beispiel von weiter oben).
    🙂



  • Erhard Henkes schrieb:

    Wenn ich so auf kmalloc(...) schaue, frage ich mich gerade, wo eigentlich der heap erzeugt wird, denn vorher ist kheap = 0.

    da gibt's doch 'ne funktion 'create_heap'. die musste natürlich vorher aufrufen.
    🙂


  • Mod

    Diese Message Geschichten sind eher typisch für Mini Kernels wie das bedeutungslose (?) aber "elegante" Minix von Tanenbaum. Wie gesagt, ich bin diesbezüglich noch völlig locker.

    Momentan machen mich einfach die C-Basics fertig. Als C++ler bin ich ich echt nicht gewohnt, so "tief unten" zu wühlen, aber ich finde gerade diese herausforderung, alles selbst aufbauen zu müssen, total interessant. Ist alles nur eine Frage der Zeit, bis das klappt.

    Aber ob das noch tutorial-tauglich ist, was ich da treibe, da bin ich nicht mehr sicher. So auf gar keinen Fall. Ein Zwischenverweis auf James Molley's Tutorial (er lädt mit Grubs und verwendet im Programm externe Daten aus dem Linker Skript, igitt) und weiter machen / modifizieren, wo er aufhört, macht IMHO keinen Sinn.



  • "frames" ist seltsamerweise zu klein, was heißt, daß der Aufruf von

    k_memset(frames, 0, INDEX_FROM_BIT(nframes));
    

    wohl einen Teil des Kernels überschrieben hat. Lt. Quelltext hätte "frames" aber nach Aufruf von

    frames = (ULONG*)kmalloc(INDEX_FROM_BIT(nframes));
    

    0x300000 sein müssen:

    //kheap.c
    
    ULONG kmalloc(ULONG sz)
    {
     return kmalloc_int(sz, 0, 0);
    }
    
    ULONG kmalloc_int(ULONG sz, int align, ULONG *phys)
    {
      if (kheap != 0) // "kheap" ist Null beim ersten Aufruf
      {
    (...)
      }
      else
      {               // "align" ist auch Null
       if (align == 1 && (placement_address & 0xFFFFF000) )
       {
    (...)
       }
       if (phys)      // "phys" auch
       {
       *phys = placement_address;
       }
    // somit wird "placement_address" zurückgegeben
       ULONG tmp = placement_address;
       placement_address += sz;
       return tmp;
      }
    }
    

    Und "placement_address" ist:

    //kheap.h
    (...)
    heap_t* kheap = 0;
    (...)
    ULONG end               = 0x300000;    // 3 MB TODO???
    ULONG placement_address = (ULONG)&end; // <- die Adresse von "end"?????
    

    Hoffentlich hilft das weiter.


  • Mod

    @+gjm+: Danke für die Analyse, kannst Du Dir den aktuellen Code nochmals anschauen?

    Da waren leider doch noch einige plötzlich aufpoppende Fehler mit memset() anstelle k_memset in ordered_array usw., aber dennoch klappt es noch nicht richtig. Habe auch in den headern os.h, ... noch etwas Ordnung (hoffentlich) geschafft.

    Ich schiebe den aktuellen Code mal hoch, vielleicht hat jemand die entscheidende Idee zum Durchblick. Vor lauter blöden Adressen blicke ich nicht mehr durch.
    create_heap() hilft auch noch nicht. Bin nicht völlig sicher, ob das in ckernel.c sein muss. Keine Ahnung, wo der heap momentan erzeugt wird.

    Sehe vor lauter Wald die Bäume nicht mehr, aber den Code dürfte ich jetzt soweit funktionsfähig haben. Könnte sich das bitte mal jemand anschauen (fehlen nur noch die richtigen Parameter, sicher bin ich aber noch nicht)? 🙄
    http://www.henkessoft.de/OS_Dev/Downloads/20_analyze_failure.zip

    EDIT1: hier sieht die frames Anzahl (mit createheap(0x300000,...) z.B. 3674124) nun besser aus.
    es läuft ohne sti() durch bis zum Umschalten auf Paging, dann kommt der reset, kann noch an falschen Parametern liegen:
    http://www.henkessoft.de/OS_Dev/Bilder/Fehlersuche_PAGING_HEAP.PNG

    EDIT2: das Problem liegt in create_heap(...)
    Da ist etwas im hinteren Teil instabil. Auch mit Kontroll-Prints passieren da merkwürdige Sachen auf dem Bildschirm, noch dazu nicht gleich reproduzierbar.
    ..

    heap in create_heap(...) 0000B1D0h
    heap->index in create_heap(...) 00200000h
    header_t_less_than in create_heap(...) 0000A90Ch
    start in create_heap(...) 00280000h
    start ... after alignment check 00281000h

    Absturz?

    Manchmal kommt auch noch die nächste Zeile. ???
    Nach der letzten Ausgabe springt der Cursor nach (0,0)! keine Ahnung warum?
    Dann erfolgt Reset.

    Ohne sti() bekommt man mehr Infos (s.u. seaprater Post)

    Bitte um weitere Unterstützung, damit wir das Thema didaktisch angehen können.

    Ich werde mich mal zur Ablenkung auf die Key Queue als nächste Aufgabe konzentrieren.

    Diesen Paging/Heap Mist werde ich etwas schieben. Dieser verschachtelte Code mit den kreuz und quer verteilten Parametern nervt mich langsam.

    Der Code müsste für ein Tutorial entflochten und klar strukturiert werden.
    Vielleicht kennt/hat jemand etwas Besseres?

    Problemliste:
    - Beep() geht nicht (speaker)
    - Paging/Heap zum Laufen bringen

    Kurzfristige Taskliste:
    - KeyQueue aufbauen (als ersten Schritt kann man die Daten ja über eine Auswerte-Funktion in ckernel.c abholen und darstellen)
    - Paging/Heap entflechten (erst Heap und Demo, dann Paging für Multitasking)

    Auf jeden Fall danke an alle, die mich unterstützen.


  • Mod

    Letzter Stand:
    http://www.henkessoft.de/OS_Dev/Downloads/20_analyze_failure.zip ( ohne sti() )

    #include "os.h"
    
    int main()
    {
        //...
        //sti(); //ansonsten Absturz im hinteren Teil von create_heap(...)
        kheap = create_heap(0x200000, 0x400000, 0x500000, 0, 0);
        paging_install(); //TEST
    

    Bildschirmausdruck:
    http://www.henkessoft.de/OS_Dev/Bilder/Fehlersuche_PAGING_HEAP_1.PNG

    Please help. 😕


  • Mod

    - deleted -


  • Mod

    Fehler gefunden, ein kleines & zuviel vor 'end'. Man sucht immer an der falschen Stelle. Naja, zumindest beschäftigt man sich intensiv mit dem Code. Das hat seine Vorteile. 😉

    Nun endlich lauffähig: die vereinfachte Paging-Version ohne create_heap(...):
    http://www.henkessoft.de/OS_Dev/Downloads/22.zip

    Mit Bitte um Vorschläge zur Vereinfachung und Demo-Nutzung des Codes,
    z.B. Page Fault ...
    Bezüglich Didaktik denke ich darüber nach:
    *Wie kann man Paging zum Anfassen/Experimentieren darstellen?
    Welche Vorteile haben wir nun davon?
    ...
    *


  • Mod

    So nun habe ich auch die komplexe Variante mit create_heap() zum Laufen gebracht.
    @abc.w: bringt sogar eine echte page_fault_exception 😃

    http://www.henkessoft.de/OS_Dev/Downloads/20_Paging_Heap.zip

    So, nun geht's mir wieder besser. 🙂
    ... und den Blick nach vorne:

    Problemliste:
    - Beep() geht nicht (speaker)
    - Scroll in video.c schneidet erstes Zeichen in neuer Zeile ab (??)

    Kurzfristige Taskliste:
    - Paging optimieren (für Tutorial)
    - Was macht man nun mit dem Heap? - Einfache Anwendungssteuerung? (was zuerst?)
    - KeyQueue aufbauen
    - Anwendung auf KeyQueue zugreifen lassen
    - Multitasking


  • Mod

    da gibt's doch 'ne funktion 'create_heap'. die musste natürlich vorher aufrufen.

    @+fricky: Wie Du siehst ist Paging und Heap hier entkoppelt, geht also zum Glück ohne dieses create_heap(...) via kmalloc(...). 🙂



  • Erhard Henkes schrieb:

    da gibt's doch 'ne funktion 'create_heap'. die musste natürlich vorher aufrufen.

    @+fricky: Wie Du siehst ist Paging und Heap hier entkoppelt, geht also zum Glück ohne dieses create_heap(...) via kmalloc(...).

    ok, aber irgendwie musste dem heap ja sagen, wo sein speicher ist.

    Erhard Henkes schrieb:

    - Was macht man nun mit dem Heap? - Einfache Anwendungssteuerung? (was zuerst?)

    na, den user-programmen (und dem kernel, also z.b. treibern usw) die funktionen malloc(), realloc() und free() zur verfügung stellen.

    Erhard Henkes schrieb:

    - Anwendung auf KeyQueue zugreifen lassen

    hier haste für sowas einen lock-free FIFO: http://svn.akop.org/psp/tags/fuse/0.9.0.1/sound/sfifo.c
    so'n FIFO kann z.b. von einer interrupt-routine (oder anderen task) gefüllt und während des lesens müssen keine interrupts gesperrt werden. ich hab' ihn schon mal benutzt: funzt perfekt.
    🙂


  • Mod

    Danke für den Link, aber ich möchte es mit einer Datenstruktur analog BDA probieren, sieht momentan so aus:
    os.h:

    /* This defines the operatings system common data area */
    
    #define KQSIZE    100 // size of key queue
    
    typedef struct oda
    {
        // Hardware Data
        //...
    
        // Key Queue
        UCHAR  KEYQUEUE[KQSIZE];   // circular queue buffer
        UCHAR* pHeadKQ;            // pointer to the head of valid data
        UCHAR* pTailKQ;            // pointer to the tail of valid data
        UCHAR  KQ_count_read;      // number of data read from queue buffer
        UCHAR  KQ_count_write;     // number of data put into queue buffer
    }oda_t;
    
    // operatings system common data area
    oda_t ODA;
    extern oda_t* pODA;
    

    util.c (später vielleicht os.c):

    oda_t* pODA = &ODA;
    
    void initODA()
    {
        int i;
        for(i=0;i<KQSIZE;++i)
           pODA->KEYQUEUE[i]=0;          // circular queue buffer
        pODA->pHeadKQ = pODA->KEYQUEUE;  // pointer to the head of valid data
        pODA->pTailKQ = pODA->KEYQUEUE;  // pointer to the tail of valid data
        pODA->KQ_count_read  = 0;        // number of data read from queue buffer
        pODA->KQ_count_write = 0;        // number of data put into queue buffer
    }
    

    keyboard.c

    void keyboard_handler(struct regs* r)
    {
       UCHAR KEY = ScanToASCII();
       if(KEY)
       {
         *(pODA->pTailKQ) = KEY;
         ++(pODA->KQ_count_write);
    
           if(pODA->pTailKQ > pODA->KEYQUEUE)
           {
               --pODA->pTailKQ;
           }
           if(pODA->pTailKQ == pODA->KEYQUEUE)
           {
               pODA->pTailKQ = (pODA->KEYQUEUE)+KQSIZE-1;
           }
       }
       //...
    }
    

    Test in ckernel.c:

    //...
        initODA();
        printformat("KQ: %x TAIL: %x HEAD: %x", pODA->KEYQUEUE, pODA->pTailKQ, pODA->pHeadKQ);
    
        settextcolor(2,0);
    
    	int y=6;
    	while(TRUE)
    	{
    	    sleepSeconds(10);
    	    if(y>24) y=24;
    	    set_cursor(0,++y);
    	    printformat(" 10 sec: ");
    	    printformat("TAIL: %x HEAD: %x WRITE: %i ", pODA->pTailKQ, pODA->pHeadKQ, pODA->KQ_count_write);
    	    printformat("TAILCONTENT: %c %i HEADCONTENT: %c %i\n", *(pODA->pTailKQ),*(pODA->pTailKQ),*(pODA->pHeadKQ),*(pODA->pHeadKQ));
    	};
    

    ************************************************
    * Welcome to PrettyOS 0.06 *
    * Paging is activated *
    ************************************************
    KQ: 0000A1A4h TAIL: 0000A1A4h HEAD: 0000A1A4h

    10 sec: TAIL: A1A4h HEAD: A1A4h WRITE: 0 TAILCONTENT: 0 HEADCONTENT:
    10 sec: TAIL: A207h HEAD: A1A4h WRITE: 1 TAILCONTENT: 0 HEADCONTENT: a
    10 sec: TAIL: A206h HEAD: A1A4h WRITE: 2 TAILCONTENT: 0 HEADCONTENT: a
    10 sec: TAIL: A205h HEAD: A1A4h WRITE: 3 TAILCONTENT: 0 HEADCONTENT: a
    10 sec: TAIL: A204h HEAD: A1A4h WRITE: 4 TAILCONTENT: 0 HEADCONTENT: a
    10 sec: TAIL: A1FEh HEAD: A1A4h WRITE: 109 TAILCONTENT: g 103 HEADCONTE
    NT: a 97

    0xA207 = 0xA1A4 + 0x64 (KQSIZE) - 1
    passt also alles. Den Tasten-Release (KEY == 0) habe ich unterdrückt, so dass nur ein Zeichen pro Tastenanschlag in die KQ gelangt.

    Ich möchte diesen Mechanismus komplett selbst durchziehen, weil ich das derart low-level noch nicht gemacht habe, bin durch die Standard Template Library verhätschelt. 😃

    Über Lesen aus der KQ und Interrupts habe ich mir noch keine Gedanken gemacht.
    Wie geht man mit einem buffer full, also (pODA->KQ_count_write - pODA->KQ_count_read)>100 um. Da ich die Zähler momentan leichtsinnig in UCHAR definiert habe, kommt es auch noch zu einem Überlauf. 😃 Das lässt sich sicher durch ULONG in den Griff bekommen, aber prinzipiell ist das Problem dadurch nur in die weite Ferne geschoben. Es soll ja Leute geben, die ihren Rechner nie ausschalten. Bei PrettyOS ist das fast garantiert. 😉

    Wo sollte das Lese-Programm, also das alte:

    restore_cursor();
       switch(KEY)
       {
           case KINS:
               break;
           case KDEL:
               move_cursor_right();
               putch('\b'); //BACKSPACE
               break;
           case KHOME:
               move_cursor_home();
               break;
           case KEND:
               move_cursor_end();
               break;
           case KPGUP:
               break;
           case KPGDN:
               break;
           case KLEFT:
               move_cursor_left();
               break;
           case KUP:
               break;
           case KDOWN:
               break;
           case KRIGHT:
               move_cursor_right();
               break;
           default:
               printformat("%c",KEY); // the ASCII character
               break;
       }
       save_cursor();
    

    nun eigentlich hin? Der User will doch Zahlen und Buchstaben sehen, wenn er tippt. 😃 Zumindest als Demo.
    Soll ich das als getchar() in keyboard.c realisieren und in ckernel.c mal als demo in der while-Schleife (klares "Polling") laufen lassen oder habt ihr bessere Ideen?


  • Mod

    Ich habe das zunächst als k_checkKQ_and_print_char() umgesetzt, um didaktisch an unsere bisherige - von Nobuo T kritisierte - "Schreibmaschine" in keyboard_handler(...) anzuknüpfen.

    Test in ckernel:

    UINT c=0;
    	while(TRUE)
    	{
    	  if( k_checkKQ_and_print_char() )
    	  {
    	    ++c;
    	    if(c>79)
    	    {
    	      c=0;
    	      settextcolor(4,0);
    	      printformat("\nT: %x H: %x WRITE: %i Read: %i ", pODA->pTailKQ, pODA->pHeadKQ, pODA->KQ_count_write, pODA->KQ_count_read);
              printformat("*T: %c %i *H: %c %i\n", *(pODA->pTailKQ),*(pODA->pTailKQ),*(pODA->pHeadKQ),*(pODA->pHeadKQ));
              settextcolor(2,0);
    	    }
    	  }
    	}
    
    jkdfhsdjkhgksjhkjdhkjdfshjkdsfhgjkhjghdfjkghjkdfhgdjkfhkdjfhgkdjfhgkjdfhjkdfhgjk
    dfhgjkdfhksdfhksdahfksdajhfkjsdhfksdjhfksdajhfasdkhfjkasdhfkasjdfhkjasdhfksladjh
    faskdjlhfkjhsadkjfhkjasdhfjkasdfhkajsdhfjkasdfhkjasdhfjkasdhfjkasdhfjkasdhfjkasd
    hfjkhfjkasdhfjksdhfkjahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
    hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
    hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
    hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
    jjjjjjjjjjjjjjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkkkkKKKKKKKKKKKKKLAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    T: 0000A2DAh H: 0000A2DAh WRITE: 640 Read: 640 *T: j 106 *H: j 106
    T: 0000A2EDh H: 0000A2EDh WRITE: 720 Read: 720 *T: A 65 *H: A 65
    

    Test und Reaktion (welche?) auf BufferFull/Overrun fehlt noch.
    Die Pfeiltasten links/rechts kommen nicht mehr durch.
    Was man wirklich mit den Infos in der KeyQueue machen will, hängt sehr von der konkreten Anwendung ab. Ich frage mich momentan, wie man mit den Sondertasten sinnvoll umgehen sollte. Als Flags in der ODA wie bei der BDA machen sie keinen Sinn, weil man nicht weiß, zu welchem Zeichen sie gehören. Aber das lässt sich alles leicht anpassen. Vielleicht hat jemand eine glänzende Idee oder gute Erfahrungen mit eigenen OS.

    Ich schieb das Programm oben mal hoch, wenn jemand mit dem Code spielen will:
    http://www.henkessoft.de/OS_Dev/Downloads/22a.zip

    Baut man eine Verzögerungsschleife ein, so kommt Schreiben/Lesen so ab 100 Millisekunden (Warteschleife für ms habe ich nun in timer.c ergänzt) aus dem Gleichklang: http://www.henkessoft.de/OS_Dev/Downloads/22b.zip

    jksdghkdfjhgkskdfjhgkjsdfhgkjsdfhgskjdfhkhjhgdfjkhgdfkjhgkjdfhgkjdfhgkdfjhgkjdfh
    gkfdhgkdfhgkdfhgkdfhgkdfhgkdfjhgkdfhgkdfhgkfhkjdshgkjsdfjjjjjjjjjjjjjjjjjjjjjjjj
    jjjjJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAh WRITE: 662 Read: 640 *T: A 65 *H: A 65
    T: 0000A2E0h H: 0000A30Dh WRITE: 765 Read: 720 *T: A 65 *H: A 65
    

    Bleiben die Fragen, wie groß muss KQ sein und wie geht man mit einem Overrun um? (früher hat es da gepiepst 😃 ).


  • Mod

    Bezüglich der Interpretation von Scancodes habe ich folgende interessante Gliederung gefunden:
    http://www.toasteros.net/
    ..


Anmelden zum Antworten