محاكاة Linus Torvalds: قم بإنشاء نظام التشغيل الخاص بك من البداية (VI)

حسنًا ، بعد قوس صغير نواصل سلسلة البرامج التعليمية الخاصة بنا. إذا عدنا إلى الكود السابق ، يجب أن يكون لدينا ISR للقسمة على صفر. الآن يجب علينا ملء بقية تقارير ISR التي قمنا بنشرها (أول 32). حسنًا ، سنواصل الآن مقاطعة البرمجة ، وسنقوم بعمل IRQs المعروف أيضًا باسم طلبات المقاطعات. يتم إنشاء IRQs بواسطة أجهزة مثل لوحات المفاتيح والفأرة والطابعات وما إلى ذلك. في البداية ، يتم تعيين أول 8 IRQs تلقائيًا إلى مواضع IDT من 8 إلى 15. وبما أننا استخدمنا أول 32 طلبًا للاستثناءات ، فعلينا الآن إعادة تخطيطها. سنضع IRQ من 32 إلى 45. لهذا يجب علينا أولاً إعادة تعيين IRQs:

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

نقوم الآن بإنشاء وظيفة لتثبيت IRQs:

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 الأمراض المنقولة جنسيا نقوم بتنشيط IRQs. حسنًا ، نذهب الآن مع شيء مشابه لـ ISR. وظائف IRQ الأساسية:

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

جزء مشترك (مثل 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"
);
}

والمعالج الأساسي:

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

مع هذا ، يجب أن يكون لدينا بالفعل IRQ مفعلًا حتى لو لم يفعلوا أي شيء. في الفصل التالي سوف نرى كيفية الحصول على البيانات من هذه IRQs مثل الساعة أو لوحة المفاتيح.

NextDivel-IRQ
وبهذا ينتهي منشور اليوم. كما ترون الآن أكتب بشكل أقل انتظامًا بسبب مشكلات أخرى. ومع ذلك ، سأستمر حتى يكون لدي نظام تشغيل أكثر اكتمالاً


محتوى المقال يلتزم بمبادئنا أخلاقيات التحرير. للإبلاغ عن خطأ انقر فوق هنا.

22 تعليقات ، اترك لك

اترك تعليقك

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها ب *

*

*

  1. المسؤول عن البيانات: ميغيل أنخيل جاتون
  2. الغرض من البيانات: التحكم في الرسائل الاقتحامية ، وإدارة التعليقات.
  3. الشرعية: موافقتك
  4. توصيل البيانات: لن يتم إرسال البيانات إلى أطراف ثالثة إلا بموجب التزام قانوني.
  5. تخزين البيانات: قاعدة البيانات التي تستضيفها شركة Occentus Networks (الاتحاد الأوروبي)
  6. الحقوق: يمكنك في أي وقت تقييد معلوماتك واستعادتها وحذفها.

  1.   aitor_cz قال

    شكرًا جزيلاً لك Adrian ، بمجرد أن يكون لدي بعض الوقت (الآن أنا مشغول جدًا ، من بين أشياء أخرى أيضًا مع نظام التشغيل) ، سأبدأ في اختبار البرنامج التعليمي خطوة بخطوة.

  2.   ياقوت قال

    شكرا جزيلا لك على توت.

  3.   ساسكي قال

    سؤال واحد أقوم به في مشروع يعتمد على لغات البرمجة هذه
    * هتمل 5
    * Css3
    * جافا
    سؤالي هو أنني أرغب في أن يكون هذا المشروع قابلاً للتنفيذ ، حتى يستخدمه المستخدمون في أنظمة التشغيل مثل لينكس وويندوز ، هل يمكن أن تخبرني كيف أفعل ذلك

    1.    شارع أدريان أرويو قال

      لا علاقة له بهذا لكنني أجيب على أي حال. أفترض أنه سيكون HTML5 و CSS3 وجافا سكريبت وليس جافا ، لأن HTML5 و Java يتعايشان بشكل قاتل. باستخدام HTML5 ، يمكنك إنشاء مواقع ويب كما كان من قبل يتم الوصول إليها من الإنترنت. إذا كنت ترغب في جعله محليًا ، فيمكنك حزمه كتطبيق Firefox OS و Chrome OS. إذا كان ما تريده هو أنه في كل نظام تشغيل يوجد ملف تنفيذي ألق نظرة على XUL Runner وهي أداة لتنفيذ XUL (وبالتالي HTML5 داخل العنصر) باستخدام محرك Gecko.

    2.    سويد بيريز قال

      يعد إطار Java أو اللوحة خيارًا جيدًا للغاية ، لقد قمت بإنشاء بعض التطبيقات القابلة للتنفيذ في النافذة باستخدام فئات إطار java كمتصفح ويب ولكن بدلاً من استخدامها في أي صفحة ، أعطيها مسارًا مباشرًا في الكود وباستخدام php أقوم بتنفيذ جمل java من خلال من الجار الذي يعتني بالفولاذ. على الرغم من أنني أوصي باستخدام HTML5 و CSS3 و JavaScript كما يقول Adrian Java ، إلا أنه قاتل مع Html5 وجلب لي الكثير من الصداع

  4.   عمامة قال

    سيكون البرنامج التعليمي حول كيفية صنع لغة البرمجة الخاصة بك أمرًا رائعًا

  5.   إيفان قال

    هذه السلسلة من المقالات الجيدة جدًا حول كيفية إنشاء نظام تشغيل ، ستتعلم أشياء كثيرة. إنني أتطلع إلى الإدخال التالي ، فأنا أرغب بالفعل في الحصول على لوحة مفاتيح في نظام التشغيل. لقد كنت العبث برمز git ، ولم أتمكن من تشغيله مع المنفذين 0x60 و 0x64. على الرغم من أنني اعتقدت أنه بالنسبة للوحة المفاتيح كان هناك مقاطعة أعطتك المفتاح المضغوط.

    1.    شارع أدريان أرويو قال

      يمكنك بالفعل الحصول على إدخال لوحة المفاتيح دون مقاطعة ، ولكن يجب عليك القراءة باستخدام ND :: Ports :: InputB على المنفذ 0x60. ومع ذلك ، فإن الطريقة المثلى للقيام بذلك هي المقاطعات IRQ. أحاول حاليًا القيام بذلك ويستغرق الأمر وقتًا أطول قليلاً للاستمرار بسبب ذلك.

      1.    كارلوسورتا قال

        مرحبًا Adrian ، لقد كنت أتحقق من الكود وأنا معجب بما يفعله وكيف ساعدني جيدًا في فهم بعض الأشياء.

        لدي بعض الأسئلة الصغيرة حول كيفية عملها والمصدر هو الذي تلقيته من GIT:

        1.- في جزء IRQs ، ذكرت أنه تم استخدام المواضع من 0 إلى 32 من IDT للاستثناءات ومن 32 (0x20) إلى 45 (0x2D) لـ IRQs ، لكن IRQs هي 16 في المجموع ، لن يكون إعادة التخطيط من 0x20 إلى 0x30؟

        2.- في جزء IRQ ، لاحظ أنك أرسلت البوابات المحددة إلى قسم IDT ؛ عندما تفصل بينهما ، لاحظ أنه لم يعد ينتج استثناء القسمة على 0 ، لذلك من الضروري إضافة IDT Flush () لكل تعديل يتم إجراؤه. لماذا يتغير IDT عند ضبط المؤقت والقسمة بين 0 توقف عن العمل؟

        3.- كنت أحاول تتبع الكود مع بعض الطباعة لأخذها كمؤشر لما يتم تنفيذه (حتى لا يتم تصحيح الأخطاء خطوة بخطوة) وأدركت أنه لا يوجد IRQ قيد التشغيل ، فهل يجب علي تسجيل شيء آخر لـ إنشاء المقاطعات IRQ؟

        1.    كارلوسورتا قال

          لقد نسيت أن أذكر أنني وجدت هذه الروابط بمعلومات:
          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

          على ما يبدو ، للتعامل مع IRQs ، من الضروري مراعاة نوع المعالج المستخدم إذا ، PIC ، APIC ، IOAPIC. . .إلخ. هل هناك طريقة لجعل إدارة IRQ ديناميكية أم أنك بحاجة إلى تجربة الحظ؟

  6.   كارلوسورتا قال

    مساء الخير يا أدريان.

    لقد رأيت أن لدي مشاكل مع IRQs ولهذا السبب لا يمكن تطوير الكود ، أخذت نسخة من المشروع وبدأت في تحليله ؛ لقد أضفت وظيفة إلى طباعة الشاشة لطباعة تسجيلات reg لـ Struct reg ، في وقت المقاطعة ؛ لقد وجدت العديد من الأشياء ، من بينها أن هناك سجلًا قيد التشغيل وما زلت لا أعرف السبب ؛ قم بتغيير مقاطعة Timer لمقاطعة لوحة المفاتيح لإجراء الاختبارات وهي تفعل ما يجب أن تفعله ولكن لا يمكنني العثور على المشكلة ، هل يمكنك مساعدتي ومتابعة هذا المنشور الجيد؟ 😀

    أترك الرابط (يحتوي على بعض التعديلات لأنني أستخدم Mageia وأستخدم Grub2 ، وأنا أستخدم VirtualBox لاختباره)
    https://www.mediafire.com/?93psrgaoozatse8

    في انتظار ردك اليقظ وإذا كان لديك أي أسئلة أو بحاجة إلى شيء أود المساعدة

    1.    كارلوسورتا قال

      لقد نسيت أن أذكر أنني أيضًا قمت بفحص KernelPanic لأن ISRs لم تعمل ولدي نفس المشكلة في الجزء العلوي من المكدس الذي تتسلل فيه القيمة ولا أعرف ما إذا كان مترجمي أم أن هناك مشكلة ، أستخدم GCC 4.8.2 مع Mageia 4

    2.    شارع أدريان أرويو قال

      يعجبني حقًا أنك تساعدني في المشروع. لقد علقت حقًا في Timer ولا أفهم لماذا لا يعمل. لقد أجريت اختبارات لتعديل الكثير من الأشياء ولم تنجح. حاليًا لا يمكنني تعديل الرمز (أنا في إجازة بعيدًا) لكنني سألقي نظرة فاحصة عليه في أسرع وقت ممكن. أقدم لك رابطًا بمعلومات حول هذه المشكلة يبدو أنها شيء شائع: http://wiki.osdev.org/I_Cant_Get_Interrupts_Working

      فيما يتعلق بالاستثناءات ، أعتقد أنني أتذكر أنه يتعين عليك إجراء مكالمة إلى "sti" في ASM لتنشيطها على الرغم من أنه من الواضح أن هناك خطأ ما في مكان ما.

      1.    كارلوسورتا قال

        شكرا على إجابتك ونعم بالفعل. كانت المقاطعات تفشل ولكن كانت هناك مشكلة في إدخال الرموز في المكدس ومشكلة صب ، سوف أتحقق من الرابط وسأجري اختبارات. إذا قمت بحلها ، فسوف أعلمك بذلك ، وإذا لم يكن الأمر كذلك فسوف أبلغك بالتقدم المحرز. اجازة سعيدة 🙂

      2.    كارلوسورتا قال

        لن تكون هناك طريقة لرؤية الكود المُجمَّع؟ هل يحدث شيء غريب ولا يمكنني العثور على ماذا؟ انظر إلى هذه الشاشة (أضع الرابط في النهاية) ، إنه شيء غريب لأنه في وظيفة IRQ 2 (لوحة المفاتيح) يدخل قم بتجميع القيمة 0 و 0x20 (32 ، لذا قم بتلائمها للاختبار) ثم pushal (سجلات GPR 32 بت) متبوعة بسجلات التجزئة ثم الجزء العلوي من المكدس ثم اتصل بـ IRQ Handler. لقد بدأت في رؤية كل مكدس ويبدو أنه بالترتيب ولكن إذا كان بإمكانك رؤية إخراج الجهاز الظاهري ، يمكنك أن ترى أنه يكدس عنصرًا آخر ، لا يمكنني العثور على مكان ، أعرف فقط أنه 0x10 وأن الهيكل خارج الترتيب. هذا هو هيكل التسجيل.

        بناء ريجس {
        uint32_t gs، fs، es، ds؛ / * دفع الثواني الماضي * /
        uint32_t edi و esi و ebp و esp و ebx و edx و ecx و eax ؛ / * مدفوع بـ "pushal" * /
        uint32_t int_no ، err_code ؛ /* خطا بالكود */
        uint32_t eip، cs، eflags، useresp، ss؛ / * مكدس عند الاستراحة * /
        };

        يزعجني أنه يضع عنصرًا آخر في الجزء العلوي ولا يمكنني العثور على مكان مكدس إذا كان كل شيء مكدسًا كما ينبغي. هل لديك أي فكرة عما يمكن أن يكون؟

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

  7.   كارلوسورتا قال

    احصل على مقاطعة لوحة المفاتيح للعمل ولكن ليس مقاطعة المؤقت ؛ كان الخطأ في طريقة تجميعه ، واستخدمت objdump لرؤية الكائن النهائي واتضح أن كل وظيفة تم إدخالها حتى باستخدام "asm volatile" كانت مصحوبة أيضًا بـ pushl ebp و mov ebp و esp. ثم فقط أضف popl ebp لاستعادة المكدس الأولي وسيقوم بتمرير الوسائط دون فشل. أرفق هنا الكود لأولئك الذين يرغبون في التحقق منه وإذا كان بإمكانك معرفة سبب عدم إنشاء المقاطعة بواسطة Timer ، أود أن أعرف ذلك وأرفق رابطًا يتحدثون فيه عن تعدد المهام http://www.jamesmolloy.co.uk/tutorial_html/9.-Multitasking.html
    التالي Divel
    https://www.mediafire.com/?kmo83dxyzc7c3cz

    1.    شارع أدريان أرويو قال

      فهمت. لقد كان خطأ في مكان آخر أثر على تنشيط Timer PIC ، وتحديداً في إعادة رسم خريطة IRQ ، كان هناك سطرين يجب تعديلهما. بفضل حقيقة أنه كان بإمكاني رؤية رمز على موقع ويب كان في ذلك الوقت يحتوي على شيء مختلف وانقر عليه! كان التغيير على غرار:
      ND :: Ports :: OutputB (PIC1 + 1، 0xFF) ؛
      ND :: Ports :: OutputB (PIC2 + 1، 0xFF) ؛

      كان عليك تغيير قيمة 0xFF (أود أن أقول إنها تشير إلى تعطيل) إلى 0x00 (أود أن أقول إنها تشير إلى التمكين) على الرغم من أنني لست متأكدًا حقًا ، لكنها تعمل. لقد قمت بتحديث الكود على GitHub. شكرًا جزيلاً على مساعدتي في المشروع الذي تخليت عنه قليلاً بسبب هذه المشكلة. ح

      1.    كارلوسورتا قال

        على الرحب والسعة ، سأنتظر التحديث القادم للموضوع ويمكنك الاعتماد علي في أي شيء 🙂 (Y)

      2.    كارلوسورتا قال

        تغيير روتين التقاط سلسلة لوحة المفاتيح ؛ لأنه يقرأ في لحظة تحرير المفتاح ويقوم بتركيب 0 في المخزن المؤقت ، مما يؤدي إلى حدوث مشاكل في القراءة وفي النهاية ، قم بتغييره إلى »بحيث تعمل الطباعة الصحيحة

  8.   سويد بيريز قال

    مرحبًا ، لقد قرأت مشاركتك بالكامل ، على الرغم من أنها عمليًا لا تزيد عن مشاركتين ، إلا أنها جيدة جدًا حقًا ، احفظ كل شيء ، لكنني سأحتاج حقًا إلى دراسة c ++ و posix لفهمها لأنني أعرف شيئًا عن "c" (أنا مفتون بلغة البرمجة تلك) ولكن على الرغم من أن c ++ هي c OO ، إلا أنني لم أعمل عليها أبدًا ، اقرأ بعض البرامج التعليمية في google ثم أعيد هذا السؤال المثير للاهتمام والسؤال ، هل بدء تشغيل النافذة مشابه لنظام Linux؟

    1.    شارع أدريان أرويو قال

      يشبه التمهيد في Windows بمعنى أن هذه هي طريقة تمهيد نظام بمعالج x86 ونظام التشغيل المبني عليه ليس له تأثير يذكر. نحن في الواقع لا نطلق النار على أنفسنا على أي حال ، إنه يمهد GRUB لنا. يمكن لـ GRUB ، المصمم لتشغيل Linux ، تشغيل Windows وفي هذه الحالة NextDivel.

      1.    سويد قال

        حسنًا ، شكرًا ، هذا يعني أن ما أريد القيام به ممكن ، أنا بالفعل أدرس c ++ وقمت بإنشاء بعض التطبيقات وقمت بتثبيت نظامك على pendrive وأنا أدرسه بمزيد من التفصيل وهو منشور جيد جدًا