من سالها در مورد نوشتن سیستم عامل مطالعه کردم نه به طور مداوم جسته گریخته هم نیمچه سیستم عامل هم نوشتم که دارای چند ریسمانی مدیریت حافظه و شل و ... بودند
الان سالهاست حوصله نوشتن کد دیگه ندارم
اینها مربوط به 22-20 سال پیش بود اما هنوز گاهی در موردش مطالعه میکنم خواستم دانسته هام در اختیار کسانی که علافه مند هستند قرار بدهم شاید به کسی کمک کرد راه بهشون نشان داد از کجا باید به کجا بروند و یک دید کلی بهشون بده
تو طراحی سیستم عامل چند تا نکته کلیدی وجود دارد که باید رعایت بشه
بعضی دستگاه باید پاسخ در زمان واقعی ارائه بدهند (realtime) بعضی دستگاه ها اجباری ندارند
بعضی سیستم عامل ها نیاز هست فقط با 3-4 تا دستگاه مدیریت کنند که قرار نیست سخت افزاری بهش اضافه یا کم بشه خوب این سیستم عامل کوچیک سبکی میشه براش نوشت
بعضی سیستم عامل ها با ده ها و صدها سخت افزار به و صورت همزمان ارتباط دارند خوب اینها پیچیدگیش بیشتر هست
ما فرض بر این میزاریم که هدف علافه مندان به نوشتن سیستم عامل در ایران گوشی و کامپیوتر ها رومیزی یا لپ تاپ هست
نوشتن سیستم عامل که حتی دارای یک محیط گرافیکی (نه خیلی حرفه ای نه خیلی ابتدای) هست را میشود در عرض 1-2 سال توسط 2-3 برنامه نویس حرفه ای که دانش عمیقی از سیستم عامل داشته باشند انجام داد یک سیستم عامل مبتدی نه یک سیستم عامل متوسط یا حرفه ای
نمونه هاش تو اینترنت بگردید برنامه نویس های پیدا میکنید که به صورت اتفرادی انجام دادند
یکسریشون تو بخش osdev سایت reddit هنوز فعالیت میکنند نمونه کار میذارند
اما چرا اکثریت این سیتم عامل های انفرادی یا گروه کوچک به نتیجه نمیرسند به خاطر این سه موضوع هست
1 - سازگاری نرم افزاری
یعنی سیستم عامل جدید فایل ها EXE ویندوز یا فایل ها اجرای ELF لینوکس یا مکینتاش یا APK اندروید را پشتیانی نمیکند
این یعنی چندین هزار نرم افزار کوچک بزرگ (از بانک اطلاعاتی گرفته تا بازی ها) و صدها میلیارد دلار هزینه ای و زمانی که برای نوشتن این نرم افزار نوشته شده باید کنار گذاشته و دور ریخته شود
2 - پشتبانی سخت افزاری
یعنی هزاران درایوری که برای راه اندازی سخت افزار طی چند دهه توسط شرکت ها نوشته شده بلا استفاده است
3 - پایداری و قابلیت اطمینان اون سیستم عامل هست
یعنی سیستم عامل خوب طراحی شده باشه و تمام استثناها و خطا ها و حالات کاری و روابط بین بخش هاش براش تعریف و مشخص شده باشد و اگر به هر دلیلی ایرادی پیش امد نرم افزار یا سیستم عامل کرش نکند و قابل اطمینان و پایدار باشد
فرضا اگر در اینده فرد یا گروه بخواهند سیستم عامل بنویسند و این سه عامل در نظر بگیرند احتمالش زیاد هست سیستم عاملشان بتواند جایگزین ویندوز لینوکس و دیگر سیستم عامل ها بشود
برای اضافه کردن این موارد به سیستم عامل جدید هر سه اینها راه حل دارند
اضافه کردن اینها به سیستم عامل جدید کار واقعا سخت طاقت فرسای است ولی نتیجه اش بسیار بسیار عالیه و راضی کننده است
درمورد سازگاری نرم افزاری
بجای اینکه بیایم برای سیستم عامل جدید ده ها نرم افزار و کامپایلر طراحی کنیم که بسیار سخت هزینه بر است و شاید کاربران و توسعه دهندگان بهش رغبتی نشان ندهند
کاری کنیم که نرم افزار ها دیگر سیستم عامل ها بر روی سیستم عامل ما به صورت بومی اجرا شوند مثلا نرم افزارهای لینوکس و ویندوز
در این صورت شما توانای اجرای ده ها هزار نرم افزار روی سیستم عاملتان پیدا میکنید که تاثیر شگرفی در جذب مخاطب برای سیستم عاملتان دارد
برای این کار باید تمام یا اکثریت توابع API که فایل های اجرای در لینوکس و ویندوز فراخوانی میکنند را پیاده سازی کنید
یک نرم افزار حتی در حد Hello World که در سیستم عامل اجرا میشود مستقیما با کرنل از طریق API های که کرنل در اختیارش قرار داده در ارتباط هست مثل دسترسی به باز و بستن و خواندن و نوشتن فایل یا پورت یا رسم پنجره یا کنسول و ....
شما یک فایل اجرای را دیکامپایل کنید میتوانید لیست و نام این توابع ببینید (نام تمام این توابع مورد نیاز برای اجرای ان نرم افزار در خود فایل اجرای است)
باید تمام این توابع با همان نامی که فراخوانی میشوند در سیستم عامل پیاده سازی بشوند
برای دانستن عظمت و عمق کار میتوانید به Wine در لینوکس اشاره کرد میتوانید از کدش در سیستم عاملتان کپی کنید
هرچقدر فایلهای اجرای بیشتری از سیستم عامل های دیگر بتوانند بدون مشکل در سیستم عامل شما اجرا شوند اعتماد بیشتری به سیستم عامل شما میشود
قسمت بعدی در مورد پشتبانی از سخت افزارهای مختلف است
هرچقدر بتوانید از سخت افزارهای بیشتری پشیتبانی کنید به طبع اون کاربر بیشتری جذب میکنید اما این سخت ترین قسمت سیستم عامل است در وافع بیش از 70 درصد کد یک سیستم عامل مربوط به درایورها هست !!!! چه در ویندوز چه در لینوکس
مثلا از 15 میلیون خط کد کرنل لینوکس بیش از 10 میلیون خط ان مربوط به درایورها است !! و کمتر از 5 میلیون مربوط به کرنل که اون 5 میلیون خط هم بیشترش مربوط به پشتیبان کردن لینوکس از معماری ها مختلف سی پی یو هست و کمتر از 1 میلیون خطش مربوط به خود کرنل لینوکس هست
برای حل مشکل درایور شما یا باید برای همه سخت افزارها درایور بنویسید که کاری تقریبا نشدنی هست برای یک گروه کوچک
فقط از یک شرکت با هزاران برنامه نویس و صد ها میلیون دلار پول برمیاید مثل مایکروسافت
اونها هم یکسری سخت افزارها را میتواند برایش درایور بنویسد مثلا سخت افزارهای تخصصی را فقط شرکت سازنده سورس کدش دارد
یا اینکه از معماری لینوکس یا ویندوز برای ارتباط با سخت افزارها استفاده کنید
برای لینوکس میتوانید از device tree یا درخت دستگاه استفاده کنید که درایورها به صورت اپن سورس درش وجود دارند و شما باید تمام توابعی که در سورس کد درایورها برای ارتباط با کرنل لینوکس فراخوانی شده را در کرنل خود بازنویسی کنید تا ان درایورها روی سیستم عامل شما کار کنند (مثل بحث سازگاری نرم افزار)
در این صورت ساختار کرنل شما شبیه به یونیکس میشود
برای ویندوز هم چون درایورها به صورت باینری و کلوز سورس هستند شما باید از ساختار معماری NT استفاده کنید
یعنی تمام توابع و روابط بین انها برای مدیریت سخت افزار ها و درایورها و همچنین توابعی که برای ارتباط با کرنل ویندوز از انها استفاده میکنند را با همان نام ها در کرنل خود قرار دهید
که در این صورت ساختار کرنل شما شبیه به ویندوز NT میشود
یا اینکه فقط برای 2-3 سخت افزار تولیدی و مختص به شرکت خودتان درایور بنویسد و در کرنلتون قرار بدید مثلا کاری که اپل انجام میده و کلا قید همه (یا اکثریت) سخت افزارها دیگر را بزنید
مثلا یک سخت افزار گوشی تولید کنید و برای ان یک سیستم عامل بنویسید و فقط درایورها مربوط به ان سخت افزار را در کرنل تان قرار دهید
قسمت سوم هم مربوط به پایداری و قابلیت اطمینان سیستم عاملتون هست
اینجا جای هست نسبت به مورد اول و دوم ساده اما بسیار بسیار تاثیرگذار و مهم
این جای هست که باید معماری و ساختار سیستم عاملتان و روابط بین اجزای ان را با جزییات کامل مشخص کنید
مثلا کرنل شما شامل چه بخش های میشود
ایا درایور گرافیک در کرنل قرار میگیرد یا خارج کرنل در فضای کاربر
ایا درایور شبکه در کرنل قرار میگیرد یا خارج کرنل در فضای کاربر
ایا درایور هارد و ذخیره سازی ذر کرنل قرار میگیرد یا خارج کرنل در فضای کاربر
ایا درایور USB در کرنل قرار میگیرد یا خارج کرنل در فضای کاربر
ایا درایور کارت صدا در کرنل قرار میگیرد یا خارج کرنل در فضای کاربر
و .....
هرکدام از اینها را در کرنل قرار دهید سرعت اجرا ان بخش بیشتر میشود
اما همچنین پیچیدگی کرنل بیشتر میشود و درصورت کوچکترین ایرادی در کد درایور سیستم کرش میکند و همچنین حجم کرنل بیشتر میشود
انتخاب مواردی که در کرنل باید قرار بگیرد و روابط بین انها میشود همان معماری و ساختار سیستم عامل
مثل اسکلت ساختمان وقتی بنا شد همیشه ثابت است
اگر همه چیز خارج کرنل از قرار بدیم بازدهی سیستم میتواند افت زیادی کند
دلیلش هم به خاطر تعویض متن (context switching ) هست
سیستم در هر ثانیه هزاران بار بین برنامه های مختلف جابه جا میشود و هر بار که یک برنامه را استپ میکند
تمام رجیسترها پرچم ها و وضعیت پردازنده را ذخیره میکند و دوباره بازیابی میکند
حالا اگر یک برنامه بخواد به فلان سخت افزار مثلا گرافیک USB یا هارد یا و .... در خارج از فضای کرنل دسترسی پیدا کند
کرنل باید به طور مداوم برنامه را استپ کند به کرنل برود دوباره به حالت کاربر برود فلان درایور سخت افزار را اجرا کند پاسخش را بگیرد به کرنل برگرد و وضعیت رجیسترها را بازیابی کند و دوباره برنامه را اجرا کند این تعویض متن وقتی هزاران بار در ثانیه اجرا میشود خیلی روی کارای سیستم تاثیر میگذارد
مخصوصا در سخت افزارهای قدیم این مورد افت کارای خیلی شدید خودش را نشان میداد
در طراحی کرنل شما باید معماری و روابط بین اجزای کرنل و تمام توابع ان را کاملا مشخص کنید و تمام خطاهای که ممکن است در انها اتفاق بیفتد را کامل و دقیق مشخص و طریق برخورد با این خطاها و برطرف کردنشان را مشخص کنید و حتی سلسله مراتبی که اینها قرار هست اجرا شوند (به دیاگرام روابط بین اجزای کرنل لینوکس نگاه کنید تو گوگل بزنید linux kernel diagram)
یعنی لیست تمام توابع را با فلش نشان دهید که کدام تابع , کدام تابع دیگر را فراخوانی میکند وقتی این دیاگرام کشیده شده تمام افزاد میدانند چگونه سیستم عامل شما کار میکند بدون این دیاگرام هیچکسی از ساختار سیستم عامل شما سر درنمیارد
این نمودار و دیاگرام تنها راه ارتباطی دیگر برنامه نویسان برای درک سیستم عامل و کرنل شما است و دقیقا اینجا همانجای است که اکثریت افرادی یا گروهای که سیستم عامل مینویسند ان را رعایت نمیکنند مخصوصا در ایران و باعث میشود دیگران روش کارکرد سیستم عامل انها را درک نکنند و رهایش کنند
نوشتن سیستم عامل مثل پا گذاشتن در یک راه پر پیچ خم و پر از سنگلاخ است
اما نوشتن ساختار و دیاگرام سیستم عامل به همراه تمام توابع و روابط انها مثل اسفالت کردن ان مسیر است از صدها و هزاران ساعت کد نویسی عیب یابی بیهوده نجات میدهد اما باید قبلش این ساختار را با حوصله و به دقت تمام اجزاش را مشخص کرد
یا روی تخته سیاه یا دفتر یا روی نرم افزارهای طراحی در کامپیوتر
هرچقدر در این بخش وقت گذاشته شود نوشتن سیستم عامل لذت بخش تر راحتتر و سریعتر و دقیقتر و قابل فهم تر انجام میشود حتی اگر چتدین هفته یا ماه برایش وقت گذاشته شود کاملا ارزشش دارد این بخش ندید بگیرید صددرصد در گسترش سیستم عاملتون به سختی و بن بست میرسید
این بخش خیلی خیلی مهم هست
حالا از سختی های نوشتن سیستم عامل گفتیم از مزایاش هم بگم
برخلاف دیگر بخش ها دنیای کامپیوتر که خیلی پویا هست از نرم افزارها الگوریتم ها کتابخانه ها توسعه نرم افزار گرفته تا کامپلرها مرورگر ها هر چند سال یکبار عوض میشود و شما نیاز هست دانش تان را باهاش بروز کنید
ساختار کرنل سیستم عاملها تغییر نمیکنند و فقط پوسته یا رابط GUI عوض میشود و ساختار کرنل و روابط و توابعش اصلا عوض نمی شود اگر روزی عوض شود تمام نرم افزارها و درایورها از کار می افتند بخاطر همین نرم افزارهای قدیمی روی سیستم عامل جدید کار میکنند
کدها بهبود یا اصلاح پیدا میکنند اما ساختار اصلا تغییر نمیکند
پس دانش شما در مورد ساختار سیستم عامل یا کار کردش با گذر زمان قدیمی نمیشود
مثلا ساختار کرنل لینوکس بر اساس ساختار یونیکس هست که حدود 60-50 سال پیش طراحی و پیاده سازی شد
حالا کسی که 40-50 سال پیش کدی برای یونیکس نوشته احتمال زیاد اون کد یا بدون تعغیر یا با تغیر بسیار بسیار اندک روی لینوکس هم قابل اجرا است
و هنوز بعد 50-60 سال ساختار همان است و اگر 40 سال پیش متخصص و استاد کرنل یونیکس بوده باشید امروز هم با همان دانش قدیم همان جایگاه دارید و ممکنه تا 40-50 سال دیگه هم همینطور باشد !
اصلا یکی از دلایل اصلی رشد لینوکس همین مشابهت کامل ساختار کرنل لینوکس با ساختار کرنل یونیکس بود چون در دانشگاه های غربی کرنل یونیکس را اموزش میدادند دانشجوها و دیگر مهندسان براحتی ساختار لینوکس را درک کردند توانستند کرنل لینوکس را گسترش دهند و به اینجا برسانند
کرنل ویندوز هم با طراحی و معرفی ساختار کرنل NT که نزدیک به 30 سال پیش دیگر تعغییر نکرد و به همین دلیل است که نرم افزارهای قدیمی هنوز کار میکنند
فقط مایکروسافت رابط گرافیکی را کمی تعغیر و چیزهای جدید بهش اضافه میکند و کد کرنل را کمی بهبود میدهد اما ساختار کرنل را دست نمیزند و نامهای توابع کرنل را عوض نمیکند و همان کد قدیمی و اضافه شده را کامپایل و با نام یک سیستم عامل جدید به بازار عرضه میکند (ویندوز دارای حدود 20 میلیون خط کد است مایکروسافت نمیتواند هر دو سال اینقدر کد را بدون مشکل از اول بنویسد و سیستم عامل جدید بیرون دهد اصلا عقلانی نیست)
مورد اخر اگر شما موضوع سازگاری نرم افزاری و سازگاری سخت افزاری (درایور) را دور بریزید فقط از چند تا سخت افزار پشتیبانی کنید نوشتن یک سیستم عامل براحتی با کمتر از 10 هزار خط کد در طی چند ماه و کمتر از یکسال ممکن است به شرطی که قبلش روایط و ساختار کاملا مشخص و طراحی کرده باشید
بطور مثال سیستم عامل Minix 3.3 که از ساختار کرنل یونیکس استفاده میکند کلا 12 هزار خط کد است
امیدوارم این اطلاعات برای کسی مفید بوده باشد