Posnemanje Linusa Torvaldsa: ustvarite svoj operacijski sistem iz nič (VI)

No, po majhnih oklepajih nadaljujemo z našo serijo vaj. Če se vrnemo na prejšnjo kodo, moramo imeti ISR ​​delitve z ničlo. Zdaj moramo izpolniti preostale ISR-je, za katere smo objavili sporočilo (prvih 32). No, zdaj bomo nadaljevali s programskimi prekinitvami, naredili bomo IRQ, znan tudi kot Prekine zahteve. Te IRQ generirajo strojne naprave, kot so tipkovnice, miške, tiskalniki itd. Sprva se prvih 8 IRQ samodejno preslika v položaje IDT 8-15, ker smo prvih 32 uporabili za izjeme, jih moramo zdaj preslikati. IRQ bomo postavili z 32 na 45. Za to moramo najprej preslikati IRQ:

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);
}

Zdaj ustvarimo funkcijo za namestitev IRQ-jev:

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");
}

Stavek asm sti aktiviramo IRQ-je. No, zdaj gremo z nečim podobnim ISR. Funkcije osnovnega IRQ:

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

Skupni del (enako kot 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"
);
}

In osnovni vodnik:

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);
}

S tem bi morali imeti že aktiviran IRQ, tudi če še vedno ne naredijo ničesar. V naslednjem poglavju bomo videli, kako pridobiti podatke iz teh IRQ-jev, na primer uro ali tipkovnico.

NextDivel-IRQ


In s tem se konča današnja objava. Kot lahko vidite, zaradi drugih težav pišem manj redno. Kljub temu bom nadaljeval, dokler ne dobim popolnejšega operacijskega sistema


Pustite svoj komentar

Vaš e-naslov ne bo objavljen. Obvezna polja so označena z *

*

*

  1. Za podatke odgovoren: Miguel Ángel Gatón
  2. Namen podatkov: Nadzor neželene pošte, upravljanje komentarjev.
  3. Legitimacija: Vaše soglasje
  4. Sporočanje podatkov: Podatki se ne bodo posredovali tretjim osebam, razen po zakonski obveznosti.
  5. Shranjevanje podatkov: Zbirka podatkov, ki jo gosti Occentus Networks (EU)
  6. Pravice: Kadar koli lahko omejite, obnovite in izbrišete svoje podatke.

  1.   aitor_cz je dejal

    Najlepša hvala, Adrian, takoj ko bom imel nekaj časa (zdaj sem precej zaposlen, med drugim tudi z operacijskim sistemom), bom začel vadnico preizkušati korak za korakom.

  2.   Ruby je dejal

    Najlepša hvala za tute.

  3.   Sasuke je dejal

    Eno vprašanje je, da delam projekt, ki temelji na teh programskih jezikih
    * Html5
    * Css3
    * Java
    Moje vprašanje je, da bi rad, da je ta projekt izvedljiv, da bi ga uporabniki lahko uporabljali v operacijskih sistemih, kot sta linux in Windows, ali bi mi lahko povedali, kako to počnem

    1.    AdrianArroyoStreet je dejal

      S tem nima nič skupnega, vendar vam vseeno odgovorim. Predvidevam, da bo HTML5, CSS3 in JavaScript in ne Java, saj se HTML5 in Java usodno razumeta. Z HTML5 lahko ustvarite spletna mesta, kot prej, do katerih dostopate iz interneta. Če ga želite narediti lokalnega, ga lahko zapakirate kot aplikacijo Firefox OS in Chrome OS. Če želite, da je v vsakem operacijskem sistemu izvedljiva datoteka, si oglejte XUL Runner, ki je orodje za izvajanje XUL (in s tem HTML5 znotraj elementa) z mehanizmom Gecko.

    2.    Soid perez je dejal

      Okvir ali podokno Java je zelo dobra možnost. V oknu sem ustvaril nekaj izvršljivih aplikacij z uporabo razredov java frame kot spletnega brskalnika, vendar namesto da bi jih uporabil za katero koli stran, mu dam direktno pot v kodo in s php izvajam stavke Java skozi .jar, ki skrbi za jeklo. Čeprav bi priporočal uporabo HTML5, CSS3 in JavaScript, saj Adrian Java pravi, da je Html5 potreben Fatal in mi je povzročil veliko preglavic

  4.   mestni je dejal

    Lepo bi bilo, kako narediti svoj programski jezik

  5.   Ivan je dejal

    Zelo dobro v tej seriji člankov o tem, kako zgraditi operacijski sistem, se naučite marsičesa. Veselim se naslednjega vnosa, v OS že želim imeti tipkovnico. Zelo sem se zafrkaval s kodo git in mi ni uspelo, da bi delal z vrati 0x60 in 0x64. Čeprav sem mislil, da je pri tipkovnici prišlo do prekinitve, zaradi katere ste pritisnili tipko.

    1.    AdrianArroyoStreet je dejal

      Vnos tipkovnice lahko dejansko dobite brez prekinitve, vendar morate brati z ND :: Ports :: InputB na vratih 0x60. Vendar je idealen način za to z IRQ prekinitvami. Trenutno to poskušam narediti in zaradi tega traja malo dlje.

      1.    karlosorta je dejal

        Živijo, Adrian, preverjal sem kodo in navdušen sem nad tem, kako deluje in kako dobro mi je pomagalo razumeti nekatere stvari.

        Imam nekaj majhnih vprašanj o tem, kako deluje, in vir je tisti, ki sem ga dobil iz vašega GIT:

        1. - V delu IRQ ste omenili, da so bili položaji od 0 do 32 IDT uporabljeni za izjeme in od 32 (0x20) do 45 (0x2D) za IRQ, vendar je IRQ skupaj 16, remapiranje ne bi bilo od 0x20 do 0x30?

        2. - V delu IRQ upoštevajte, da so bili predlogi poslani v oddelek IDT; Ko jih ločite, upoštevajte, da ne povzroča več izjeme deljenja z 0, zato je treba dodati IDT Flush () za vsako izvedeno spremembo. Zakaj se IDT spremeni pri nastavitvi časovnika in delitev med 0 preneha delovati?

        3. - Poskušal sem izslediti kodo z nekaj tiskanja, da bi bil vzorec, kaj izvaja, (da ne bi odpravljal napak po korakih) in ugotovil sem, da se IRQ ne izvaja, ali moram registrirati kaj drugega do ustvarjenih prekinitev IRQ?

        1.    karlosorta je dejal

          Pozabil sem omeniti, da sem našel te povezave z informacijami:
          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

          Očitno je treba pri ravnanju z IRQ upoštevati, kakšen tip vodnika se uporablja, če PIC, APIC, IOAPIC. . itd. Ali obstaja način, kako narediti dinamiko upravljanja IRQ ali morate poskusiti srečo?

  6.   karlosorta je dejal

    Dober dan Adrian.

    Videl sem, da imam težave z IRQ-ji in zato kode ni bilo mogoče napredovati, vzel sem kopijo projekta in ga začel analizirati; Sitotisku sem dodal funkcijo za tiskanje reg zapisov struct reg v času prekinitve; Našel sem več stvari, med njimi je, da plošča teče in še vedno ne najdem, zakaj; spremenite prekinitev časovnika, da prekinitev tipkovnice preizkusite in naredite, kar bi morala, vendar ne najdem težave, mi lahko pomagate in nadaljujete s to dobro objavo 😀

    Povezavo zapustim (ima nekaj sprememb, ker uporabljam Mageio in Grub2, za preskušanje uporabljam VirtualBox)
    https://www.mediafire.com/?93psrgaoozatse8

    Čakam na vaš pozoren odgovor in če imate kakršna koli vprašanja ali kaj potrebujete, bi rad pomagal 🙂

    1.    karlosorta je dejal

      Pozabil sem omeniti, da sem preveril tudi KernelPanic, ker ISR-ji niso delovali in imam isti problem na vrhu sklada, da se vrednost filtrira in ne vem, ali je to moj prevajalnik ali obstaja težava, uporabite GCC 4.8.2 z Mageia 4

    2.    AdrianArroyoStreet je dejal

      Zelo mi je všeč, da mi pomagate pri projektu. Res sem se zataknil v časovniku in ne razumem, zakaj ne deluje. Naredil sem teste, ki so spreminjali kar nekaj stvari in se ni izšlo. Trenutno ne morem urejati kode (na dopustu sem), vendar jo bom takoj dobro pregledal. Dajem vam povezavo z informacijami o tej težavi, ki se zdi nekaj običajnega: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Glede izjem se zdi, da se spomnim, da morate v ASM poklicati "sti", da jih aktivirate, čeprav je jasno, da je nekje kaj narobe.

      1.    karlosorta je dejal

        Hvala za vaš odgovor in ja, res. Prekinitve niso uspele, vendar je prišlo do težave pri vstavljanju kod v sklad in težava z oddajanjem, preveril bom povezavo in naredil teste. Če ga rešim, vas obvestim, v nasprotnem primeru pa vas obvestim o napredku. Lepe praznike 🙂

      2.    karlosorta je dejal

        Zbrane kode ne bo mogoče videti? Se kaj čudnega dogaja in ne najdem česa? Poglejte ta zaslon (na koncu dam povezavo), nekaj čudnega je, saj je v funkciji IRQ 2 (tipkovnica ) v sklad vnese vrednost 0 in 0x20 (32, tako da ga prilagodite preizkusu), nato pushal (32-bitni GPR registri), ki mu sledijo segmentacijski registri in nato vrh sklada ter nato pokličete IRQ Handler. Začel sem videti vsak sklad in očitno je v redu, če pa vidiš izhodne podatke VM-a, lahko vidiš, da vsebuje še en element, ne najdem kam, vem samo, da je 0x10 in struktura pride iz reda. To je struktura zapisa.

        struct regs {
        uint32_t gs, fs, es, ds; / * zadnji potisnil sekunde * /
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * potisnil 'pushal' * /
        uint32_t int_no, koda napake; /* Napačna koda */
        uint32_t eip, cs, eflags, useresp, ss; / * Zloženo na odmor * /
        };

        Daje mi pločevinko, ki postavi še en element na vrh in ne najdem, kje je zložen, če je očitno vse zloženo tako, kot bi moralo biti. Imate kakšno idejo, kaj bi to lahko bilo?

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

  7.   karlosorta je dejal

    Prekinitev tipkovnice naj deluje, ne pa tudi prekinitve časovnika; napaka je bila v načinu prevajanja, z objdumpom sem videl končni objekt in izkazalo se je, da je vsako funkcijo, ki je bila vnesena tudi z uporabo "asm volatile", spremljal tudi pushl ebp, mov ebp, esp. Nato mu preprosto dodajte ebp popl, da obnovite začetni sklad, in argumente bo brez težav prenesel. Tukaj prilagam kodo za tiste, ki jo želijo preveriti in če lahko ugotovite, zakaj prekinitve ne ustvarja časovnik, bi jo rad vedel in priložim povezavo, kjer govorijo o večopravilnosti http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Naslednji potop
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyoStreet je dejal

      Razumem. To je bila napaka na drugem mestu, ki je vplivala na aktivacijo časovnika PIC, natančneje v remapu IRQ sta bili dve vrstici, ki sem ju moral spremeniti. Zahvaljujoč dejstvu, da sem na spletnem mestu videl kodo, ki je takrat imela nekaj drugega, in kliknila! Sprememba je sledila:
      ND :: Vrata :: IzhodB (PIC1 + 1, 0xFF);
      ND :: Vrata :: IzhodB (PIC2 + 1, 0xFF);

      Morali ste spremeniti vrednost 0xFF (rekel bi, da pomeni onemogočeno) na 0x00 (rekel bi, da pomeni omogočeno), čeprav v resnici nisem prepričan, vendar deluje. Kodo sem posodobil na GitHubu. Najlepša hvala, ker ste mi pomagali pri projektu, ki sem ga zaradi te težave nekoliko opustil. H

      1.    karlosorta je dejal

        Vabljeni, veselim se naslednje posodobitve na temo in na mene lahko računate kar koli 🙂 (Y)

      2.    karlosorta je dejal

        Spremenite rutino zajemanja nizov tipkovnice; ker bere ob sprostitvi ključa in v odbojnik namesti 0, kar povzroča težave pri branju in na koncu '\ n' spremeni v », tako da deluje pravilno tiskanje

  8.   Soid perez je dejal

    Pozdravljeni, prebral sem celotno vašo objavo, čeprav v praksi ne gre za več kot 2 objavi, je res zelo dobro, shranite vse, vendar bom resnično moral preučiti c ++ in posix, da jo razumem, ker vem o " c "(navdušen sem nad tem programskim jezikom), toda čeprav je c ++ c OO, nisem nikoli zares delal, preberite mi nekaj vadnic v Googlu in nato vrnem to zelo zanimivo in vprašanje, ali je zagon okna podoben linux?

    1.    AdrianArroyoStreet je dejal

      Zagon v operacijskem sistemu Windows je podoben v smislu, da je to način za zagon sistema s procesorjem x86 in operacijski sistem, zgrajen na njem, nima velikega vpliva. V resnici se vseeno ne zaganjamo, za nas se začenja GRUB. GRUB, zasnovan za zagon Linuxa, lahko zažene Windows in v tem primeru NextDivel.

      1.    zvok je dejal

        v redu, hvala, to pomeni, da je to, kar želim narediti, mogoče. Že preučujem c ++ in ustvaril sem nekaj aplikacij ter vaš sistem namestil na pendrive in ga podrobneje preučujem, zelo dobra objava