في المقالة
السابقة ، الثانية في صف واحد ، قمنا بتطوير الوظائف اللازمة للعمل مع سلاسل من مكتبة C. في هذا الدرس ، نقوم بتنفيذ إخراج تصحيح كامل على الشاشة - سجل نظام kernel.
جدول المحتويات
- بناء نظام (جعل ، مجلس التعاون الخليجي ، الغاز). التمهيد الأولي (متعدد التمهيد). إطلاق (qemu). مكتبة C (strcpy ، memcpy ، strext).
- مكتبة C (sprintf ، strcpy ، strcmp ، strtok ، va_list ...). بناء المكتبة في وضع kernel ووضع تطبيق المستخدم.
- سجل نظام النواة. ذاكرة الفيديو الإخراج إلى المحطة (kprintf ، kpanic ، kassert).
- الذاكرة الديناميكية ، الكومة (kmalloc ، kfree).
- تنظيم الذاكرة والتعامل مع المقاطعة (GDT ، IDT ، PIC ، syscall). الاستثناءات.
- الذاكرة الظاهرية (دليل الصفحة وجدول الصفحة).
- العملية. المجدول. تعدد المهام. مكالمات النظام (القتل ، الخروج ، ملاحظة).
- نظام ملفات kernel (initrd) ، قزم ، وداخله. مكالمات النظام (exec).
- برامج تشغيل الأجهزة الشخصية. مكالمات النظام (ioctl ، fopen ، fread ، fwrite). مكتبة C (fopen ، fclose ، fprintf ، fscanf).
- شل كبرنامج كامل للنواة.
- وضع حماية المستخدم (ring3). قسم حالة المهمة (tss).
سجل نظام Kernel
قبل أن نبدأ ، سنحتاج إلى تقديم بعض الوظائف المفيدة للعمل مع منافذ الإدخال / الإخراج. لا تختلف منافذ الإدخال / الإخراج للمبرمج عن الخلايا العادية في الذاكرة ، باستثناء وجود أوامر منفصلة لتشغيلها. الأجهزة التي تعمل على هذه المنافذ متصلة بنقل الذاكرة. هناك أيضًا مساحة عنوان مخصصة لهم. سنحتاج إلى وظيفتين للتجميع للعمل مع منافذ الإدخال / الإخراج ، لأنه كما تتذكر بالفعل ، لا أتسامح مع إدراج أداة التجميع.
extern u_char asm_read_port(u_char port); extern void asm_write_port(u_int port, u_char data);
وبالمثل ، هناك أمران للتحكم في مقاطعات المعالج المقنع.
extern void asm_lock(); extern void asm_unlock();
حسنًا ، لتوفير الطاقة بعد الأخطاء القاتلة ، فأنت بحاجة إلى أمر إيقاف المعالج.
extern void asm_hlt();
كما تتذكر ، تبدأ ذاكرة الفيديو في 0xB8000 ، لكنني أقترح كتابة الرسائل أولاً إلى المخزن المؤقت بتنسيق نص عادي. ثم انسخ هذا المخزن المؤقت في ذاكرة الفيديو ، مع مراعاة سمات الألوان. للقيام بذلك ، قمت بتنفيذ العديد من الأدوات المساعدة للعمل مع هذه المخازن المؤقتة. سيكون المخزن المؤقت واحد syslog kernel ، والباقي من أجل المحطات الافتراضية. سيتم تنفيذ التمرير على الشاشة أيضًا على المخزن المؤقت. ولن تؤدي وظيفة video_flush إلا إلى نسخ المخزن المؤقت إلى ذاكرة الفيديو ، مع توسيعه بسمات.
extern void video_init(); extern void video_disable_cursor(); extern void* video_scroll(char const* video_buff, char* pos); extern char* video_clear(char const* video_buff); extern void video_flush(char const* video_buff);
الآن هو الوقت المناسب لتقديم الميزات الأكثر استخدامًا. سيتم استخدام الأخيرتين لتصحيح kernel عندما يتم تصحيح الكسل بواسطة المصحح. صدقوني ، لم أستخدم مصححًا أبدًا عندما كتبت هذا النواة.
extern void kpanic(char* message, ...); extern void kassert(const char* file, u_int line, bool expr); extern void kunreachable(const char* file, u_int line);
حسنا ، في الواقع ، وظائف للعمل مع سجل نظام kernel. للتحكم في ما يتم عرضه على الشاشة ، أدخلت وظيفة kmode في سجل النظام أو وحدة تحكم المستخدم. لقراءة سجل النظام في المخزن المؤقت ، ستكون هناك حاجة إلى وظيفة klog ، لأن عمليات المستخدم لن يكون لها حق الوصول إلى kernel إلا من خلال مكالمات النظام.
extern void kclear(); extern void kprintf(const char* format, ...); extern void kvprintf(const char* format, va_list list); extern void kmode(bool is_early); extern void klog(char* buf, u_int n);
أعطي الوظائف الأكثر إثارة للاهتمام هنا:
extern void* video_scroll(char const* video_buff, char* pos) { char* ptr = (void*)video_buff; for (int i = 1; i < VIDEO_SCREEN_HEIGHT; ++i) { for (int j = 0; j < VIDEO_SCREEN_WIDTH; ++j) { ptr[(i - 1) * VIDEO_SCREEN_WIDTH + j] = ptr[i * VIDEO_SCREEN_WIDTH + j]; } } for (int j = 0; j < VIDEO_SCREEN_WIDTH; ++j) { ptr[(VIDEO_SCREEN_HEIGHT - 1) * VIDEO_SCREEN_WIDTH + j] = ' '; } pos -= VIDEO_SCREEN_WIDTH; return pos; }
extern void kvprintf(const char* format, va_list list) { char buff[VIDEO_SCREEN_WIDTH]; int len = vsprintf(buff, format, list); for (int i = 0; i < len; ++i) { if (buff[i] != '\n') { kputc(buff[i]); } else { int line_pos = (syslog_pos - syslog) % VIDEO_SCREEN_WIDTH; for (int j = 0; j < VIDEO_SCREEN_WIDTH - line_pos; ++j) { kputc(' '); } } } kflush(); }
static void kputc(char ch) { if ((size_t)syslog_pos - (size_t)syslog + 1 < VIDEO_SCREEN_SIZE) { *syslog_pos++ = ch; } else { syslog_pos = video_scroll(syslog, syslog_pos); kputc(ch); } }
انظر البرنامج التعليمي المفصل في الفيديو التعليمي.
مراجع
→
فيديو تعليمي لهذا المقال→
شفرة المصدر (تحتاج إلى فرع الدرس 3)
مراجع
- جيمس مولوي. لفة نظام التشغيل الخاص بك UNIX استنساخ.
- زوبكوف. مجمع ل DOS ، ويندوز ، يونيكس
- كلاشينكوف. المجمع سهل!
- تانينباوم. أنظمة التشغيل. التنفيذ والتطوير.
- روبرت لوف. نواة لينكس وصف عملية التطوير.