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

Pa, nakon malo zagrade nastavljamo s našim nizom vodiča. Ako se vratimo na prethodni kod, moramo imati ISR ​​podjele s nulom. Sada moramo popuniti ostatak ISR-ova za koje smo objavili (prva 32). Pa, nastavit ćemo s prekidima programiranja, napravit ćemo IRQ-ove također poznate kao Prekida zahtjeve. Te IRQ-ove generiraju hardverski uređaji poput tipkovnica, miševa, pisača itd. U početku se prvih 8 IRQ-a automatski preslikava na IDT položaje 8 do 15. Kako smo koristili prvih 32 za iznimke, sada ih moramo preslikati. IRQ ćemo postaviti s 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);
}

Uz ovo bismo već trebali aktivirati IRQ čak i ako još uvijek ništa ne rade. U sljedećem ćemo poglavlju vidjeti 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. Uprkos tome, nastavit ću dok ne dobijem cjelovitiji operativni sustav


Ostavite svoj komentar

Vaša email adresa neće biti objavljen. Obavezna polja su označena s *

*

*

  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 obvezi.
  5. Pohrana podataka: Baza podataka koju hostira Occentus Networks (EU)
  6. Prava: U bilo kojem trenutku možete ograničiti, oporaviti i izbrisati svoje podatke.

  1.   aitor_cz dijo

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

  2.   Rubin dijo

    Najljepša hvala za tute.

  3.   Sasuke dijo

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

    1.    AdrianArroyoStreet dijo

      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 loše slažu. Pomoću HTML5 možete stvoriti web stranice kao i prije kojima se pristupa s Interneta. Ako ga želite učiniti lokalnim, možete ga pakirati kao Firefox OS i Chrome OS aplikaciju. Ako želite da u svakom operativnom sustavu postoji izvršna datoteka, pogledajte XUL Runner koji je alat za izvršavanje XUL-a (i stoga HTML5 unutar elementa) s Gecko motorom.

    2.    Soid perez dijo

      Java okvir ili ploča vrlo su dobra opcija Stvorio sam neke izvršne aplikacije u prozoru koristeći klase java okvira kao web preglednik, ali umjesto da ih koristim za bilo koju stranicu, dajem mu izravan put u kodu i s php izvršavam java rečenice kroz .jar koji se brine za čelik. Iako bih preporučio upotrebu HTML5, CSS3 i JavaScript, jer kako Adrian Java kaže, potreban je Fatal s Html5 i donio mi je puno glavobolje

  4.   lurbanski dijo

    Bio bi lijep vodič za izradu vlastitog programskog jezika

  5.   Ivane dijo

    Vrlo je dobra ova serija članaka o tome kako izgraditi operativni sustav, naučite mnoge stvari. Radujem se sljedećem unosu, već želim imati tipkovnicu u OS-u. Petljao sam se s git kodom i nisam uspio postići da radi s portima 0x60 i 0x64. Iako sam mislio da je za tipkovnicu došlo do prekida zbog kojeg ste pritisnuli tipku.

    1.    AdrianArroyoStreet dijo

      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 zbog toga treba malo više vremena da nastavim.

      1.    karlosorta dijo

        Pozdrav 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 je onaj koji sam dobio iz vašeg GIT-a:

        1.- U dijelu IRQ-a spomenuli ste da su položaji od 0 do 32 IDT-a korišteni za iznimke i od 32 (0x20) do 45 (0x2D) za IRQ-ove, ali IRQ-ovi su ukupno 16, remapiranje ne bi bilo od 0x20 do 0x30?

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

        3. - Pokušavao sam pronaći 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 IRQ, moram li registrirati nešto drugo do IRQ generisanih prekida?

        1.    karlosorta dijo

          Zaboravio sam spomenuti da sam pronašao ove poveznice 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

          Izgleda da je za rukovanje IRQ-ovima potrebno uzeti u obzir koja se vrsta rukovatelja koristi ako je PIC, APIC, IOAPIC. . itd. Postoji li način za dinamičko rukovanje IRQ-om ili trebate okušati sreću?

  6.   karlosorta dijo

    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 sam 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; promijeni prekid Timer za prekid tipkovnice za testiranje i radi 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, za testiranje koristim VirtualBox)
    https://www.mediafire.com/?93psrgaoozatse8

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

    1.    karlosorta dijo

      Zaboravio sam spomenuti da sam također provjerio KernelPanic jer ISR-ovi nisu radili i imam isti problem na vrhu stoga, vrijednost se filtrira i ne znam je li to moj kompajler ili postoji problem, ja koristite GCC 4.8.2 s Mageia 4

    2.    AdrianArroyoStreet dijo

      Jako mi se sviđa što mi pomažete u projektu. Stvarno sam zapeo u timeru i ne razumijem zašto to ne radi. Napravio sam testove modificirajući puno 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 su, čini se, nešto uobičajeno: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Što se tiče iznimaka, 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.    karlosorta dijo

        Hvala na odgovoru i da, zaista. Prekidi nisu uspjeli, ali problem je bio u unosu kodova u stog i problem lijevanja, 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.    karlosorta dijo

        Neće se moći vidjeti okupljeni kod? Je li se dogodilo nešto čudno i ne mogu pronaći što? Pogledajte ovaj zaslon (vezu stavljam na kraju), to je nešto čudno jer u IRQ 2 funkciji (tipkovnica ) unosi u stog vrijednosti 0 i 0x20 (32, pa ga prilagodite testiranju), zatim pushal (32-bitni GPR registri), nakon čega slijede registri segmentacije, a zatim vrh steka, a zatim nazovite IRQ Handler. Počeo sam vidjeti svaki stog i očito je u redoslijedu, ali ako možete vidjeti izlaz VM-a, možete vidjeti da on slaže 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, kôd pogreške; /* Kod pogreške */
        uint32_t eip, cs, eflags, useresp, ss; / * Složeno na pauzi * /
        };

        Daje mi limenku koja stavlja još jedan element na vrh i ne mogu pronaći gdje je složen ako je očito sve složeno kako treba. Znate li što bi to moglo biti?

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

  7.   karlosorta dijo

    Neka prekida tipkovnice radi, ali ne i tajmer; pogreška je bila u načinu na koji je kompiliran, koristio sam objdump da bih vidio 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 kod za one koji ga žele provjeriti i ako možete saznati zašto prekid ne generira odbrojavanje, volio bih ga znati i prilažem vezu na kojoj razgovaraju o multitaskingu http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Sljedeći Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyoStreet dijo

      Shvatio sam. Bila je to greška na drugoj stranici koja je utjecala na aktivaciju Timer PIC-a, točnije u IRQ remapu bila su dva retka koja 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 zapravo nisam siguran, ali djeluje. Ažurirao sam kôd na GitHubu. Puno vam hvala što ste mi pomogli u projektu koji sam pomalo napustio zbog ovog problema. H

      1.    karlosorta dijo

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

      2.    karlosorta dijo

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

  8.   Soid perez dijo

    Pozdrav, pročitao sam cijeli vaš post, iako u praksi to nije više od 2 posta, stvarno je jako dobro, spremite sve, ali stvarno ć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 na njemu nisam stvarno radio, pročitajte mi nekoliko tutorijala u googleu, a onda se vratim u vrlo zanimljivo i pitanje, je li pokretanje prozora slično linux ?

    1.    AdrianArroyoStreet dijo

      Dizanje u sustavu Windows slično je u smislu da je to način pokretanja sustava s x86 procesorom i operativni sustav izgrađen na njemu nema puno utjecaja. Mi se ionako zapravo ne pokrećemo, već započinje GRUB za nas. GRUB, dizajniran za pokretanje Linuxa, može pokretati Windows i u ovom slučaju NextDivel.

      1.    zvuk dijo

        ok hvala, to znači da je moguće ono što želim učiniti. Već proučavam c ++ i stvaram neke aplikacije i instaliram vaš sustav na pendrive, a detaljnije ga proučavam vrlo je dobar post