Eigenes OS?


  • Mod

    Die Interrupt-Technik habe ich bereits vorbereitet (0x7F = 127).

    ..

    ➡ Danke an alle, die mich bisher soweit getragen haben.
    Jetzt habe ich soviel OS-Blut geleckt, dass ich keinesfalls aufhöre. 😋
    Diesem Assembler-Forum möchte ich für seine konstruktive und offene Haltung ein ganz großes Lob aussprechen. Das findet man sehr selten!



  • blitzmaster schrieb:

    also ich würde euch empfehlen, das ganze über interrupts zu machen. da gibts dann später bei multitasking keine probleme, da bei einem interrupt autamtisch das i-flag in den eflags gelöscht wird, sodass der kernel nicht unterbrochen werden wird...

    interrupts global zu sperren (macht man das mit dem i-flag?) ist, wenn nicht unbedingt erforderlich, eigentlich keine gute idee, weil dann interrupt-anforderungen verloren gehen können, wenn die sperre zu häufig eingesetzt wird oder lange dauert. und ich weiss nicht, ob die pc-architektur 'nested' interrupts und interrupt-prioritäten kennt (ich glaub' die hardware unterstützt es nicht, aber es geht mit software-tricks).

    blitzmaster schrieb:

    Aber nachdem das ja ein Sprung in den Kernel ist, könnte es sein, dass dann zwei Tasks gleichzeitig springen und im Kernel dann Datenstrukturen zerstört werden, weil das nicht synchron geschieht.

    in einem multitasking-os sollten systemfunktionen sowieso immer reentrant-fähig sein. dass mehrere task gleichzeitig im kernel rumschwirren, oder gar die selbe systemfunktion nutzen, ist keine seltenheit.
    🙂


  • Mod

    in einem multitasking-os sollten systemfunktionen sowieso immer reentrant-fähig sein. dass mehrere task gleichzeitig im kernel rumschwirren, oder gar die selbe systemfunktion nutzen, ist keine seltenheit.

    Klingt wirklich herausfordernd, erinnert mich an multithreading. Da lauern neben "malicious codes" bestimmt schon die "deadlocks". 😉

    interrupt-prioritäten

    Je kleiner die Zahl, je höher die Priorität, zumindest habe ich es so gelesen. Also Timer > Keyboard > ...

    Hat eigentlich jemand einen Tipp, wie ich "Files" - ohne GRUB - möglichst einfach in diese RAM disk tranferieren kann, so dass man den VFS-Mechanismus mal vorführen könnte?



  • +fricky schrieb:

    blitzmaster schrieb:

    also ich würde euch empfehlen, das ganze über interrupts zu machen. da gibts dann später bei multitasking keine probleme, da bei einem interrupt autamtisch das i-flag in den eflags gelöscht wird, sodass der kernel nicht unterbrochen werden wird...

    interrupts global zu sperren (macht man das mit dem i-flag?) ist, wenn nicht unbedingt erforderlich, eigentlich keine gute idee, weil dann interrupt-anforderungen verloren gehen können, wenn die sperre zu häufig eingesetzt wird oder lange dauert. und ich weiss nicht, ob die pc-architektur 'nested' interrupts und interrupt-prioritäten kennt (ich glaub' die hardware unterstützt es nicht, aber es geht mit software-tricks).

    Jo, das IF ignoriert praktisch die IRQ-Line der CPU (nicht aber NMIs, exceptions, usw.).
    AFAIR: Selbst der PIC (programmable Interrupt Controller) in den ersten PCs kannte schon eine Prioritaetsbehandlung von IRQs. Das Ding wurde dann zunaechst in typischer x86-manier erweitert, indem man quasi den gleichen Controller nochmal hinten dran geklatscht hat (toll: jetzt mit 16 IRQs!!) und inzwischen gibt es den in die CPU integrierten APIC.
    IAR geht also nichts verloren, wenn das IF geloescht wird ... es sei denn, das bleibt ueber Sekunden so (daher auch meine Ermahnung, schnelle IRQ-handler zu schreiben).
    Dennoch hast du recht: IRQs sollte man nur ausschalten, wenn unbedingt noetig, was bei x86ern mit ihren ganzen atomaren spezial-Befehlen im Prinzip relativ selten vorkommen duerfte.

    +fricky schrieb:

    blitzmaster schrieb:

    Aber nachdem das ja ein Sprung in den Kernel ist, könnte es sein, dass dann zwei Tasks gleichzeitig springen und im Kernel dann Datenstrukturen zerstört werden, weil das nicht synchron geschieht.

    in einem multitasking-os sollten systemfunktionen sowieso immer reentrant-fähig sein. dass mehrere task gleichzeitig im kernel rumschwirren, oder gar die selbe systemfunktion nutzen, ist keine seltenheit.
    🙂

    Richtig. Da kann man entweder alle moeglichen Teile des Kerns einzeln in kritische Sektionen packen, oder man tuetet den ganzen Kern einfach in eben eine solche. Zu Demonstrationszwecken im Rahmen eines Tutorials waere das IMHO uebersichtlicher. Dabei kann man dann auch problemlos IRQs zulassen.

    Int loescht uebrigens nicht das IF. AFAIR sysenter genau so wenig.
    Die Entscheidung gegen sysenter und fuer int befuerworte ich uebrigens (wie ich schon sagte) : Kein neuer Spezial-Befehl, Gebastel mit AMD vs. Intel, einfache Handhabung, abwaertskompatibel. KISS halt. 😃

    BTW ist die Benutzung eines eigenen Stacks fuer Kern-Aufrufe (auch IRQ- und Exception-Handler) wie gesagt dringend zu empfehlen. Praktisch fast wie ein TASK-Switch.



  • Nobuo T schrieb:

    Int loescht uebrigens nicht das IF. AFAIR sysenter genau so wenig.

    So weit ich weiß, wird das IF bei einem Sprung zu einem Interrupt Gate gelöscht.



  • Erhard Henkes schrieb:

    in einem multitasking-os sollten systemfunktionen sowieso immer reentrant-fähig sein. dass mehrere task gleichzeitig im kernel rumschwirren, oder gar die selbe systemfunktion nutzen, ist keine seltenheit.

    Klingt wirklich herausfordernd, erinnert mich an multithreading.

    isses auch. multithreading und -tasking bedeutet, je nach kontext, mal was anderes, mal das selbe. windows-user verstehen unter multitasking, dass gleichzeitig mehrere prozesse möglich sind, von denen jeder mehrere threads (==parallel ausführbare einheiten) haben kann. in der RTOS-terminologie wird das, was unter win 'thread' heisst, oft 'task' oder 'prozess' genannt.

    Nobuo T schrieb:

    BTW ist die Benutzung eines eigenen Stacks fuer Kern-Aufrufe (auch IRQ- und Exception-Handler) wie gesagt dringend zu empfehlen. Praktisch fast wie ein TASK-Switch.

    dann haste aber ein ziemlich schwergewichtiges interface zwischen kernel und userland, das syscalls relativ unperformant macht. eigentlich braucht man doch nur einen privilegwechsel beim sprung in den kernel und bei der rückkehr. natürlich musste noch checken, ob die parameter gültig sind, genug platz auf dem stack ist, pointer sinnvollen inhalt haben und ähnliche kleinigkeiten. einen kompletten, task-switch ähnlichen mechanismus, halte ich für übertrieben. aber vielleicht geht's mit den x86 software-int befehlen nur so (weshalb später 'sysenter' eingeführt wurde).
    🙂


  • Mod

    Die system calls laufen. Man kann also nun z.B. die Funktion puts(...) als syscall_puts(...) aufrufen. Ich benötige mal eure Hilfe, da ich momentan etwas nicht verstehe und nicht sicher bin, ob das genau so richtig ist oder ob im OS etwas nicht stimmt (was mir wahrscheinlicher erscheint).

    Ich habe hier zwei Varianten:
    http://www.henkessoft.de/OS_Dev/Downloads/31&32.zip
    31) nach dem switch_to_user_mode() hat der user privileg 0
    32) nach dem switch_to_user_mode() hat der user privileg 3

    Im ersten Fall:

    switch to user mode
    After set_kernel_stack. tss_entry.esp0: 0000083Ch
    Right before user mode

    IRQ 127<<<Hello, user world!
    behind switch to user mode with ring 0 supervisor privilege!
    SS: 00000010h, ESP: 0018FFE0h, EBP: 0018FFF0h, CS: 00000018h, DS: 00000020h

    Das "Hello, user world!" wird mittels syscall_puts(...) ausgegeben. Daher weiß ich, dass die system calls nun funktionieren. Baut man auf diese Weise ein API auf? (habe das bisher noch nie gemacht 😃 )

    switch_to_user_mode();
        syscall_puts("Hello, user world!\n");
    

    Im zweiten Fall:

    switch to user mode
    After set_kernel_stack. tss_entry.esp0: 0000083Ch
    Right before user mode
    Page Fault

    Exception. System Halted! <<<

    Ich bin etwas irritiert darüber, dass im echten User Mode der Syscall (ring 3 ruft ring 0) vor dem Page Fault (wegen unerlaubtem Zugriff auf Kernel code) nicht durchgegangen ist. Vielleicht liegt es daran, dass auf dem Weg zur Ausführung des Syscalls (... -> IRQ127 -> syscall_handler -> ...) bereits ein "Page Fault" erfolgte.

    Sorry, dass der Code im IRQ-Bereich momentan etwas "gestöpselt" ist. Das muss ich noch aufräumen, wollte jetzt nur erst mal das Tasking und die Syscalls zum Laufen bekommen, denn die Schnittstelle zwischen Kernel und Anwendungen im User Mode sind ja genau das Interessante. 🙂

    Wenn ich das so nebeneinander sehe, wundere ich mich gerade über die Leerzeile zwischen Right before user mode und >>>IRQ 127<<<Hello, user world!.

    Die nächste Aufgabe ist jetzt, den vorhandenen Code vernünftig zu überarbeiten, damit er eine wirklich brauchbare Basis für ein OS ergibt, möchte nicht völlig chaotisch weiter hetzen, weil dann die Didaktik und vor allem das Tutorial auf der Strecke bleibt. Schlechten Code erklärt und zeigt man nicht gerne, sondern ist froh, wenn er läuft. Damit Experimentieren ist zumeist auch nicht gerade lustig. Vielleicht, wenn man die Module noch ordentlich sortiert und hier und da entkoppelt, kann das noch etwas Sinnvolles werden?

    Vielleicht kann sich ein Assembler-Spezialist die IRQ/ISR/exception-Story mal anschauen (z.Z. eine wilde Mischung aus ASM und C). Da blicke ich kaum noch selbst durch. Den int127 (128 ging nicht wegen Überlauf, muss ja auch nicht sein, wäre nur wegen Linux 0x80) habe ich schon an den fault_handler, der eigentlich nur für exceptions gedacht war, "provisorisch angeschraubt", ging irgendwie nicht anders. 🙄 Aber so ist wahrscheinlich auch Windows und Linux entstanden. 😃

    Inzwischen habe ich gehörig Respekt vor der OS-Entwicklung. 👍
    ... und das Schwierigste liegt ja eher noch vor mir. 🕶


  • Mod

    ..

    Gut finde ich bisher,
    - dass nicht der GRUB Loader verwendet wird
    - den sauberen Übergang von Assembler zum C-Kernel (thanks to Nobuo T)
    - die Bitset-Verwaltung beim Paging (effizient)
    - das VFS analog Linux (leider noch nicht richtig in Aktion)

    Schlecht finde ich
    - das Interrupt-Gerödel (richtig zusammen geschustert, da verwende ich sogar noch den alten Aufbau, weil James das auch nicht wirklich auf die Reihe bekam, ist jedoch im Wesentlichen Fleißarbeit, das zu ordnen)
    - die AT&T Syntax innerhalb C (ziemlich unverständlich, das gehört wirklich alles als Intel Syntax ausgelagert, da hat abc.w Recht)

    Unsicher bin ich mir bei
    - der Heap-Erzeugung/-Verwaltung (schwieriges aber langweiliges Thema, Hauptsache läuft erstmal)
    - der Tasking-Steuerung

    Das wird aber alles noch richtig gut, da bin ich ganz sicher.

    Ich musste für mich schnell Zusammenhänge praktisch durchspielen, daher der Rückgriff auf Vorhandenes, um zu sehen, was wirklich voneinander abhängt. Übrigens geht es anderen auch so. Selbst, wenn ich den Sourcecode alleine erfinde, bringt das niemand weiter. Für andere ist der Code immer "fremd". Was zählt, sind gute Erklärungen. Da sieht es in James Molloy's Tutorial allerdings düster aus.

    Was mir bisher noch weitgehend fehlt, ist die Darstellung der Arbeitsweise des OS. Ich möchte kein "unsichtbares" OS, sondern einen "offenen Wecker". Da habe ich bisher überhaupt noch keinen Ansatz gefunden, das ist bei vielen "Educational OS" lauter in sich geschlossenes unverständliches "Gefrickel".

    ..


  • Mod

    ..


  • Mod

    So sieht momentan ein typischer Bildschirmausdruck zur Überprüfung aus:
    ..

    Bezüglich Visualisierung des Pagings habe ich mal Folgendes probiert:
    Um das Bitset mit seinen Nullen und Einsen und den Bezug zu den Speicheradressen darzustellen, habe ich die unten stehende Funktion entworfen. Sie bleibt 'sec' Sekunden stehen, wenn eine oder mehrere Einsen (allokierte Pages) auftauchen, bei Nullen flitzt sie durch. Damit kann man recht praktisch den Speicher scannen und sich in Bochs mit copy von der jeweils interessanten Region screenshots machen:

    void analyze_frames_bitset(ULONG sec)
    {
        ULONG index, offset, counter1=0, counter2=0;
        for(index=0; index<(NFRAMES/32); ++index)
        {
            settextcolor(15,0);
            printformat("\n%x  ",index*32*0x1000);
            ++counter1;
            for(offset=0; offset<32; ++offset)
            {
                if( !(frames[index] & 1<<offset) )
                {
                    settextcolor(4,0);
                    putch('0');
                }
                else
                {
                    settextcolor(2,0);
                    putch('1');
                    ++counter2;
                }
            }
            if(counter1==24)
            {
                counter1=0;
                if(counter2)
                    sleepSeconds(sec);
                counter2=0;
            }
        }
    }
    

    Diese Funktion geht sämtliche Pages durch und stellt jeweils 32 in einer Zeile je nach Allokation als Null oder Eins dar. Vorne steht die erste Hex-Speicheradresse der ersten Page (also jeweils 4KB * 32 = 128KB in einer Reihe).

    Bsp.: Erstes Ende der kompakten Allokierung oberhalb 18 MB (1200000h) :

    011C0000h  11111111111111111111111111111111
    011E0000h  11111111111111111111111111111111
    01200000h  11111111111111111110000000000000
    01220000h  00000000000000000000000000000000
    

    Screenshot: http://www.henkessoft.de/OS_Dev/Bilder/Paging_Scan.PNG

    Bsp.: #define KHEAP_START 0x40000000 // 1GB
    #define KHEAP_INITIAL_SIZE 0x100000
    #define KHEAP_MAX 0x4FFFF000
    Dort befindet sich auch die RAM Disk:

    3FFC0000h  00000000000000000000000000000000
    3FFE0000h  00000000000000000000000000000000
    40000000h  10100110000011001000100010000000
    40020000h  10100000000000101000100010000000
    40040000h  10100000000010101000100010000000
    40060000h  10100000000001101000100010000000
    40080000h  10100000000011101000100010000000
    400A0000h  10100000000000011000100010000000
    400C0000h  10100000000010011000100010000000
    400E0000h  10100000000001011000100010000000
    40100000h  10100000000011011000100010000000
    40120000h  10100000000000111000100010000000
    40140000h  10100000000010111000100010000000
    40160000h  10100000000001111000100010000000
    40180000h  10100000000011111000100010000000
    401A0000h  10100000000000000100100010000000
    401C0000h  10100000000010000100100010000000
    401E0000h  10100000000001000100100010000000
    

    usw.

    Zum Verständnis die Bitset-Funktionen aus paging.c:
    ..

    Nun "sieht" man endlich, was man macht. 😉
    Solche Dinge sind mir wie bereits ausgeführt wichtig.

    EDIT: Ebenfalls hilfreich ist eine Analyse der physikalischen Adressen der Startadressen der Pages:

    ULONG show_physical_address(ULONG virtual_address)
    {
        page_t* page = get_page(virtual_address, 0, kernel_directory);
        return( (page->frame_addr)*PAGESIZE + (virtual_address&0xFFF) );
    }
    
    void analyze_physical_addresses()
    {
       int i,j,k, k_old;
        for(i=0;i<(PHYSICAL_MEMORY/0x18000+1);++i){
            for(j=i*0x18000; j<i*0x18000+0x18000; j+=0x1000){
                if(show_physical_address(j)==0){
                    settextcolor(4,0); k_old=k; k=1;
                }
                else{
                    if(show_physical_address(j)-j){
                        settextcolor(3,0); k_old=k; k=2;
                    }
                    else{
                        settextcolor(2,0); k_old=k; k=3;
                    }
                }
                if(k!=k_old)
                    printformat("%x %x\n", j, show_physical_address(j));
            }
        }
    }
    

    00000000h 00000000h
    00001000h 00001000h
    01113000h 00000000h
    01400000h 12389000h
    40100000h 00000000h
    40400000h 12389000h

    12389... ist eine "Magic Number" (#define HEAP_MAGIC 0x123890AB in kheap.h)


  • Mod

    Um den Page Fault näher zu beschreiben, wurde jetzt folgende Auswertung eingebaut:

    if (r->int_no == 14) //Page Fault
            {
                ULONG faulting_address;
                asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); // faulting address => CR2 register
    
                // The error code gives us details of what happened.
                int present   = !(r->err_code & 0x1); // Page not present
                int rw        =   r->err_code & 0x2;  // Write operation?
                int us        =   r->err_code & 0x4;  // Processor was in user-mode?
                int reserved  =   r->err_code & 0x8;  // Overwritten CPU-reserved bits of page entry?
                int id        =   r->err_code & 0x10; // Caused by an instruction fetch?
    
                // Output an error message.
                              printformat("Page Fault (");
                if (present)  printformat("page not present");
                if (rw)       printformat("read-only - write operation");
                if (us)       printformat("user-mode");
                if (reserved) printformat("overwritten CPU-reserved bits of page entry");
                if (id)       printformat("caused by an instruction fetch");
                              printformat(") at %x - EIP: %x\n", faulting_address, r->eip);
            }
    

    Test mit Page Fault: http://www.henkessoft.de/OS_Dev/Downloads/34.zip

    Der Page Fault wurde provoziert durch Streichen des Extra-Speichers oberhalb der placement_address:

    // Allocate a little bit extra so the kernel heap can be initialised properly.
        // map (phys addr <---> virt addr) from 0x0 to the end of used memory
        ULONG counter=0;
        i=0;
        while( i < placement_address /*+ 0x100000*/ ) //important to add more! 
        {
            alloc_frame( get_page(i, 1, kernel_directory), 0, 0);
            i += PAGESIZE;
            ++counter;
        }
    

    Dadurch kann man heraus finden, wieviel Speicher allokiert werden muss, um den Kernel Heap zu initialisieren. Endlich mal eine Aufgabe für die Leser. 😃

    Antwort: Bei 0x0 0der 0x1000 erfolgt ein Page Fault. Die Info lautet:

    Page Fault (page not present) at 01014004h - EIP: 0000AD36h

    Über die Info 01014000h 00000000h weiß man, dass nur bis 01013000h frames allokiert wurden. Daher muss man mindestens 0x1001 addieren, welches dann auf 0x2000 "aligned" wird. Dann klappt das.

    So langsam bekomme ich das Thema Paging didaktisch in den Griff. Jetzt fehlt eigentlich nur noch die Darstellung des nicht-linearen Mappings.


  • Mod

    Für das Laden von vorgefertigten File-Daten in den Speicher für die Ram Disk des VFS hat mir jemand einen möglichen Weg gewiesen, nämlich via NASM-Anweisung incbin und Linken mit ld. Diesen Befehl kannte ich bisher noch nicht.


  • Mod

    Hier ein prinzipielles Beispiel mit Erzeugung mehrerer Tasks und Taskswitch:
    http://www.henkessoft.de/OS_Dev/Downloads/35.zip

    After set_kernel_stack ==> tss_entry.esp0: 40101800h

    > IRQ 127 <<<
    Hello, user world!

    create a new process in a new address space
    fork() returned: 00000002h and getpid() returned: 00000001h

    create a new process in a new address space
    fork() returned: 00000003h and getpid() returned: 00000001h

    create a new process in a new address space
    fork() returned: 00000004h and getpid() returned: 00000001h

    getpid() 00000002h
    getpid() 00000003h
    getpid() 00000004h
    getpid() 00000001h
    getpid() 00000002h

    int retValFork1 = fork(); //create a new process in a new address space which is a clone of this
        int retValGetPid1 = getpid();
        printformat("fork() returned: %x and getpid() returned: %x\n", retValFork1, retValGetPid1);
    //...
        task_switch();
        printformat("getpid() %x\n", getpid());
        sleepSeconds(3);
        task_switch();
    //...
    

    Den Scheduler kann man dann über den Timer aufrufen.

    Mit Task Switches kann man schon auf einfachste Weise recht nette Sachen machen, hier ein Beispiel mit Farbwechsel (Farbe = Process ID) beim Tippen:
    http://www.henkessoft.de/OS_Dev/Downloads/35a.zip (Programm)
    http://www.henkessoft.de/OS_Dev/Downloads/task_switch_test.png (Test in Bochs)

    UCHAR c=0;
    	while(TRUE) {
    	  if( k_checkKQ_and_print_char() ) {
    	    ++c;
    	    if(c>5) {
    	      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);
              task_switch(); settextcolor(getpid(),0);
    	    }
    	  }
    	}
    

    Interessant ist, wenn man die Zeile task_switch(); settextcolor(getpid(),0); an eine andere Stelle in der while-Schleife setzt, dann gibt es einen eindrucksvollen "General protection fault":
    http://en.wikipedia.org/wiki/General_protection_fault#Switching
    ..

    Nun muss ich mich noch mit dem Fileformat, dem Transfer in die RAM Disk und dem Zugriff im Programm via Virtual File System beschäftigen. Sobald das alles klappt und die Didaktik passt, werde ich stepwise am Tutorial weiter schreiben (verflixt viel Material und Background) und ein Basis Modell für die Weiterentwicklung von PrettyOS stabilisieren.



  • Erhard Henkes schrieb:

    Nun muss ich mich noch mit dem Fileformat, dem Transfer in die RAM Disk und dem Zugriff im Programm via Virtual File System beschäftigen. Sobald das alles klappt und die Didaktik passt, werde ich stepwise am Tutorial weiter schreiben (verflixt viel Material und Background) und ein Basis Modell für die Weiterentwicklung von PrettyOS stabilisieren.

    nun wird es auch an der zeit sein, dir grundsätzliche überlegungen zu machen, ob du dabeibleiben oder abweichen solltest.
    nur ein kleines beispiel: ich bekomme als spielstandslader oder compilerbauer vom bs (win oder linux hier echt gleich) per filemapping daten hereingeschubst. Shade nannnte es dieser datenhaltung diesbezüglich afair NonCopyStrings, ich splitte bei zum beispiel immer bei \n und habe "zeilen", die aus struct{char *begin,*end} bestehen. das bs gibt mir einen bei read() z.B. 8K großen sektor un ich gebe ihn zurück, wenn ich ihn nicht mehr brauche. natürlich kann ich als old-style-lib ein kopierendes read() im userspace anbieten. vielleicht wäre ein no-copy-read verflixt viel schneller, wenn die anwendung das neue paradigma verwendet. in dieser richtung isses nicht nervig. andersrum schon: ich habe viele strings, ich habe ausschließlich stings mit begin/end in meiner anwendung (naja, c++ halt) und muß bei jedem syscall erstmal speicher für nullterminierten string anlegen, würg.
    vielleicht wäre das an sich gar kein problem, wenn man strings von vorn herein mit begin/end auch im kernel schon angedacht hätte.
    vielleicht wäre das ganze startup/shuutdown-geschmuse gar nicht notwendig, wenn ein prozess==programm leben würde, sobald es installiert ist und runterfahren/hochfahren nur betriebssystem-kacke wäre, die die anwendungen gar nicht sehen.
    nur mal so als meinen kleinen einwurf. es könnte möglich sein, daß anscheinend voll verrückte konzepte aus versehen zugleich dir voll arbeit sparen, das BS schneller machen und für den anwendungsprogrammierer auch noch netter sind.

    hihi, ich möchte nicht in deinen schuhen stecken.



  • volkard schrieb:

    nur ein kleines beispiel: ich bekomme als spielstandslader oder compilerbauer vom bs (win oder linux hier echt gleich) per filemapping daten hereingeschubst. Shade nannnte es dieser datenhaltung diesbezüglich afair NonCopyStrings, ich splitte bei zum beispiel immer bei \n und habe "zeilen", die aus struct{char *begin,*end} bestehen. das bs gibt mir einen bei read() z.B. 8K großen sektor un ich gebe ihn zurück, wenn ich ihn nicht mehr brauche.

    hört sich gut an. eine proprietäre high-speed datenschnittstelle zwischen OS und user-mode hat vorteile, z.b. wenn irgendwann netzwerkprotokolle, filesystems, etc. dran sind, die dann bequem im userspace laufen könnten, was der stabilität des system zugute kommen würde. knackpunkt ist aber das zurückgeben der buffer ans system, es wäre ja doof, wenn die anwendung das vergisst und der kernel irgendwann 'out of memory' ist.

    volkard schrieb:

    hihi, ich möchte nicht in deinen schuhen stecken.

    ich auch nicht, aber erhard hat durchhaltevermögen und auf den kopf gefallen ist er auch nicht.
    🙂


  • Mod

    Danke für den interessanten Einwurf. 🙂

    hihi, ich möchte nicht in deinen schuhen stecken.

    Das Problem ist, dass alles miteinander vernetzt ist, aber so ist es nun einmal.



  • Erhard Henkes schrieb:

    Das Problem ist, dass alles miteinander vernetzt ist, aber so ist es nun einmal.

    deswegen sollteste frühzeitig das ganze in überschaubare teilkomponenten zerlegen, KISS-prinzip, teile und herrsche und so.
    🙂



  • Erhard Henkes schrieb:

    hihi, ich möchte nicht in deinen schuhen stecken.

    Das Problem ist, dass alles miteinander vernetzt ist, aber so ist es nun einmal.

    hihi, ich möchte nicht in deinen schuhen stecken.


  • Mod

    deswegen sollteste frühzeitig das ganze in überschaubare teilkomponenten zerlegen

    Genau dies werde ich versuchen, soweit das möglich ist. Paging, Heap, Task Switching, User Mode vs Kernel Mode, Syscalls, VFS sind solche Einheiten, die allerdings zum einfachen Begreifen teilweise zu groß sind. Da versuche ich gerade, Unterelemente als elementare Module weiter heraus zu schneiden.

    Noch wichtiger ist die Visualisierung / Verständlichmachung dessen, was passiert, wenn man dies oder jenes ändert, weil viele Leute beim Verstehen und Begreifen eher praktisch an die Dinge heran gehen.

    ..

    Der Schwachpunkt von PrettyOS besteht momentan noch darin, dass noch kein Fileformat festgelegt wurde (jedoch kein Problem) und noch kein Mechanismus zum Übertragen von "Files" (Laden/Lesen Schreiben/Speichern), z.B. aus der RAM Disk in den Speicher und umgekehrt existiert. Sobald diese Mechanismen funktionieren, komme ich auf dieses Thema "proprietäre high-speed Datenschnittstelle zwischen OS und User Mode" zurück. Es geht nichts verloren. Wie sehen die entsprechenden Pendants bei Linux und Windows genau aus, damit ich das im Detail studieren kann?



  • Erhard Henkes schrieb:

    Wie sehen die entsprechenden Pendants bei Linux und Windows genau aus, damit ich das im Detail studieren kann?

    win haste ja schon gefunden. bei linux heißt die schlüsselfunktion mmap http://linux.die.net/man/3/mmap


Anmelden zum Antworten