Lino Torvaldso mėgdžiojimas: sukurkite savo operacinę sistemą nuo nulio (VI)

Na, o po trumpos pertraukėlės tęsiame savo pamokų seriją. Jei grįšime prie ankstesnio kodo, turime turėti padalijimo iš nulio ISR. Dabar turime užpildyti likusius ISR, dėl kurių įdėjome pranešimą (pirmieji 32). Na, dabar mes tęsime programavimo trikdžius, darysime IRQ, taip pat žinomus kaip Pertraukia prašymus. Šiuos IRQ generuoja aparatūros įrenginiai, tokie kaip klaviatūros, pelės, spausdintuvai ir kt. Iš pradžių pirmieji 8 IRQ automatiškai susiejami su IDT pozicijomis nuo 8 iki 15. Kadangi pirmąsias 32 panaudojome išimtims, dabar turime jas perdaryti. IRQ nustatysime nuo 32 iki 45. Norėdami tai padaryti, pirmiausia turime perdaryti 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);
}

Dabar sukuriame IRQ įdiegimo funkciją:

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

Asm sakinys VMI Tai suaktyvina mūsų IRQ. Na, dabar pereikime prie kažko panašaus į ISR. Pagrindinės IRQ funkcijos:

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

Bendra dalis (ta pati kaip 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"
);
}

Ir pagrindinis prižiūrėtojas:

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

Turėtume suaktyvinti IRQ, net jei jie vis tiek nieko nedaro. Kitame skyriuje pamatysime, kaip gauti duomenis iš šių IRQ, pvz., laikrodžio ar klaviatūros.

KitasDivel-IRQ


Ir tuo šios dienos įrašas baigiasi. Kaip matėte, dabar rašau rečiau dėl kitų problemų. Nepaisant to, tęsiu tol, kol turėsiu pilnesnę operacinę sistemą


Palikite komentarą

Jūsų elektroninio pašto adresas nebus skelbiamas. Privalomi laukai yra pažymėti *

*

*

  1. Atsakingas už duomenis: Miguel Ángel Gatón
  2. Duomenų paskirtis: kontroliuoti šlamštą, komentarų valdymą.
  3. Įteisinimas: jūsų sutikimas
  4. Duomenų perdavimas: Duomenys nebus perduoti trečiosioms šalims, išskyrus teisinius įsipareigojimus.
  5. Duomenų saugojimas: „Occentus Networks“ (ES) talpinama duomenų bazė
  6. Teisės: bet kuriuo metu galite apriboti, atkurti ir ištrinti savo informaciją.

  1.   aitor_cz sakė

    Labai ačiū, Adrianai, kai tik turėsiu laiko (dabar esu gana užsiėmęs, be kita ko, ir su operacine sistema) žingsnis po žingsnio išbandysiu pamoką.

  2.   rubinas sakė

    Labai ačiū už paskaitą.

  3.   Sasuke sakė

    Vienas klausimas, aš darau projektą, pagrįstą šiomis programavimo kalbomis.
    * HTML5
    * Css3
    *Java
    Mano klausimas: norėčiau, kad šis projektas būtų vykdomas, kad vartotojai galėtų jį naudoti tokiose operacinėse sistemose kaip „Linux“ ir „Windows“. Ar galėtumėte man pasakyti, kaip tai padaryti?

    1.    AdrianArroyo gatvė sakė

      Tai neturi nieko bendro su tuo, bet aš jums atsakysiu. Manau, kad tai bus HTML5, CSS3 ir „JavaScript“, o ne „Java“, nes HTML5 ir „Java“ sutaria siaubingai. Naudodami HTML5 galite kaip anksčiau kurti svetaines, kurias galima pasiekti iš interneto. Jei norite, kad jis būtų vietinis, galite jį supakuoti kaip „Firefox“ OS ir „Chrome“ OS programą. Jei norite, kad kiekviena operacinė sistema turėtų vykdomąjį failą, pažiūrėkite į XUL Runner, kuris yra įrankis, skirtas paleisti XUL (taigi ir HTML5 elemente) su Gecko varikliu.

    2.    Venkite perezo sakė

      Java rėmelis arba skydelis yra labai geras pasirinkimas. Sukūriau kai kurias vykdomąsias programas lange, naudodamas java rėmelių klases kaip žiniatinklio naršyklę, bet užuot naudojęs bet kokiam puslapiui, suteikiu tiesioginį kelią kode ir su php vykdau java pareiškimus per .jar, kuris yra atsakingas už tai. Nors aš rekomenduočiau naudoti HTML5, CSS3 ir JavaScript, nes, kaip sako Adrianas, Java yra baisi su HTML5 ir man sukėlė daug galvos skausmo.

  4.   luban sakė

    Būtų puiku pamoka, kaip sukurti savo programavimo kalbą.

  5.   Ivanas sakė

    Ši straipsnių serija apie tai, kaip sukurti operacinę sistemą, yra labai gera, sužinosite daug dalykų. Nekantriai laukiu kito įrašo, jau laukiu, kada OS turėsiu klaviatūrą. Netvarkau su git kodu ir nepavyko jo priversti veikti su prievadais 0x60 ir 0x64. Nors maniau, kad klaviatūroje įvyko pertrauka, dėl kurios paspaudėte klavišą.

    1.    AdrianArroyo gatvė sakė

      Iš tikrųjų galite gauti klaviatūros įvestį be pertrūkių, bet turite skaityti naudodami ND::Ports::InputB prie 0x60 prievado. Tačiau idealus būdas tai padaryti yra IRQ pertraukimai. Šiuo metu bandau tai padaryti ir dėl to man užtrunka šiek tiek ilgiau.

      1.    Carlosorta sakė

        Sveiki, Adrianai, aš tikrinau kodą ir esu sužavėtas tuo, ką jis daro ir kaip jis padėjo man suprasti kai kuriuos dalykus.

        Turiu keletą nedidelių klausimų apie tai, kaip tai veikia, o šaltinis yra tas, kurį gavau iš jūsų GIT:

        1.- IRQ dalyje minėjote, kad IDT pozicijos nuo 0 iki 32 buvo naudojamos išimtims ir nuo 32 (0x20) iki 45 (0x2D) IRQ, tačiau iš viso IRQ yra 16. būti nuo 0x20 iki 0x30?

        2.- IRQ dalyje atkreipkite dėmesį, kad išsiuntėte setgates į IDT skyrių; Kai juos atskyriau, pastebėjau, kad jis nebegamina padalijimo iš 0 išimties, todėl reikia pridėti IDT Flush() prie kiekvienos modifikacijos. Kodėl IDT pasikeičia nustatant laikmatį ir dalijimas iš 0 nustoja veikti?

        3.- Bandžiau atsekti kodą su tam tikru įspūdžiu, kad būtų parodyta, ką jis vykdo (kad nederinčiau žingsnis po žingsnio) ir supratau, kad joks IRQ neveikia. Ar turiu dar ką nors užregistruoti kad generuojami IRQ pertraukimai?

        1.    Carlosorta sakė

          Pamiršau paminėti, kad radau šias nuorodas su informacija:
          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

          Matyt, norint valdyti IRQ, reikia atsižvelgti į tai, kokio tipo tvarkytuvas naudojamas, PIC, APIC, IOAPIC. . .tt Ar yra būdas dinamiškai valdyti IRQ, ar reikia išbandyti savo laimę?

  6.   Carlosorta sakė

    Laba diena Adrian.

    Pamačiau, kad turiu problemų su IRQ ir dėl to negalėjau pereiti prie kodo, pasiėmiau projekto kopiją ir pradėjau jį analizuoti; Prie ekrano spausdinimo pridėjau funkciją, leidžiančią spausdinti struct reg įrašus, kai daroma pertrauka; Radau keletą dalykų, tarp jų, kad veikia registras ir vis tiek nerandu priežasties; Pakeičiau laikmačio pertraukimą į klaviatūros pertraukimą, kad išbandyčiau ir jis daro tai, ką turėtų, bet nerandu problemos. Ar galėtumėte man padėti ir tęsti šį gerą įrašą? 😀

    Palieku jums nuorodą (jis turi tam tikrų modifikacijų, nes naudoju Mageia ir Grub2, išbandymui naudoju VirtualBox)
    https://www.mediafire.com/?93psrgaoozatse8

    Lauksiu jūsų dėmesingo atsakymo ir jei turite klausimų ar ko nors reikia, mielai padėsiu 🙂

    1.    Carlosorta sakė

      Pamiršau paminėti, kad taip pat patikrinau „KernelPanic“, nes ISR neveikė ir turiu tą pačią problemą krūvos viršuje, slysta reikšmė ir aš nežinau, ar tai mano kompiliatorius, ar tiesiog yra problema , Aš naudoju GCC 4.8.2 su Mageia 4

    2.    AdrianArroyo gatvė sakė

      Labai džiaugiuosi, kad padedate man įgyvendinti projektą. Tikrai įstrigo laikmatis ir nesuprantu, kodėl jis neveikia. Bandžiau pakeisti nemažai dalykų ir nepavyko. Šiuo metu negaliu redaguoti kodo (esu išvykęs atostogų), bet kai tik galėsiu, gerai jį apžiūrėsiu. Pateiksiu nuorodą su informacija apie šią problemą, kuri, matyt, dažna: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Dėl išimčių, atrodo, pamenu, kad norint jas suaktyvinti reikia skambinti į "sti" ASM, nors aišku, kad kažkas negerai.

      1.    Carlosorta sakė

        Ačiū už atsakymą ir tikrai taip. Pertraukimai nepavyko, bet kilo problemų įterpiant kodus į krūvą ir perdavimo problema. Aš patikrinsiu nuorodą ir išbandysiu. Jei išspręsiu, pranešiu jums, o jei ne, informuosiu apie pažangą. Linksmų švenčių 🙂

      2.    Carlosorta sakė

        Niekaip nematote surinkto kodo? Kažkas keisto vyksta ir nerandu kas? Pažiūrėkite į šį ekraną (nuorodą įdėjau gale), tai kažkas keisto, nes IRQ 2 funkcijoje (klaviatūra) jis įdeda į krūvą reikšmes 0 ir 0x20 (32, todėl sudėliojau ją bandymui), tada stumia ją (32 bitų GPR registrus), tada segmentavimo registrus ir krūvos viršų, tada iškviečia IRQ tvarkyklę. Aš pradėjau matyti kiekvieną krūvą ir, matyt, yra tokia tvarka, bet jei galite stebėti VM išvestį, pamatysite, kad ji sukrauna dar vieną elementą, nerandu kur, žinau tik, kad tai yra 0x10 ir struktūra netvarkinga. Tai yra įrašo struktūra.

        struct regs{
        uint32_t gs, fs, es, ds; /* nustūmė paskutines sekundes */
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* nustumtas 'pushal' */
        uint32_t int_no, err_code; /* Klaidos kodas */
        uint32_t eip, cs, vėliavėlės, useresp, ss; /* Sukrauta pertraukus */
        };

        Mane trukdo, kad dar vieną elementą deda į viršų ir nerandu, kur jis susidėlioja, jei, matyt, viskas sukrauta taip, kaip turėtų būti. Ar žinote, kas tai galėtų būti?

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

  7.   Carlosorta sakė

    Gavau klaviatūros pertraukimą, bet ne laikmatį; Klaida buvo kompiliavimo būdu, aš naudojau objdump, kad pamatyčiau galutinį objektą ir paaiškėjo, kad kiekviena funkcija, kuri buvo įvesta net naudojant "asm volatile", taip pat buvo kartu su pushl ebp, mov ebp, esp. Tada tiesiog pridėkite popl ebp, kad atkurtumėte pradinį krūvą ir argumentai bus perduoti be klaidų. Čia pridedu kodą tiems, kurie nori jį patikrinti ir jei galite sužinoti, kodėl trukdžių negeneruoja laikmatis, norėčiau sužinoti ir pridedu nuorodą, kur jie kalba apie daugiafunkcinį darbą http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Kitas nardymas
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyo gatvė sakė

      Supratau. Tai buvo klaida kitur, turėjusi įtakos laikmačio PIC aktyvavimui, konkrečiai IRQ pertvarkyme buvo dvi eilutės, kurias turėjau modifikuoti. Dėl to, kad svetainėje galėjau pamatyti kodą, kuriame tuo metu buvo kažkas kitokio, ir oho! Pakeitimas buvo toks:
      ND::Privadai::IšvestisB(PIC1 + 1, 0xFF);
      ND::Privadai::IšvestisB(PIC2 + 1, 0xFF);

      Turėjote pakeisti reikšmę iš 0xFF (sakyčiau, kad tai rodo išjungtą) į 0x00 (sakyčiau, kad tai rodo įjungtą), nors aš nesu tikras, bet tai veikia. Atnaujinau kodą „GitHub“. Labai, labai ačiū, kad padėjote man įgyvendinti projektą, kurį šiek tiek apleidau dėl šios problemos. h

      1.    Carlosorta sakė

        Sveiki, lauksiu kito atnaujinimo šia tema ir galite manimi pasikliauti viskuo 🙂 (Y)

      2.    Carlosorta sakė

        Keisti klaviatūros eilutės fiksavimo tvarką; nes jis skaito, kai atleidžiate klavišą ir buferyje sukuria 0, todėl kyla problemų skaitant ir pabaigoje pakeiskite '\n' į », kad veiktų teisingas spausdinimas

  8.   Venkite perezo sakė

    sveiki, perskaiciau visa tavo posta, nors praktikoje neeinu toliau nei 2 postai, tikrai labai gerai, issaugojau viska, bet man tikrai reikes mokytis c++ ir posix, kad galeciau suprasti nes zinau "c" (esu sužavėta ta programavimo kalba) bet nors c++ yra c OO, aš niekada su ja nedirbau. Perskaičiau keletą vadovėlių Google ir grįžau. Tai labai įdomu ir kyla klausimas: ar "Windows" paleidimas panašus į Linux?

    1.    AdrianArroyo gatvė sakė

      „Windows“ paleidimas yra panašus ta prasme, kad tokiu būdu galima paleisti sistemą su x86 procesoriumi, o ant jo sukurta operacinė sistema turi mažai įtakos. Šiaip mes tikrai nesikrauname, už mus paleidžia GRUB. GRUB, skirtas paleisti Linux, gali paleisti Windows ir šiuo atveju NextDivel.

      1.    kietas sakė

        gerai, ačiū, tai reiškia, kad tai, ką aš noriu padaryti, yra įmanoma Aš jau studijuoju c++ ir sukūriau keletą programų, įdiegiau jūsų sistemą į diską ir tyrinėju ją išsamiau, tai labai geras įrašas