Linus Torvalds'ı Taklit Etmek: Kendi işletim sisteminizi sıfırdan oluşturun (VI)

Küçük bir parantezden sonra eğitim serimize devam ediyoruz. Önceki koda dönersek, bölümün ISR'sini sıfıra sahip olmalıyız. Şimdi bir mesaj gönderdiğimiz geri kalan ISR'leri (ilk 32) doldurmalıyız. Pekala, şimdi programlama kesintilerine devam edeceğiz, IRQ'ları da yapacağız. İstekleri Keser. Bu IRQ'lar klavyeler, fareler, yazıcılar vb. Gibi donanım aygıtları tarafından oluşturulur. Başlangıçta ilk 8 IRQ otomatik olarak 8'den 15'e IDT konumlarına eşlenir. İlk 32'yi istisnalar için kullandığımızdan şimdi onları yeniden eşleştirmemiz gerekiyor. IRQ'yu 32'den 45'e koyacağız. Bunun için önce IRQ'ları yeniden eşleştirmeliyiz:

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

Şimdi IRQ'ları kurmak için bir fonksiyon oluşturuyoruz:

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 cümlesi şti IRQ'ları etkinleştiriyoruz. Şimdi ISR'ye benzer bir şeyle gidiyoruz. Temel bir IRQ'nun işlevleri:

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

Ortak bir bölüm (ISR ile aynı):

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

Ve temel bir işleyici:

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

Bununla birlikte, hala bir şey yapmasalar bile IRQ'yu zaten etkinleştirmiş olmalıyız. Bir sonraki bölümde, bu IRQ'lardan saat veya klavye gibi verilerin nasıl elde edileceğini göreceğiz.

SonrakiDivel-IRQ


Ve bununla bugünün gönderisi sona eriyor. Gördüğünüz gibi, diğer sorunlar nedeniyle daha az düzenli yazıyorum. Yine de daha eksiksiz bir işletim sistemine sahip olana kadar devam edeceğim


Yorumunuzu bırakın

E-posta hesabınız yayınlanmayacak. Gerekli alanlar ile işaretlenmiştir *

*

*

  1. Verilerden sorumlu: Miguel Ángel Gatón
  2. Verilerin amacı: Kontrol SPAM, yorum yönetimi.
  3. Meşruiyet: Onayınız
  4. Verilerin iletilmesi: Veriler, yasal zorunluluk dışında üçüncü kişilere iletilmeyecektir.
  5. Veri depolama: Occentus Networks (AB) tarafından barındırılan veritabanı
  6. Haklar: Bilgilerinizi istediğiniz zaman sınırlayabilir, kurtarabilir ve silebilirsiniz.

  1.   aitor_cz dijo

    Çok teşekkür ederim Adrian, biraz zamanım olur olmaz (şimdi oldukça meşgulüm, diğer şeylerin yanı sıra bir işletim sistemi ile) öğreticiyi adım adım test etmeye başlayacağım.

  2.   Yakut dijo

    Tute için çok teşekkür ederim.

  3.   sasuke dijo

    Bir soru bu programlama dillerine dayalı bir proje yapıyorum
    * Html5
    * Css3
    * Java
    Sorum şu, bu projenin çalıştırılabilir olmasını istiyorum, böylece kullanıcılar onu linux ve windows gibi işletim sistemlerinde kullansın, bana bunu nasıl yaptığımı söyleyebilir misiniz

    1.    AdrianArroyoSokak dijo

      Bununla ilgisi yok ama yine de size cevap vereceğim. HTML5 ve Java kötü bir şekilde çalıştığı için HTML3, CSS5 ve JavaScript olacak, Java değil. HTML5 ile daha önce olduğu gibi internetten erişilen web siteleri oluşturabilirsiniz. Yerel hale getirmek istiyorsanız, bir Firefox OS ve Chrome OS uygulaması olarak paketleyebilirsiniz. İstediğiniz şey, her işletim sisteminde, Gecko motoruyla XUL'u (ve dolayısıyla öğenin içindeki HTML5'i) yürütmek için bir araç olan XUL Runner'a bir göz atan bir yürütülebilir dosya olması ise.

    2.    Soid perez dijo

      Java çerçevesi veya paneli çok iyi bir seçenek Java çerçeve sınıflarını web tarayıcısı olarak kullanarak pencerede bazı çalıştırılabilir uygulamalar oluşturdum, ancak herhangi bir sayfa için kullanmak yerine kodda doğrudan bir yol veriyorum ve php ile java cümlelerini çalıştırıyorum çelikle ilgilenen bir .jar aracılığıyla. HTML5, CSS3 ve JavaScript kullanmanızı tavsiye etmeme rağmen, Adrian Java, Html5 ile Fatal dediği ve bana birçok baş ağrısını getirdiğinden

  4.   pusuda dijo

    Kendi programlama dilinizi nasıl yapacağınıza dair bir eğitim güzel olurdu

  5.   Ivan dijo

    Bir işletim sisteminin nasıl kurulacağına dair bu makale dizisi çok iyi, pek çok şey öğreniyorsunuz. Bir sonraki girişi dört gözle bekliyorum, işletim sisteminde zaten bir klavyeye sahip olmak istiyorum. Git koduyla uğraşıyorum ve onu 0x60 ve 0x64 bağlantı noktaları ile çalıştırmayı başaramadım. Klavye için size basılan tuşu veren bir kesinti olduğunu düşünmeme rağmen.

    1.    AdrianArroyoSokak dijo

      Aslında kesintisiz klavye girdisi alabilirsiniz, ancak 0x60 bağlantı noktasında ND :: Ports :: InputB ile okumalısınız. Ancak bunu yapmanın ideal yolu IRQ kesintileridir. Şu anda yapmaya çalışıyorum ve bu nedenle devam etmem biraz daha uzun sürüyor.

      1.    Carlosorta dijo

        Merhaba Adrian, Kodu kontrol ediyordum ve ne yaptığından ve bazı küçük şeyleri anlamama ne kadar yardımcı olduğundan etkilendim.

        Nasıl çalıştığına dair birkaç küçük sorum var ve GIT'inizden aldığım kaynak:

        1.- IRQ bölümünde, istisnalar için IDT'nin 0'dan 32'ye ve IRQ'lar için 32'den (0x20) 45'e (0x2D) kadar konumlarının kullanıldığından bahsetmiştiniz, ancak IRQ'ların toplamda 16 olduğunu, yeniden biçimlendirmenin olmayacağını söylediniz. 0x20 ile 0x30 arasında?

        2.- IRQ bölümünde, set kapılarının IDT bölümüne gönderildiğine dikkat edin; Bunları ayırdığınızda, artık 0'a bölme istisnasını üretmediğine dikkat edin, bu nedenle yapılan her değişiklik için IDT Flush () eklemek gerekir. Zamanlayıcıyı ayarlarken IDT neden değişiyor ve 0 arasındaki bölme çalışmayı durduruyor?

        3.- Neyin yürütüldüğünün bir göstergesi olarak almak için bir miktar baskı ile kodu izlemeye çalışıyordum (adım adım hata ayıklama yapmamak için) ve IRQ'nun çalışmadığını fark ettim, başka bir şey kaydetmem gerekiyor mu? IRQ kesintileri oluşturuldu mu?

        1.    Carlosorta dijo

          Şu bilgileri içeren bağlantıları bulduğumu söylemeyi unuttum:
          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

          Görünüşe göre IRQ'ları işlemek için, PIC, APIC, IOAPIC ise hangi tür işleyicinin kullanıldığını hesaba katmak gerekir. . .vb. IRQ yönetimini dinamik hale getirmenin bir yolu var mı yoksa şans denemeniz mi gerekiyor?

  6.   Carlosorta dijo

    İyi günler Adrian.

    IRQ'larla sorunlar yaşadığımı ve bu nedenle kodun geliştirilemediğini gördüm, projenin bir kopyasını aldım ve analiz etmeye başladım; Kesintilerin yapıldığı anda struct reg'in kayıtlarını yazdırmak için serigrafi baskısına bir işlev ekledim; Aralarında bir kayıt defterinin çalıştığı ve nedenini hala bulamadığım birkaç şey buldum; Klavye kesintisinin test edilmesi için Timer interrupt'ını değiştirin ve yapması gerekeni yapın, ancak sorunu bulamıyorum, bana yardım edip bu güzel gönderiye devam edebilir misiniz? 😀

    Bağlantıyı bırakıyorum (bazı değişiklikler var çünkü Mageia kullanıyorum ve Grub2 kullanıyorum, test etmek için VirtualBox kullanıyorum)
    https://www.mediafire.com/?93psrgaoozatse8

    Dikkatli yanıtınızı bekliyorum ve herhangi bir sorunuz varsa veya bir şeye ihtiyacınız varsa, yardım etmek isterim 🙂

    1.    Carlosorta dijo

      KernelPanic'i de kontrol ettiğimi söylemeyi unuttum çünkü ISR'ler çalışmadı ve yığının tepesinde aynı sorunu yaşıyorum, bir değer gizlice giriyor ve derleyicim mi yoksa bir sorun mu olduğunu bilmiyorum, ben Mageia 4.8.2 ile GCC 4 kullanın

    2.    AdrianArroyoSokak dijo

      Bana projede yardımcı olman çok hoşuma gidiyor. Zamanlayıcıya gerçekten takıldım ve neden çalışmadığını anlamıyorum. Birkaç şeyi değiştirerek testler yaptım ve işe yaramadı. Şu anda kodu düzenleyemiyorum (tatildeyim) ancak elimden geldiğince çabuk gözden geçireceğim. Size bu sorunla ilgili ortak bir şey gibi görünen bilgileri içeren bir bağlantı veriyorum: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      İstisnalarla ilgili olarak, bir yerde yanlış bir şeyler olduğu açık olmasına rağmen, ASM'de onları etkinleştirmek için "sti" ye bir çağrı yapmanız gerektiğini hatırlıyorum.

      1.    Carlosorta dijo

        Cevabınız için teşekkürler ve evet, gerçekten. Kesmeler başarısız oluyordu ancak kodların yığına girilmesinde bir sorun ve bir döküm sorunuydu, bağlantıyı kontrol edeceğim ve testler yapacağım. Çözersem size haber vereceğim, çözemezseniz size ilerleme konusunda bilgi vereceğim. İyi Tatiller 🙂

      2.    Carlosorta dijo

        Birleştirilmiş kodu görmenin bir yolu olmayacak? Tuhaf bir şey mi oluyor ve ne bulamıyorum? Bu ekrana bakın (bağlantıyı sonuna koyuyorum), IRQ 2 işlevinde (klavye ) Yığına 0 ve 0x20 değerini (32, bu nedenle test etmek için sığdırın), ardından itmeli (32 bit GPR kayıtları), ardından bölümleme kayıtlarını ve ardından yığının tepesini girer ve ardından IRQ İşleyicisini çağırır. Her yığını görmeye başladım ve görünüşe göre sıralı ama VM'nin çıktısını görüyorsanız, bir eleman daha yığdığını görebilirsiniz, nerede bulamıyorum, sadece 0x10 olduğunu biliyorum ve yapı arızalanır. Bu kayıt yapısıdır.

        struct regs {
        uint32_t gs, fs, es, ds; / * saniyeleri en son itti * /
        uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; / * 'pushal' tarafından itildi * /
        uint32_t int_no, err_code; /* Hata kodu */
        uint32_t eip, cs, eflags, useresp, ss; / * Arada yığılmış * /
        };

        Bana bir tane daha eleman koyan bir teneke kutu veriyor ve görünüşe göre her şey olması gerektiği gibi istiflenmişse, nerede istiflendiğini bulamıyorum. Ne olabileceğine dair bir fikrin var mı?

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

  7.   Carlosorta dijo

    Klavye kesintisinin çalışmasını sağlayın, ancak zamanlayıcıyı kesmeyin; hata derlenme biçimindeydi, son nesneyi görmek için objdump kullandım ve "asm volatile" kullanılarak girilen her fonksiyona bir pushl ebp, mov ebp, esp eşlik ettiği ortaya çıktı. Ardından, ilk yığını geri yüklemek için bir popl ebp ekleyin ve argümanları başarısız olmadan geçirecektir. Buraya kontrol etmek isteyenler için kodu ekliyorum ve kesintinin neden Zamanlayıcı tarafından oluşturulmadığını öğrenebilirseniz, bunu bilmek isterim ve çoklu görev hakkında konuştukları bir bağlantı ekliyorum http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    Sonraki Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    AdrianArroyoSokak dijo

      Anladım. Zamanlayıcı PIC'in aktivasyonunu etkileyen başka bir sitedeki bir hataydı, özellikle IRQ yeniden eşleştirmesinde değiştirmek zorunda olduğum iki satır vardı. Bir web sitesinde o noktada farklı bir şeye sahip olan ve tıklayan bir kod görebildiğim için teşekkürler! Değişiklik şu satırlardaydı:
      ND :: Ports :: ÇıktıB (PIC1 + 1, 0xFF);
      ND :: Ports :: ÇıktıB (PIC2 + 1, 0xFF);

      Gerçekten emin olmasam da değeri 0xFF'den (devre dışı olduğunu belirtirim) 0x00'e (etkin olduğunu söyleyebilirim) değiştirmeniz gerekiyordu, ama çalışıyor. Kodu GitHub'da güncelledim. Bu sorun nedeniyle biraz terk ettiğim projede bana yardımcı olduğunuz için çok çok teşekkür ederim. H

      1.    Carlosorta dijo

        Rica ederim, konunun bir sonraki güncellemesini dört gözle bekliyorum ve bana her konuda güvenebilirsin 🙂 (Y)

      2.    Carlosorta dijo

        Klavye dizisi yakalama yordamını değiştirin; çünkü anahtarı serbest bıraktığı anda okuyor ve arabelleğe bir 0 takıyor, bu okumada sorunlara neden oluyor ve sonunda '\ n' olarak değiştirerek »doğru yazdırma çalışması

  8.   Soid perez dijo

    Merhaba, yazının tamamını okudum, pratikte 2'den fazla gönderi olmasa da, gerçekten çok iyi, her şeyi sakla, ancak anlamak için gerçekten c ++ ve posix çalışmam gerekecek çünkü "c" yi biliyorum (Bu programlama diline hayran kaldım) ama c ++ c OO olmasına rağmen, bunun üzerinde hiç çalışmadım, bana google'da bazı öğreticiler okuyun ve sonra bunu çok ilginç ve bir soruyla geri dönüyorum, pencere başlangıcı linux'a benzer mi?

    1.    AdrianArroyoSokak dijo

      Windows'ta önyükleme, x86 işlemcili bir sistemi önyüklemenin yolu olması ve bunun üzerine kurulu işletim sisteminin çok az etkisi olması bakımından benzerdir. Zaten kendimizi gerçekten başlatmıyoruz, bizim için GRUB'u başlatıyor. Linux'u başlatmak için tasarlanan GRUB, Windows'u ve bu durumda NextDivel'i önyükleyebilir.

      1.    katı dijo

        tamam teşekkürler bu, yapmak istediğim şeyin mümkün olduğu anlamına geliyor zaten c ++ üzerinde çalışıyorum ve bazı uygulamalar oluşturdum ve sisteminizi bir pendrive'a yükledim ve daha detaylı çalışıyorum çok iyi bir yazı