Efterligne Linus Torvalds: Opret dit eget operativsystem fra bunden (VI)

Nå, efter en lille parentes fortsætter vi med vores række tutorials. Hvis vi vender tilbage til den forrige kode, skal vi have ISR for divisionen med nul. Nu skal vi udfylde resten af ​​ISR'erne, som vi havde sendt en besked om (de første 32). Nå skal vi fortsætte programmeringen af ​​afbrydelser, vi skal gøre IRQ'erne, også kendt som Afbryder anmodninger. Disse IRQ'er genereres af hardwareenheder såsom tastaturer, mus, printere osv. Oprindeligt kortlægges de første 8 IRQ'er automatisk til IDT-positioner 8-15. Da vi har brugt de første 32 til undtagelser, er vi nu nødt til at omlægge dem. Vi sætter IRQ fra 32 til 45. Til dette skal vi først omforme IRQ'erne:

void ND::IRQ::Remap(int pic1, int pic2)
{
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
/* send ICW1 */
ND::Ports::OutputB(PIC1, ICW1);
ND::Ports::OutputB(PIC2, ICW1);
/* send ICW2 */
ND::Ports::OutputB(PIC1 + 1, pic1); /* remap */
ND::Ports::OutputB(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
ND::Ports::OutputB(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
ND::Ports::OutputB(PIC2 + 1, 2);
/* send ICW4 */
ND::Ports::OutputB(PIC1 + 1, ICW4);
ND::Ports::OutputB(PIC2 + 1, ICW4);
/* disable all IRQs */
ND::Ports::OutputB(PIC1 + 1, 0xFF);
}

Nu opretter vi en funktion til at installere IRQ'erne:

void ND::IRQ::Install()
{
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_BLACK);
ND::Screen::PutString("\nInstalling IRQ...");
ND::IRQ::Remap(0x20,0x28);
ND::IDT::SetGate(32,(unsigned)ND::IRQ::IRQ1,0x08,0x8E);
ND::IDT::SetGate(33,(unsigned)ND::IRQ::IRQ2,0x08,0x8E);
ND::IDT::SetGate(34,(unsigned)ND::IRQ::IRQ3,0x08,0x8E);
ND::IDT::SetGate(35,(unsigned)ND::IRQ::IRQ4,0x08,0x8E);
ND::IDT::SetGate(36,(unsigned)ND::IRQ::IRQ5,0x08,0x8E);
ND::IDT::SetGate(37,(unsigned)ND::IRQ::IRQ6,0x08,0x8E);
ND::IDT::SetGate(38,(unsigned)ND::IRQ::IRQ7,0x08,0x8E);
ND::IDT::SetGate(39,(unsigned)ND::IRQ::IRQ8,0x08,0x8E);
ND::IDT::SetGate(40,(unsigned)ND::IRQ::IRQ9,0x08,0x8E);
ND::IDT::SetGate(41,(unsigned)ND::IRQ::IRQ10,0x08,0x8E);
ND::IDT::SetGate(42,(unsigned)ND::IRQ::IRQ11,0x08,0x8E);
ND::IDT::SetGate(43,(unsigned)ND::IRQ::IRQ12,0x08,0x8E);
ND::IDT::SetGate(44,(unsigned)ND::IRQ::IRQ13,0x08,0x8E);
ND::IDT::SetGate(45,(unsigned)ND::IRQ::IRQ14,0x08,0x8E);
ND::IDT::SetGate(46,(unsigned)ND::IRQ::IRQ15,0x08,0x8E);
ND::IDT::SetGate(47,(unsigned)ND::IRQ::IRQ16,0x08,0x8E);
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_GREEN);
ND::Screen::PutString("done");
asm volatile("sti");
}

Sætningen af ​​asm kender vi aktiverer IRQ'erne. Nå, nu går vi med noget der ligner ISR. Funktionerne i en grundlæggende IRQ:

void ND::IRQ::IRQ1()
{
asm volatile(
"cli \n"
"pushl 0\n"
"pushl 32\n"
"jmp ND_IRQ_Common"
);
}

En fælles del (samme som ISR):

extern "C"
void ND_IRQ_Common()
{
asm volatile(
"pusha \n"
"push %ds\n"
"push %es\n"
"push %fs\n"
"push %gs\n"
"movw $0x10, %ax \n"
"movw %ax, %ds \n"
"movw %ax, %es \n"
"movw %ax, %fs \n"
"movw %ax, %gs \n"
"movl %esp, %eax \n"
"push %eax \n"
"movl $ND_IRQ_Handler, %eax \n"
"call *%eax \n"
"popl %eax \n"
"popl %ds \n"
"popl %es \n"
"popl %fs \n"
"popl %gs \n"
"popa \n"
"addl 8, %esp \n"
"iret \n"
);
}

Og en grundlæggende handler:

extern "C"
void ND_IRQ_Handler(struct regs* r)
{
void (*handler)(struct regs *r);
if(r->int_no >= 40)
{
ND::Ports::OutputB(0xA0,0x20);
}
ND::Ports::OutputB(0x20,0x20);
}

Med dette skal vi allerede have IRQ aktiveret, selvom de stadig ikke gør noget. I det næste kapitel vil vi se, hvordan man får data fra disse IRQ'er, f.eks. Uret eller tastaturet.

NæsteDivel-IRQ


Og med dette slutter dagens indlæg. Som du kan se nu skriver jeg mindre regelmæssigt på grund af andre problemer. Alligevel fortsætter jeg, indtil jeg har et mere komplet operativsystem


22 kommentarer, lad dine

Efterlad din kommentar

Din e-mailadresse vil ikke blive offentliggjort. Obligatoriske felter er markeret med *

*

*

  1. Ansvarlig for dataene: Miguel Ángel Gatón
  2. Formålet med dataene: Control SPAM, management af kommentarer.
  3. Legitimering: Dit samtykke
  4. Kommunikation af dataene: Dataene vil ikke blive kommunikeret til tredjemand, undtagen ved juridisk forpligtelse.
  5. Datalagring: Database hostet af Occentus Networks (EU)
  6. Rettigheder: Du kan til enhver tid begrænse, gendanne og slette dine oplysninger.

  1.   aitor_cz sagde han

    Mange tak Adrian, så snart jeg har lidt tid (nu har jeg ret travlt, blandt andet også med et operativsystem), begynder jeg at teste vejledningen trin for trin.

  2.   Rubin sagde han

    Mange tak for tuten.

  3.   Sasuke sagde han

    Et spørgsmål, jeg laver et projekt baseret på disse programmeringssprog
    * HTML5
    * Css3
    * Java
    Mit spørgsmål er, at jeg gerne vil have, at dette projekt skal køres, så brugerne bruger det i operativsystemer som linux og windows, kan du fortælle mig, hvordan jeg gør det

    1.    AdrianArroyoStreet sagde han

      Det har intet at gøre med dette, men jeg svarer dig alligevel. Jeg antager, at det vil være HTML5, CSS3 og JavaScript ikke Java, da HTML5 og Java kommer fatalt sammen. Med HTML5 kan du oprette websteder som før, der er adgang til fra internettet. Hvis du vil gøre det lokalt, kan du pakke det som en Firefox OS- og Chrome OS-app. Hvis det, du ønsker, er, at der i hvert operativsystem er en eksekverbar kigge, så XUL Runner, som er et værktøj til at udføre XUL (og derfor HTML5 inde i elementet) med Gecko-motoren.

    2.    Soid perez sagde han

      Java-ramme eller -panel er en meget god mulighed. Jeg har oprettet nogle eksekverbare apps i vinduet ved hjælp af java-rammeklasser som en webbrowser, men i stedet for at bruge den til en hvilken som helst side giver jeg den en direkte sti i koden og med php udfører jeg java-sætninger gennem en .jar, der tager sig af stål. Selvom jeg vil anbefale at bruge HTML5, CSS3 og JavaScript, da Adrian Java siger, at det tager fatalt med HTML5, og det gav mig mange hovedpine

  4.   by sagde han

    En tutorial om, hvordan du laver dit eget programmeringssprog, ville være rart

  5.   Ivan sagde han

    Meget god denne serie af artikler om, hvordan man bygger et operativsystem, lærer man mange ting. Jeg ser frem til næste post, jeg vil allerede have et tastatur i operativsystemet. Jeg har rodet med git-koden, og jeg har ikke været i stand til at få den til at fungere med port 0x60 og 0x64. Selvom jeg troede, at der for tastaturet var en afbrydelse, der gav dig den trykte tast.

    1.    AdrianArroyoStreet sagde han

      Du kan faktisk få tastaturinput uden afbrydelse, men du skal læse med ND :: Porte :: InputB på port 0x60. Imidlertid er den ideelle måde at gøre dette på med IRQ-afbrydelser. Jeg prøver i øjeblikket at gøre det, og det tager lidt længere tid at fortsætte på grund af det.

      1.    carlosorta sagde han

        Hej Adrian, jeg har kontrolleret koden, og jeg er imponeret over, hvad den gør, og hvor godt det har hjulpet mig til at forstå nogle ting.

        Jeg har et par små spørgsmål om, hvordan det fungerer, og kilden er den, jeg fik fra din GIT:

        1.- I den del af IRQ'erne nævnte du, at positionerne fra 0 til 32 af IDT blev brugt til undtagelser og fra 32 (0x20) til 45 (0x2D) for IRQ'erne, men IRQ'erne er i alt 16, omlægning ville ikke være fra 0x20 til 0x30?

        2.- I IRQ-delen skal du bemærke, at du sendte sætgaterne til IDT-sektionen; Når du adskiller dem, skal du bemærke, at det ikke længere producerer undtagelsen for division med 0, så det er nødvendigt at tilføje IDT Flush () for hver ændring, der foretages. Hvorfor ændrer IDT sig, når Timer og division med 0 indstilles, holder op med at arbejde?

        3.- Jeg forsøgte at spore koden med noget udskrivning for at tage som en indikation af, hvad den udfører (for ikke at debugge trin for trin) og jeg indså, at ingen IRQ kører, skal jeg registrere noget andet til IRQ-afbrydelser genereres?

        1.    carlosorta sagde han

          Jeg glemte at nævne, at jeg fandt disse links med information:
          http://arstechnica.com/civis/viewtopic.php?f=20&t=899001
          http://www.superfrink.net/athenaeum/OS-FAQ/os-faq-pics.html
          http://orga2.exp.dc.uba.ar/data/downloads/clasespracticas/interrupciones2_clase_17.pdf
          http://www.intel-assembler.it/PORTALE/4/231468_8259A_PIC.pdf

          Til håndtering af IRQ'er er det tilsyneladende nødvendigt at tage højde for, hvilken type handler der anvendes, hvis, PIC, APIC, IOAPIC. . .etc. Er der en måde at udføre en dynamisk håndtering af IRQ på, eller har du brug for at prøve lykken?

  6.   carlosorta sagde han

    God eftermiddag Adrian.

    Jeg så, at jeg havde problemer med IRQ'erne, og det var derfor, koden ikke kunne avanceres, jeg tog en kopi af projektet og begyndte at analysere det; Jeg tilføjede en funktion til skærmtrykket for at udskrive reg-registreringer af struct reg på tidspunktet for afbrydelsen; Jeg fandt flere ting, blandt dem at en rekord kører, og jeg kan stadig ikke finde hvorfor; ændre Timer-afbrydelsen for tastaturafbrydelsen for at teste og gøre, hvad den skal, men jeg kan ikke finde problemet, kan du hjælpe mig og fortsætte med dette gode indlæg? 😀

    Jeg forlader linket (det har nogle ændringer, fordi jeg bruger Mageia, og jeg bruger Grub2, jeg bruger VirtualBox til at teste det)
    https://www.mediafire.com/?93psrgaoozatse8

    Venter på dit opmærksomme svar, og hvis du har spørgsmål eller har brug for noget, vil jeg gerne hjælpe 🙂

    1.    carlosorta sagde han

      Jeg glemte at nævne, at jeg også tjekkede KernelPanic, fordi ISR'erne ikke fungerede, og jeg har det samme problem øverst i stakken, en værdi filtreres, og jeg ved ikke, om det er min kompilator, eller om der er et problem, jeg brug GCC 4.8.2 med Mageia 4

    2.    AdrianArroyoStreet sagde han

      Jeg kan virkelig godt lide, at du hjælper mig med projektet. Jeg sidder virkelig fast i timeren, og jeg forstår ikke, hvorfor det ikke virker. Jeg lavede tests, der ændrede en hel del ting, og det gik ikke. I øjeblikket kan jeg ikke redigere kode (jeg er på ferie væk), men jeg vil se godt på den, så snart jeg kan. Jeg giver dig et link med oplysninger om dette problem, der ser ud til at være noget almindeligt: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Med hensyn til undtagelserne tror jeg, at jeg husker, at du skal ringe til "sti" i ASM for at aktivere dem, selvom det er klart, at der er noget galt et eller andet sted.

      1.    carlosorta sagde han

        Tak for dit svar og ja. Afbrydelserne mislykkedes, men det var et problem at indsætte koder i stakken og et castingsproblem, jeg vil kontrollere linket og lave test. Hvis jeg løser det, giver jeg dig besked, og hvis ikke, vil jeg informere dig om fremskridt. Tillykke med ferien 🙂

      2.    carlosorta sagde han

        Der vil ikke være nogen måde at se den samlede kode på? Er der noget underligt, og jeg kan ikke finde hvad? Se på dette skærmbillede (jeg sætter linket i slutningen), det er noget underligt, da i IRQ 2-funktionen (tastaturet ) indtaster den stakken værdien 0 og 0x20 (32, så pas den til at teste) derefter pushal (32-bit GPR-registre) efterfulgt af segmenteringsregistrene og derefter toppen af ​​stakken og derefter ringe til IRQ Handler. Jeg begyndte at se hver stak, og tilsyneladende er den i rækkefølgen, men hvis du kan se output fra VM, kan du se, at den stabler et element mere, jeg kan ikke finde hvor, jeg ved kun, at det er en 0x10 og strukturen falder fra hinanden. Dette er rekordstrukturen.

        struct regs {
        uint32_t gs, fs, es, ds; / * skubbede sekunderne sidst * /
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * skubbet af 'pushal' * /
        uint32_t int_no, err_code; /* Fejlkode */
        uint32_t eip, cs, eflags, useresp, ss; / * Stablet på pause * /
        };

        Det generer mig, at det sætter endnu et element øverst, og jeg kan ikke finde, hvor det er stablet, hvis alt tilsyneladende er stablet, som det skulle være. Har du nogen idé om, hvad det kan være?

        http://www.subeimagenes.com/img/sin-titulo-1036729.jpg

  7.   carlosorta sagde han

    Få tastaturafbrydelsen til at fungere, men ikke timeafbrydelsen; fejlen var i den måde, den blev kompileret på, jeg brugte objdump til at se det endelige objekt, og det viste sig, at hver funktion, der blev indtastet, selv ved hjælp af "asm flygtig", også var ledsaget af en pushl ebp, mov ebp, esp. Derefter skal du blot tilføje en ebp-popl til den for at gendanne den indledende stak, og den vil passere argumenterne uden fejl. Her vedhæfter jeg koden for dem, der ønsker at kontrollere den, og hvis du kan finde ud af, hvorfor afbrydelsen ikke genereres af timeren, vil jeg meget gerne vide det, og jeg vedhæfter et link, hvor de taler om multitasking http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Næste Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyoStreet sagde han

      Jeg har det. Det var en fejl på et andet sted, der påvirkede aktiveringen af ​​Timer PIC, specifikt i IRQ-omlægningen var der to linjer, som jeg var nødt til at ændre. Takket være det faktum, at jeg kunne se en kode på et websted, der på det tidspunkt havde noget andet og klik! Ændringen var i retning af:
      ND :: Porte :: OutputB (PIC1 + 1, 0xFF);
      ND :: Porte :: OutputB (PIC2 + 1, 0xFF);

      Du var nødt til at ændre værdien af ​​0xFF (jeg vil sige, at det angiver deaktiveret) til 0x00 (jeg vil sige, at det angiver aktiveret), selvom jeg ikke er helt sikker, men det virker. Jeg har opdateret koden på GitHub. Mange tak, fordi du hjalp mig med det projekt, som jeg havde lidt forladt på grund af dette problem. H

      1.    carlosorta sagde han

        Du er velkommen, jeg ser frem til den næste opdatering om emnet, og du kan stole på mig for hvad som helst 🙂 (Y)

      2.    carlosorta sagde han

        Ændre tastaturstrengfangningsrutinen fordi den læser, når nøglen frigives, og den monterer et 0 i bufferen, der giver problemer i læsningen, og i slutningen ændrer '\ n' den til », så den korrekte udskrivning fungerer

  8.   Soid perez sagde han

    Hej, jeg læste hele dit indlæg, selvom det i praksis ikke er mere end 2 indlæg, det er virkelig meget godt, gem alt, men jeg bliver virkelig nødt til at studere c ++ og posix for at forstå det, fordi jeg kender til "c" (Jeg er fascineret af dette programmeringssprog), men selvom c ++ er c OO, har jeg aldrig rigtig arbejdet med det, læs mig nogle tutorials på google, og så returnerer jeg dette meget interessant og et spørgsmål, ligner opstart af vindue Linux

    1.    AdrianArroyoStreet sagde han

      Opstart i Windows er ens i den forstand, at dette er måden at starte et system med en x86-processor, og operativsystemet, der er bygget på det, har ringe indflydelse. Vi starter ikke rigtig meget selv, det starter GRUB for os. GRUB, designet til at starte Linux, kan starte Windows og i dette tilfælde NextDivel.

      1.    fast sagde han

        ok tak, det betyder, at det, jeg vil gøre, er muligt, jeg studerer allerede c ++, og jeg har oprettet nogle apps og installeret dit system på en pendrive, og jeg studerer det mere detaljeret.