Oponašanje Linusa Torvaldsa: Stvorite svoj vlastiti operativni sistem od nule (VI)

Pa, nakon malo zagrade nastavljamo s našom serijom vodiča. Ako se vratimo na prethodni kod, moramo imati ISR ​​podjele s nulom. Sada moramo popuniti ostatak ISR-ova za koje smo poslali poruku (prvih 32). E sad, nastavit ćemo s prekidima programiranja, izradit ćemo IRQ-ove poznate i kao Prekida zahtjeve. Ove IRQ-ove generiraju hardverski uređaji kao što su tastature, miševi, štampači itd. U početku se prvih 8 IRQ-a automatski preslikava na IDT pozicije 8-15. Budući da smo koristili prvih 32 za izuzetke, sada ih moramo preslikati. IRQ ćemo postaviti sa 32 na 45. Za to prvo moramo preslikati IRQ-ove:

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

Sada kreiramo funkciju za instaliranje IRQ-ova:

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

Rečenica asm sti aktiviramo IRQ-ove. Pa sad idemo s nečim sličnim ISR-u. Funkcije osnovnog IRQ-a:

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

Zajednički dio (isti kao 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"
);
}

I osnovni rukovatelj:

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 ovim bismo već trebali aktivirati IRQ čak i ako još uvijek ništa ne rade. U sljedećem poglavlju vidjet ćemo kako dobiti podatke iz ovih IRQ-ova, poput sata ili tipkovnice.

NextDivel-IRQ
I ovim završava današnji post. Kao što vidite, pišem rjeđe zbog drugih problema. Čak i tako ću nastaviti dok ne budem imao potpuniji operativni sistem


Sadržaj članka pridržava se naših principa urednička etika. Da biste prijavili grešku, kliknite ovdje.

22 komentara, ostavi svoj

Ostavite komentar

Vaša e-mail adresa neće biti objavljena. Obavezna polja su označena sa *

*

*

  1. Za podatke odgovoran: Miguel Ángel Gatón
  2. Svrha podataka: Kontrola neželjene pošte, upravljanje komentarima.
  3. Legitimacija: Vaš pristanak
  4. Komunikacija podataka: Podaci se neće dostavljati trećim stranama, osim po zakonskoj obavezi.
  5. Pohrana podataka: Baza podataka koju hostuje Occentus Networks (EU)
  6. Prava: U bilo kojem trenutku možete ograničiti, oporaviti i izbrisati svoje podatke.

  1.   aitor_cz rekao je

    Puno vam hvala, Adrian, čim budem imao vremena (sada sam poprilično zauzet, između ostalog i operativnim sistemom), započet ću s testiranjem vodiča korak po korak.

  2.   Rubin rekao je

    Puno vam hvala na tuti.

  3.   sasuke rekao je

    Jedno pitanje radim projekat zasnovan na tim programskim jezicima
    * Html5
    * Css3
    * Java
    Moje pitanje je da bih volio da ovaj projekat bude izvršan, tako da ga korisnici mogu koristiti u operativnim sistemima kao što su linux i windows, možete li mi reći kako to radim

    1.    AdrianArroyoStreet rekao je

      To nema nikakve veze s ovim, ali svejedno vam odgovaram. Pretpostavljam da će to biti HTML5, CSS3 i JavaScript, a ne Java, jer se HTML5 i Java kobno slažu. Pomoću HTML5 možete kreirati web lokacije kao i prije kojima se pristupa s Interneta. Ako ga želite učiniti lokalnim, možete ga spakirati kao Firefox OS i Chrome OS aplikaciju. Ako želite da u svakom operativnom sistemu postoji izvršna datoteka, pogledajte XUL Runner koji je alat za izvršavanje XUL-a (i stoga HTML5 unutar elementa) sa Gecko motorom.

    2.    Soid perez rekao je

      Java okvir ili panel su vrlo dobra opcija Stvorio sam neke izvršne aplikacije u prozoru koristeći klase java okvira kao web pretraživač, ali umjesto da ih koristim za bilo koju stranicu, dajem mu direktnu putanju u kodu i s php izvršavam java rečenice kroz .jar koji se brine o čeliku. Iako bih preporučio upotrebu HTML5, CSS3 i JavaScript, jer kako Adrian Java kaže, to je fatalno sa Html5 i donijelo mi je mnogo glavobolje

  4.   lurban rekao je

    Vodič o tome kako napraviti vlastiti programski jezik bio bi lijep

  5.   Ivan rekao je

    Vrlo dobra je ova serija članaka o tome kako izgraditi operativni sistem, naučite mnoge stvari. Radujem se sledećem unosu, već želim da imam tastaturu u OS-u. Zafrkavao sam se sa git kodom i nisam uspio da radi s portima 0x60 i 0x64. Iako sam mislio da je došlo do prekida zbog tipkovnice.

    1.    AdrianArroyoStreet rekao je

      Unos tipkovnice zapravo možete dobiti bez prekida, ali morate čitati pomoću ND :: Ports :: InputB na portu 0x60. Međutim, idealan način za to je s IRQ prekidima. Trenutno to pokušavam i treba malo više da nastavim zbog toga.

      1.    carlosorta rekao je

        Zdravo Adrian, provjeravao sam kod i impresioniran sam onim što on radi i koliko mi je dobro pomogao da razumijem neke stvari.

        Imam nekoliko malih pitanja o tome kako to funkcionira, a izvor sam dobio iz vašeg GIT-a:

        1.- U dijelu IRQ-a spomenuli ste da su pozicije od 0 do 32 IDT-a korištene za iznimke i od 32 (0x20) do 45 (0x2D) za IRQ-ove, ali IRQ-ovi su ukupno 16, remapiranje neće biti od 0x20 do 0x30?

        2.- U IRQ dijelu, imajte na umu da su postavljeni izlazi poslani u IDT odjeljak; Kada ih razdvajate, primijetite da više ne proizvodi izuzetak dijeljenja s 0, pa je potrebno dodati IDT Flush () za svaku napravljenu izmjenu. Zašto se IDT mijenja kada postavlja tajmer i podjela između 0 prestaje raditi?

        3.- Pokušavao sam pratiti kod s nekim ispisom kako bih ga uzeo kao pokazatelj onoga što izvršava (kako ne bi otklanjao pogreške korak po korak) i shvatio sam da se ne radi nijedan IRQ, moram li nešto drugo registrirati na Generirani IRQ prekidi?

        1.    carlosorta rekao je

          Zaboravio sam spomenuti da sam pronašao ove linkove s informacijama:
          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čigledno je za rukovanje IRQ-ovima potrebno uzeti u obzir koja vrsta rukovatelja se koristi ako je PIC, APIC, IOAPIC. . itd. Postoji li način za dinamičko rukovanje IRQ-om ili trebate probati sreću?

  6.   carlosorta rekao je

    Dobar dan Adrian.

    Vidio sam da imam problema s IRQ-ovima i zato kod nije mogao biti napredan, uzeo sam kopiju projekta i počeo ga analizirati; Sitotisku sam dodao funkciju za ispis reg zapisa zapisa struct reg, u trenutku prekida; Pronašao sam nekoliko stvari, među kojima i da je registar pokrenut, a još uvijek ne mogu pronaći zašto; promijenite tajmer za prekid tipkovnice kako biste testirali i učinili ono što treba, ali ne mogu pronaći problem, možete li mi pomoći i nastaviti s ovim dobrim postom? 😀

    Ostavljam vezu (ima neke izmjene jer koristim Mageia i Grub2, koristim VirtualBox da bih je testirao)
    https://www.mediafire.com/?93psrgaoozatse8

    Čekajući vaš pažljiv odgovor i ako imate pitanja ili trebate nešto, želio bih pomoći 🙂

    1.    carlosorta rekao je

      Zaboravio sam spomenuti da sam također provjerio KernelPanic jer ISR-ovi nisu radili i imam isti problem na vrhu steka da vrijednost curi i ne znam je li to moj kompajler ili postoji problem, koristim OUU 4.8.2 sa Mageia 4

    2.    AdrianArroyoStreet rekao je

      Zaista mi se sviđa što mi pomažete u projektu. Stvarno sam zapeo u tajmeru i ne razumijem zašto to ne radi. Napravio sam testove modificirajući dosta stvari i nije uspjelo. Trenutno ne mogu uređivati ​​kod (na odmoru sam), ali dobro ću ga pogledati čim budem mogao. Dajem vam vezu s informacijama o ovom problemu koji se čine nečim uobičajenim: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Što se tiče izuzetaka, mislim da se sjećam da morate nazvati "sti" u ASM-u kako bi ih aktivirali, iako je jasno da negdje nešto nije u redu.

      1.    carlosorta rekao je

        Hvala na odgovoru i da, zaista. Prekidi nisu uspjeli, ali bio je problem umetanju kodova u stog i problem emitiranja, provjerit ću vezu i provest ću testove. Ako to riješim, obavijestit ću vas, a ako ne, obavijestit ću vas o napretku. Sretni praznici 🙂

      2.    carlosorta rekao je

        Neće se moći vidjeti okupljeni kod? Da li se nešto čudno događa i ne mogu pronaći što? Pogledajte ovaj zaslon (vezu sam stavio na kraju), to je nešto čudno jer u IRQ 2 funkciji (tipkovnica ) on unosi u stog vrijednosti 0 i 0x20 (32, pa ga prilagodite testiranju), zatim pushal (32-bitni GPR registri), zatim registri segmentacije, a zatim vrh steka, a zatim nazovite IRQ Handler. Počeo sam vidjeti svaki stog i očito je u redu, ali ako možete vidjeti izlaz VM-a, možete vidjeti da on sadrži još jedan element, ne mogu pronaći gdje, znam samo da je 0x10 i struktura nije u redu. Ovo je struktura zapisa.

        struct regs {
        uint32_t gs, fs, es, ds; / * zadnji put gurnuo sekunde * /
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * gurnuo 'pushal' * /
        uint32_t int_no, err_code; / * Kôd greške * /
        uint32_t eip, cs, eflags, useresp, ss; / * Složeno na pauzi * /
        };

        Smeta mi što stavlja još jedan element na vrh i ne mogu pronaći gdje je složen ako je očigledno sve složeno kako treba. Imate li pojma šta bi to moglo biti?

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

  7.   carlosorta rekao je

    Neka prekida tipkovnice radi, ali ne i tajmer; greška je bila u načinu na koji je kompajliran, koristio sam objdump da vidim konačni objekt i ispalo je da je svaka funkcija koja je unesena čak i koristeći "asm volatile" bila popraćena i pushl ebp, mov ebp, esp. Zatim mu dodajte popl ebp da biste vratili početni stog i on će bez problema proslijediti argumente. Ovdje prilažem kôd onima koji ga žele provjeriti i ako možete saznati zašto tajmer ne generira prekid, volio bih ga znati i prilažem vezu na kojoj govore o multitaskingu http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Next Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyoStreet rekao je

      Shvatila sam. Bila je to greška na drugoj stranici koja je utjecala na aktivaciju tajmera PIC, konkretno u IRQ remapu bile su dvije linije koje sam morao izmijeniti. Zahvaljujući činjenici da sam na web mjestu mogao vidjeti kod koji je u tom trenutku imao nešto drugačije i kliknite! Promjena je slijedila:
      ND :: Priključci :: IzlazB (PIC1 + 1, 0xFF);
      ND :: Priključci :: IzlazB (PIC2 + 1, 0xFF);

      Morali ste promijeniti vrijednost 0xFF (rekao bih da to znači onemogućeno) u 0x00 (rekao bih da označava omogućeno), iako nisam baš siguran, ali to djeluje. Ažurirao sam kod na GitHub-u. Puno vam hvala što ste mi pomogli u projektu koji sam pomalo napustio zbog ovog problema. H

      1.    carlosorta rekao je

        Nema na čemu, radujem se sljedećem ažuriranju teme i možete računati na mene u bilo čemu 🙂

      2.    carlosorta rekao je

        Promijenite rutinu snimanja niza na tipkovnici; jer čita kada se ključ otpusti i postavlja 0 u međuspremnik, što stvara probleme u čitanju i na kraju '\ n' promijenite u », tako da ispravan ispis funkcionira

  8.   Soid perez rekao je

    Pozdrav, pročitao sam cijeli vaš post, iako u praksi to nije više od 2 posta, stvarno je jako dobar, sačuvajte sve, ali zaista ću trebati proučiti c ++ i posix da bih ga razumio, jer znam za "c" (fasciniran sam tim programskim jezikom), ali Iako je c ++ c OO, nikada zapravo nisam radio na tome, pročitajte mi nekoliko vodiča u googleu, a onda se vratim ovo vrlo zanimljivo i pitanje, je li pokretanje prozora slično Linuxu?

    1.    AdrianArroyoStreet rekao je

      Dizanje u operativnom sistemu Windows je slično u smislu da je ovo način pokretanja sistema sa x86 procesorom i operativni sistem izgrađen na njemu ima malo utjecaja. Mi se ionako zapravo ne pokrećemo, već nam započinje GRUB. GRUB, dizajniran za pokretanje Linuxa, može pokretati Windows i u ovom slučaju NextDivel.

      1.    soid rekao je

        ok hvala vam što znači da je ono što želim učiniti moguće već učim c ++ i stvorio sam neke aplikacije i instalirao vaš sistem na pendrive i proučavam ga detaljnije vrlo je dobar post