Emulace Linuse Torvaldse: Vytvořte si svůj vlastní operační systém od nuly (VI)

Po malé závorce pokračujeme v naší sérii výukových programů. Pokud se vrátíme k předchozímu kódu, musíme mít ISR dělení nulou. Nyní musíme vyplnit zbytek ISR, pro které jsme zveřejnili (prvních 32). Nyní budeme pokračovat v programovacích přerušeních, budeme dělat IRQ známé také jako Přerušení požadavků. Tyto IRQ jsou generovány hardwarovými zařízeními, jako jsou klávesnice, myši, tiskárny atd. Zpočátku je prvních 8 IRQ automaticky mapováno na pozice IDT 8 až 15. Protože jsme pro výjimky použili prvních 32, nyní je musíme přemapovat. Dáme IRQ z 32 na 45. K tomu musíme nejprve přemapovat 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);
}

Nyní vytvoříme funkci pro instalaci IRQ:

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

Věta asm Vědět aktivujeme IRQ. Teď jdeme s něčím podobným ISR. Funkce základního IRQ:

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

Společná část (stejná jako 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"
);
}

A základní obsluha:

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

Díky tomu bychom již měli mít IRQ aktivované, i když stále nic nedělají. V následující kapitole uvidíme, jak získat data z těchto IRQ, jako jsou hodiny nebo klávesnice.

DalšíDivel-IRQ


A tím končí dnešní příspěvek. Jak nyní vidíte, píšu méně pravidelně kvůli dalším problémům. I tak budu pokračovat, dokud nebudu mít úplnější operační systém


Zanechte svůj komentář

Vaše e-mailová adresa nebude zveřejněna. Povinné položky jsou označeny *

*

*

  1. Odpovědný za údaje: Miguel Ángel Gatón
  2. Účel údajů: Ovládací SPAM, správa komentářů.
  3. Legitimace: Váš souhlas
  4. Sdělování údajů: Údaje nebudou sděleny třetím osobám, s výjimkou zákonných povinností.
  5. Úložiště dat: Databáze hostovaná společností Occentus Networks (EU)
  6. Práva: Vaše údaje můžete kdykoli omezit, obnovit a odstranit.

  1.   aitor_cz řekl

    Moc děkuji Adrianovi, jakmile budu mít čas (nyní jsem docela zaneprázdněn, mimo jiné i operačním systémem), začnu tutoriál testovat krok za krokem.

  2.   Rubín řekl

    Moc děkuji za čas.

  3.   Sasuke řekl

    Jedna otázka dělám projekt založený na těchto programovacích jazycích
    * Html5
    * Css3
    *Jáva
    Moje otázka je, že bych chtěl, aby byl tento projekt spustitelný, aby jej uživatelé mohli používat v operačních systémech, jako jsou linux a Windows, můžete mi říct, jak to dělám

    1.    AdrianArroyo Street řekl

      Nemá to s tím nic společného, ​​ale stejně vám odpovídám. Myslím, že to bude HTML5, CSS3 a JavaScript, ne Java, protože HTML5 a Java se zhoršují. S HTML5 můžete vytvářet webové stránky jako dříve, ke kterým se přistupuje z internetu. Pokud jej chcete nastavit jako místní, můžete jej zabalit jako aplikaci Firefox OS a Chrome OS. Pokud chcete, aby v každém operačním systému byl spustitelný soubor, podíval se na XUL Runner, což je nástroj ke spuštění XUL (a tedy HTML5 uvnitř prvku) s motorem Gecko.

    2.    Soid perez řekl

      Java frame or panel is a very good option I have created some executable apps in window using the java frame classes as a web browser but instead of using it for any page I give it a direct path in the code and with php I execute java vety prostřednictvím .jar, který se stará o ocel. Ačkoli bych doporučil používat HTML5, CSS3 a JavaScript, protože jak říká Adrian Java, trvá to s Fatal s Html5 a přineslo mi to mnoho bolestí hlavy

  4.   městský řekl

    Výukový program, jak vytvořit vlastní programovací jazyk, by byl hezký

  5.   Ivan řekl

    Velmi dobře, v této sérii článků o tom, jak vybudovat operační systém, se dozvíte mnoho věcí. Těším se na další záznam, už chci mít klávesnici v OS. Pohrával jsem si s kódem git a nedokázal jsem to přimět k práci s porty 0x60 a 0x64. I když jsem si myslel, že u klávesnice došlo k přerušení, které vám dalo stisknutou klávesu.

    1.    AdrianArroyo Street řekl

      Ve skutečnosti můžete získat vstup z klávesnice bez přerušení, ale musíte číst pomocí ND :: Ports :: InputB na portu 0x60. Ideálním způsobem je to však s přerušeními IRQ. V současné době se o to snažím a pokračování kvůli tomu trvá trochu déle.

      1.    Carlosorta řekl

        Ahoj Adrian, zkontroloval jsem kód a jsem ohromen tím, co dělá a jak dobře mi pomohl pochopit některé věci.

        Mám několik malých otázek o tom, jak to funguje, a zdrojem je ten, který jsem dostal od vašeho GIT:

        1. - V části IRQ jste zmínili, že pozice 0 až 32 IDT byly použity pro výjimky a od 32 (0x20) do 45 (0x2D) pro IRQ, ale IRQ je celkem 16, remaping by nebyl od 0x20 do 0x30?

        2. - V části IRQ si povšimněte, že setgates byly odeslány do sekce IDT; Když je oddělíte, všimněte si, že již nevytváří výjimku dělení 0, takže je nutné přidat IDT Flush () pro každou provedenou úpravu. Proč se IDT mění při nastavení časovače a rozdělení mezi 0 přestane fungovat?

        3.- Snažil jsem se vysledovat kód pomocí nějakého tisku, který by měl brát jako indikaci toho, co provádí (aby se nedocházelo k ladění krok za krokem) a uvědomil jsem si, že neběží žádné IRQ, musím zaregistrovat něco jiného generována přerušení IRQ?

        1.    Carlosorta řekl

          Zapomněl jsem zmínit, že jsem našel tyto odkazy s informacemi:
          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

          Zřejmě pro zpracování IRQ je nutné vzít v úvahu, jaký typ obslužné rutiny se použije if, PIC, APIC, IOAPIC. . .atd. Existuje způsob, jak dynamizovat správu IRQ, nebo potřebujete zkusit štěstí?

  6.   Carlosorta řekl

    Dobré odpoledne, Adriane.

    Viděl jsem, že mám problémy s IRQ, a proto nemohl být kód pokročilý, vzal jsem kopii projektu a začal jsem ji analyzovat; Do sítotisku jsem přidal funkci pro tisk reg záznamů struktury reg, v okamžiku provádění přerušení; Našel jsem několik věcí, mezi nimiž je spuštěný registr, a stále nemohu najít proč; změnit přerušení časovače pro přerušení klávesnice, aby se otestovalo a udělalo, co by mělo, ale nemohu najít problém, mohl byste mi pomoci a pokračovat s tímto dobrým příspěvkem? 😀

    Nechávám odkaz (má nějaké úpravy, protože používám Mageia a používám Grub2, k testování používám VirtualBox)
    https://www.mediafire.com/?93psrgaoozatse8

    Čekám na vaši pozornou odpověď a pokud máte nějaké dotazy nebo něco potřebujete, rád bych pomohl 🙂

    1.    Carlosorta řekl

      Zapomněl jsem zmínit, že jsem také zkontroloval KernelPanic, protože ISR nefungovaly a mám stejný problém v horní části zásobníku, hodnota je filtrována a já nevím, jestli je to můj překladač nebo je problém, já používat GCC 4.8.2 s Mageia 4

    2.    AdrianArroyo Street řekl

      Opravdu se mi líbí, že mi v projektu pomáháte. Opravdu jsem se zasekl v časovači a nechápu, proč to nefunguje. Provedl jsem testy, které upravovaly několik věcí a nevyšlo to. V současné době nemohu editovat kód (jsem na dovolené), ale co nejdříve si to dobře prohlédnu. Dávám vám odkaz s informacemi o tomto problému, který se zdá být něčím běžným: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      Pokud jde o výjimky, myslím, že si pamatuji, že je musíte zavolat na „sti“ v ASM, abyste je aktivovali, i když je jasné, že někde něco není v pořádku.

      1.    Carlosorta řekl

        Děkuji za vaši odpověď a ano, opravdu. Přerušení selhala, ale byl to problém s vložením kódů do zásobníku a problém s odléváním, zkontroluji odkaz a budu dělat testy. Pokud to vyřeším, dám vám vědět a pokud ne, budu vás informovat o pokroku. Veselé svátky 🙂

      2.    Carlosorta řekl

        Sestavený kód nebude možné vidět? Děje se něco divného a nemohu najít co? Podívejte se na tuto obrazovku (odkaz jsem dal na konec), je to něco divného, ​​protože ve funkci IRQ 2 (klávesnice ) zadá do zásobníku hodnotu 0 a 0x20 (32, takže se hodí k testování), poté pushal (32bitové registry GPR) následovaný segmentačními registry a poté horní částí zásobníku a poté zavolá obslužný program IRQ. Začal jsem vidět každý zásobník a zjevně je to v pořádku, ale pokud vidíte výstup VM, vidíte, že hromadí ještě jeden prvek, nemohu najít kde, jen vím, že je to 0x10 a struktura vyřazeno z provozu. Toto je struktura záznamu.

        struct regs {
        uint32_t gs, fs, es, ds; / * posunul poslední sekundy * /
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * tlačil 'pushal' * /
        uint32_t int_no, err_code; /* Chybový kód */
        uint32_t eip, cs, eflags, useresp, ss; / * Skládaný na přestávku * /
        };

        Vadí mi, že nahoře umístí ještě jeden prvek a nemohu najít, kde je naskládán, pokud je zjevně vše naskládáno tak, jak by mělo být. Máte představu, co by to mohlo být?

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

  7.   Carlosorta řekl

    Nechte přerušení klávesnice fungovat, ale ne přerušení časovače; chyba byla ve způsobu, jakým byla kompilována, použil jsem objdump k zobrazení konečného objektu a ukázalo se, že každá funkce, která byla zadána i pomocí "asm volatile", byla také doprovázena pushl ebp, mov ebp, esp. Pak do něj stačí přidat popl ebp, abyste obnovili počáteční zásobník, a bez problémů předá argumenty. Zde připojuji kód pro ty, kteří si to chtějí zkontrolovat, a pokud zjistíte, proč nedochází k přerušení kvůli časovači, rád bych to znal a připojuji odkaz, kde hovoří o multitaskingu http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Další Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyo Street řekl

      Mám to. Byla to chyba na jiném místě, která ovlivnila aktivaci Timer PIC, konkrétně v IRQ remap byly dva řádky, které jsem musel upravit. Díky tomu, že jsem na webu viděl kód, který měl v té chvíli něco jiného a klikal! Změna proběhla v duchu:
      ND :: Porty :: OutputB (PIC1 + 1, 0xFF);
      ND :: Porty :: OutputB (PIC2 + 1, 0xFF);

      Museli jste změnit hodnotu z 0xFF (řekl bych, že to znamená zakázáno) na 0x00 (řekl bych, že to znamená povoleno), i když si nejsem úplně jistý, ale funguje to. Aktualizoval jsem kód na GitHubu. Velice vám děkuji za pomoc s projektem, který jsem kvůli tomuto problému trochu opustil. H

      1.    Carlosorta řekl

        Nemáte zač, těším se na další aktualizaci tématu a můžete se mnou na cokoli počítat 🙂 (Y)

      2.    Carlosorta řekl

        Změňte rutinu snímání řetězců klávesnice; protože to je čtení v okamžiku uvolnění klíče a připojí 0 do vyrovnávací paměti, což způsobí problémy při čtení a na konci '\ n' to změní na », aby fungoval správný tisk

  8.   Soid perez řekl

    Dobrý den, přečetl jsem si celý váš příspěvek, i když v praxi to není více než 2 příspěvky, je to opravdu velmi dobré, uložte vše, ale budu opravdu muset studovat c ++ a posix, abych to pochopil, protože vím o "c" (Fascinuje mě programovací jazyk), ale i když c ++ je c OO, nikdy jsem na tom opravdu nepracoval, přečtěte mi několik tutoriálů v google a pak vám vrátím tuto velmi zajímavou otázku, je spuštění okna podobné linuxu?

    1.    AdrianArroyo Street řekl

      Zavádění ve Windows je podobné v tom smyslu, že se jedná o způsob zavádění systému s procesorem x86 a operační systém na něm postavený má malý vliv. Vlastně se opravdu nespouštíme, pro nás to začíná GRUB. GRUB, určený ke spouštění Linuxu, může zavádět Windows a v tomto případě NextDivel.

      1.    ukradl řekl

        ok díky, to znamená, že to, co chci udělat, je možné, už studuji c ++ a vytvářím nějaké aplikace a instaluji váš systém na pendrive a podrobněji to studuji, je to velmi dobrý příspěvek