تطوير نظام تشغيل متماثل يشبه نظام التشغيل - مكتبة C (2)

في مقال سابق ، تعلمنا كيفية تشغيل Hello World kernel وكتبنا دالتين للتعامل مع الجمل. الآن حان الوقت لتوسيع مكتبة C بحيث يمكنك تنفيذ kprintf وغيرها من الوظائف الضرورية. دعنا نذهب!

جدول المحتويات


  1. بناء نظام (جعل ، مجلس التعاون الخليجي ، الغاز). التمهيد الأولي (متعدد التمهيد). إطلاق (qemu). مكتبة C (strcpy ، memcpy ، strext).
  2. مكتبة C (sprintf ، strcpy ، strcmp ، strtok ، va_list ...). بناء المكتبة في وضع kernel ووضع تطبيق المستخدم.
  3. سجل نظام النواة. ذاكرة الفيديو الإخراج إلى المحطة (kprintf ، kpanic ، kassert).
  4. الذاكرة الديناميكية ، الكومة (kmalloc ، kfree).
  5. تنظيم الذاكرة والتعامل مع المقاطعة (GDT ، IDT ، PIC ، syscall). الاستثناءات.
  6. الذاكرة الظاهرية (دليل الصفحة وجدول الصفحة).
  7. العملية. المجدول. تعدد المهام. مكالمات النظام (القتل ، الخروج ، ملاحظة).
  8. نظام ملفات kernel (initrd) ، قزم ، وداخله. مكالمات النظام (exec).
  9. برامج تشغيل الأجهزة الشخصية. مكالمات النظام (ioctl ، fopen ، fread ، fwrite). مكتبة C (fopen ، fclose ، fprintf ، fscanf).
  10. شل كبرنامج كامل للنواة.
  11. وضع حماية المستخدم (ring3). قسم حالة المهمة (tss).

مكتبة C


تحتاج أولاً إلى تنفيذ أنواع ذات أبعاد واضحة.

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

typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned int u_long; 

لا يضر بإدخال نوع منطقية.

 #pragma once /* types */ typedef int bool; #define true 1 #define false 0 #define null 0 

أيضا ، لن يضر بنا بضع وحدات ماكرو للعمل مع وحدات البايت.

 typedef unsigned long size_t; #define HIGH_WORD(addr) ((addr & 0xffff0000) >> 16) #define LOW_WORD(addr) ((addr & 0xffff)) #define LOW_BYTE(addr) ((addr & 0x00ff)) #define HIGH_BYTE(addr) ((addr & 0xff00) >> 8) 

وحدات الماكرو التالية مطلوبة للعمل مع عدد متغير من الوسائط. لا تعمل هذه الطريقة إلا إذا اتبعت الدالة اصطلاح استدعاء لغة C ، حيث يتم تمرير وسيطات الدالة خلال المكدس بدءًا من الأخير.

 typedef size_t* va_list; #define va_start(l, a) (l = (void*)((size_t)&a) + sizeof(a)) #define va_end(l) (l = (void*)0) #define va_arg(l, s) (*(s*)(l++)) 

بالطبع ، يمكن للمرء أن يذهب في الاتجاه الآخر. بدلاً من تحديد الوظائف الخاصة بك ، حاول استخدام المكتبة المدمجة واستبدال الوظائف التي ستصل إلى kernel من خلال LD_PRELOAD. لكنني أحب التحكم في العملية تمامًا ، لذلك دعونا نترك هذا الخيار كفكرة لأولئك الذين يبدأون في كتابة نظام التشغيل الخاص بهم على هذا البرنامج التعليمي.

علاوة على ذلك ، في الفيديو التعليمي ، سننظر في تنفيذ وظائف المكتبة التالية. لا يدعي التطبيق أنه المثالية والكمال ، لكنني أعتقد أنه يدعي أنه البساطة وسهولة القراءة. أود فقط أن نلاحظ أننا نستخدم تطبيقاً آمنًا لمؤشر الترابط لوظيفة strtok ، والذي يسمى strtok_r. وقد توصلنا إلى وظائف strinv و strext لأنفسنا في الدرس الأخير. إذا كنت معتادًا على لغة C ، فأعتقد أنك ستكون على دراية بجميع الوظائف المدرجة أدناه تقريبًا.

 extern int strlen(const char* s); extern char* strcpy(char* s1, const char* s2); extern char* strncpy(char* s1, const char* s2, u_int n); extern void* memcpy(void* buf1, const void* buf2, u_int bytes); extern void* memset(void* buf1, u8 value, u_int bytes); extern int strcmp(const char* s1, const char* s2); extern int strncmp(const char* s1, const char* s2, u_int n); extern char* strcat(char* s1, const char* s2); extern char* strext(char* buf, const char* str, char sym); extern int strspn(char* str, const char* accept); extern int strcspn(char* str, const char* rejected); char* strchr(const char* str, char ch); extern char* strtok_r(char* str, const char* delims, char** save_ptr); extern char* memext(void* buff_dst, u_int n, const void* buff_src, char sym); extern char* itoa(unsigned int value, char* str, unsigned int base); extern unsigned int atou(char* str); extern char* strinv(char* str); extern unsigned int sprintf(char* s1, const char* s2, ...); extern unsigned int snprintf(char* s1, u_int n, const char* s2, ...); extern unsigned int vsprintf(char* s1, const char* s2, va_list list); extern unsigned int vsnprintf(char* s1, unsigned int n, const char* s2, va_list list); 

يتم الروتين بعيدا. نهاية رمز النمطي. سيكون الدرس التالي أكثر تعقيدًا وإثارة للاهتمام. إذا كنت ترغب في رعاية مشروع ، يمكنك تقديم التنفيذ الأمثل لوظائف المكتبة.

مراجع


تطوير نظام تشغيل متماثل يونيكس - الشروع في العمل
فيديو تعليمي لهذا المقال
شفرة المصدر (تحتاج إلى فرع الدرس 2)

مراجع


  1. جيمس مولوي. لفة نظام التشغيل الخاص بك UNIX استنساخ.
  2. زوبكوف. مجمع ل DOS ، ويندوز ، يونيكس
  3. كلاشينكوف. المجمع سهل!
  4. تانينباوم. أنظمة التشغيل. التنفيذ والتطوير.
  5. روبرت لوف. نواة لينكس وصف عملية التطوير.

Source: https://habr.com/ru/post/ar466709/


All Articles