लिनुस टोरवाल्ड्स का अनुकरण करना: 0 (V) से अपना ऑपरेटिंग सिस्टम बनाना

इस पांचवीं किस्त में हम सिद्धांत में GDT के समान एक तालिका देखेंगे और उपयोग में, हम IDT का उल्लेख करते हैं। IDT के लिए खड़ा है व्यवधान विवरण तालिका y एक तालिका है जो कि होने वाली रुकावटों को संभालने के लिए उपयोग की जाती है। उदाहरण के लिए, कोई 0 से एक विभाजन बनाता है, प्रसंस्करण के कार्य प्रभारी को कहा जाता है। ये कार्य ISR (बाधित सेवा दिनचर्या) का है। तो आइए आईडीटी बनाएं और कुछ आईएसआर जोड़ें।

पहले हम आईडीटी के अनुरूप संरचनाओं को घोषित करने जा रहे हैं:

struct Entry{
uint16_t base_low;
uint16_t sel;
uint8_t always0;
uint8_t flags;
uint16_t base_high;
} __attribute__((packed));
struct Ptr{
uint16_t limit;
uint32_t base;
} __attribute__((packed));

जैसा कि देखा जा सकता है यदि आप इसकी तुलना GDT से करते हैं, तो Ptr संरचना समान है और प्रविष्टि काफी समान है। इसलिए एक प्रविष्टि (सेटगेट) डालने और स्थापित करने (इंस्टॉल) के कार्य बहुत समान हैं।

void ND::IDT::SetGate(uint8_t num,uint32_t base,uint16_t sel, uint8_t flags)
{
idt[num].base_low=(base & 0xFFFF);
idt[num].base_high=(base >> 16) & 0xFFFF;
idt[num].sel=sel;
idt[num].always0=0;
idt[num].flags=flags;
}

इंस्टॉल:

idtptr.limit=(sizeof(struct ND::IDT::Entry)*256)-1;
idtptr.base=(uint32_t)&idt;
ND::Memory::Set(&idt,0,sizeof(struct ND::IDT::Entry)*256);
ND::IDT::Flush();

यदि हम देखते हैं कि हम देखेंगे कि एनडी :: मेमोरी :: सेट फ़ंक्शन का उपयोग करता है जिसे हमने दूसरे पोस्ट में घोषित किया था। हम यह भी देख सकते हैं कि हम अभी तक सेटगेट पर कोई कॉल कैसे नहीं करते हैं और हम ND :: IDT :: फ्लश कहते हैं, इस फ़ंक्शन के लिए हम asm अस्थिर स्टेटमेंट का फिर से उपयोग करते हैं:

asm volatile("lidtl (idtptr)");

अगर सबकुछ ठीक हो जाता है और हम एक सौंदर्य व्यवस्था बनाते हैं तो इसे इस तरह देखना चाहिए:

नेक्स्टडिवेल-आईडीटी

ठीक है, अब आरटीडी को बाधित करने के साथ आबाद करना शुरू करें। यहाँ मैं केवल एक ही बनाने जा रहा हूँ, लेकिन बाकी के लिए भी यही होगा। मैं जीरो ब्रेक से डिवाइड करने जा रहा हूं। जैसा कि आप अच्छी तरह से गणित में जानते हैं, एक संख्या को 0. से विभाजित नहीं किया जा सकता है। यदि यह प्रोसेसर में होता है, तो एक अपवाद उत्पन्न होता है क्योंकि यह जारी नहीं रह सकता है। IDT में सूची में पहला व्यवधान (0) इस घटना से मेल खाता है।

हम इसे मेमोरी सेटिंग और IDT के इंस्टॉल फ़ंक्शन के भीतर फ्लश के बीच जोड़ते हैं:

ND::IDT::SetGate(0,(unsigned)ND::ISR::ISR1,0x08,0x8E);

कॉलबैक फ़ंक्शन ND :: ISR :: ISR1 होने जा रहा है जो काफी सरल है, हालांकि हमें ASM का उपयोग करना चाहिए:

void ND::ISR::ISR1()
{
asm volatile(
"cli \n"
"pushl 0 \n"
"pushl 0 \n"
"jmp ND_ISR_Common \n"
);
}

ND_ISR_Common हम इसे C भाषा में एक फ़ंक्शन के रूप में परिभाषित करेंगे। फ़ाइलों को सहेजने और पठनीयता में सुधार करने के लिए हम बाहरी «C» {} का उपयोग कर सकते हैं:

extern "C"
void ND_ISR_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_ISR_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"
);
}

ASM में यह कोड समझना थोड़ा मुश्किल हो सकता है, लेकिन इसका कारण यह है कि हम C में एक संरचना घोषित करने जा रहे हैं, ताकि व्यवधान उत्पन्न होने वाले डेटा का उपयोग किया जा सके। जाहिर है, अगर आप ऐसा नहीं चाहते हैं, तो आप सिर्फ ND :: ISR :: ISR1 में कर्नेल घबराहट या ऐसा कुछ कह सकते हैं। संरचना का आकार ऐसा है:

struct regs{
uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
};

और अंत में हम ND_ISR_Handler फ़ंक्शन (एक सी लिंक के साथ भी) बनाते हैं जिसमें हम एक कर्नेल आतंक और त्रुटि का एक छोटा विवरण दिखाते हैं जो हमारे पास त्रुटियों की सूची में है।

extern "C"
void ND_ISR_Handler(struct regs *r)
{
if(r->int_no < 32) { ND::Panic::Show(exception_messages[r->int_no]);
for(;;);
}
}

अच्छा है और इसके साथ हम पहले से ही इस रुकावट को संभालने में सक्षम हैं। बाकी रुकावटों के साथ ऐसा ही होगा, सिवाय इसके कि कुछ ऐसे पैरामीटर हैं जो रिटर्न पैरामीटर हैं और हम इसे प्राप्त करने के लिए रेग संरचना का उपयोग करेंगे। हालांकि, आपको आश्चर्य हो सकता है कि हम कैसे जानते हैं कि क्या यह वास्तव में काम करता है। यह परीक्षण करने के लिए कि क्या यह काम करता है हम ND :: IDT :: Install () के बाद एक सरल लाइन शुरू करने जा रहे हैं:

int sum=10/0;

यदि हम संकलित करते हैं तो यह हमें एक चेतावनी देगा और यदि हम इसे निष्पादित करने का प्रयास करते हैं तो हमें एक अच्छी स्क्रीन मिलेगी:

नेक्स्टडिवेल-आईएसआर


और इस पोस्ट को समाप्त करने के साथ, मुझे लगता है कि यह सबसे व्यापक लेकिन काफी कार्यात्मक में से एक है।


अपनी टिप्पणी दर्ज करें

आपका ईमेल पता प्रकाशित नहीं किया जाएगा। आवश्यक फ़ील्ड के साथ चिह्नित कर रहे हैं *

*

*

  1. डेटा के लिए जिम्मेदार: मिगुएल elngel Gatón
  2. डेटा का उद्देश्य: नियंत्रण स्पैम, टिप्पणी प्रबंधन।
  3. वैधता: आपकी सहमति
  4. डेटा का संचार: डेटा को कानूनी बाध्यता को छोड़कर तीसरे पक्ष को संचार नहीं किया जाएगा।
  5. डेटा संग्रहण: ऑकेंटस नेटवर्क्स (EU) द्वारा होस्ट किया गया डेटाबेस
  6. अधिकार: किसी भी समय आप अपनी जानकारी को सीमित, पुनर्प्राप्त और हटा सकते हैं।

  1.   मेसोडेबलर कहा

    मैंने एलएफएस पर स्विच किया, यह अधिक निरंतर है।

  2.   एलियोटाइम३००० कहा

    पवित्र... वैसे भी, ट्यूटोरियल अच्छे हैं।

  3.   sc कहा

    बहुत अच्छा, मैं शुरू से ही इसका पालन कर रहा हूं। क्या आप प्रत्येक ट्रेलर में कोड संलग्न कर सकते हैं?

    1.    AdrianArroyoStreet कहा

      आपके पास GitHub पर सभी स्रोत कोड उपलब्ध हैं: http://github.com/AdrianArroyoCalle/next-divel वहां से आप एक ZIP, एक TAR.GZ डाउनलोड कर सकते हैं या बस git का उपयोग कर सकते हैं।

  4.   सूक्ष्म कहा

    हाहाहा बहुत बढ़िया! मंज़ूरी देना! 🙂