این سری از مقالات به برنامه نویسی سطح پایین، یعنی معماری کامپیوتر، طراحی سیستم عامل، برنامه نویسی به زبان اسمبلی و حوزه های مرتبط اختصاص دارد. تاكنون دو حبري مشغول نوشتن هستند - و. برای بسیاری از دانش آموزان دبیرستانی، دانش آموزان و حتی برنامه نویسان حرفه ای، یادگیری این موضوعات بسیار دشوار است. ادبیات و دوره های زیادی به برنامه نویسی سطح پایین اختصاص داده شده است، اما به سختی می توان تصویری کامل و جامع از آنها به دست آورد. پس از خواندن یک یا دو کتاب در مورد اسمبلر و سیستم عامل، تصور اینکه حداقل به طور کلی چگونه این سیستم پیچیده از آهن، سیلیکون و بسیاری از برنامه ها - یک کامپیوتر - واقعاً چگونه کار می کند، دشوار است.
هرکسی به روش خود مشکل یادگیری را حل می کند. کسی ادبیات زیادی می خواند، کسی سعی می کند به سرعت به تمرین و درک در طول راه ادامه دهد، کسی سعی می کند همه چیزهایی را که در حال مطالعه است برای دوستان توضیح دهد. و ما تصمیم گرفتیم این رویکردها را ترکیب کنیم. بنابراین، در این دوره از مقالات، گام به گام نحوه نوشتن یک سیستم عامل ساده را نشان خواهیم داد. مقالات ماهیت کلی خواهند داشت، یعنی حاوی اطلاعات نظری جامعی نیستند، با این حال، ما همیشه سعی خواهیم کرد پیوندهایی به مطالب نظری خوب ارائه دهیم و به تمام سوالاتی که پیش می آید پاسخ دهیم. ما برنامه مشخصی نداریم، بنابراین تصمیمات مهم بسیاری در طول مسیر با در نظر گرفتن نظرات شما اتخاذ خواهد شد.
ممکن است ما عمداً فرآیند توسعه را به بنبست سوق دهیم تا به شما و خودمان اجازه دهیم تا عواقب یک تصمیم اشتباه را کاملاً درک کنیم و همچنین برخی از مهارتهای فنی را در آن تقویت کنیم. پس تصمیمات ما را تنها تصمیم واقعی نگیرید و کورکورانه ما را باور کنید. ما بار دیگر تاکید می کنیم که انتظار داریم خوانندگان در بحث مقالات فعال باشند، که باید بر روند کلی توسعه و نوشتن مقالات بعدی تأثیر زیادی بگذارد. در حالت ایده آل، من دوست دارم برخی از خوانندگان به مرور زمان به توسعه سیستم بپیوندند.
فرض میکنیم که خواننده قبلاً با اصول اسمبلی و زبانهای C و همچنین مفاهیم اولیه معماری رایانه آشنا است. یعنی ما توضیح نمی دهیم که رجیستر یا مثلا رم چیست. اگر دانش ندارید، همیشه می توانید به ادبیات اضافی روی بیاورید. فهرست کوتاهی از مراجع و لینک های سایت هایی با مقالات خوب در انتهای مقاله آمده است. همچنین مطلوب است که بتوان از لینوکس استفاده کرد، زیرا تمام دستورالعمل های کامپایل برای این سیستم ارائه خواهد شد.
و اکنون - به اصل مطلب نزدیک تر است. در ادامه مطلب من و شما برنامه کلاسیک سلام دنیا را می نویسیم. دنیای هالووین ما کمی خاص خواهد بود. این از هیچ سیستم عاملی اجرا نمی شود، بلکه به طور مستقیم، به اصطلاح "روی فلز خالی" اجرا می شود. قبل از اینکه مستقیماً به نوشتن کد بپردازیم، بیایید بفهمیم که دقیقاً چگونه می خواهیم این کار را انجام دهیم. و برای این کار باید فرآیند بوت شدن کامپیوتر را در نظر بگیرید.
بنابراین، کامپیوتر مورد علاقه خود را بردارید و بزرگترین دکمه را در واحد سیستم فشار دهید. ما یک محافظ صفحه نمایش شاد می بینیم ، واحد سیستم با خوشحالی با بلندگو جیر می کشد و پس از مدتی سیستم عامل بارگیری می شود. همانطور که می دانید، سیستم عامل بر روی هارد دیسک ذخیره می شود و در اینجا این سوال مطرح می شود: چگونه سیستم عامل به طور جادویی در RAM بوت شد و شروع به کار کرد؟
این را بدانید: سیستمی که در هر رایانه ای است مسئول این است و نام آن نه، ویندوز نیست، پیپ روی زبان شماست - به آن BIOS می گویند. نام آن مخفف Basic Input-Output System است، یعنی سیستم ورودی-خروجی اولیه. بایوس روی یک ریزمدار کوچک روی مادربرد قرار دارد و بلافاصله پس از فشار دادن دکمه بزرگ ON شروع به کار می کند. BIOS سه وظیفه اصلی دارد:
- همه دستگاههای متصل (پردازنده، صفحهکلید، مانیتور، رم، کارت گرافیک، سر، بازوها، بالها، پاها و دمها...) را شناسایی کرده و آنها را از نظر عملکرد آزمایش کنید. برنامه POST (Power On Self Test) این وظیفه را بر عهده دارد. اگر سخت افزار حیاتی پیدا نشود، هیچ نرم افزاری نمی تواند کمک کند و در این مرحله بلندگوی سیستم چیزی شوم را به صدا در می آورد و اصلاً به سیستم عامل نمی رسد. بیایید در مورد چیزهای غم انگیز صحبت نکنیم، بیایید فرض کنیم که یک رایانه کاملاً کار می کنیم، خوشحال باشیم و به بررسی عملکرد دوم BIOS ادامه دهیم:
- ارائه سیستم عامل با مجموعه ای از عملکردهای اساسی برای کار با آهن. به عنوان مثال، از طریق توابع BIOS، می توانید متن را روی صفحه نمایش دهید یا داده ها را از صفحه کلید بخوانید. به همین دلیل است که به آن سیستم ورودی-خروجی اولیه می گویند. به طور معمول، سیستم عامل از طریق وقفه به این توابع دسترسی پیدا می کند.
- راه اندازی لودر سیستم عامل. در این مورد، به عنوان یک قاعده، بخش بوت خوانده می شود - اولین بخش حامل اطلاعات (فلاپی دیسک، دیسک سخت، سی دی، درایو فلش). ترتیب نظرسنجی رسانه را می توان در BIOS SETUP تنظیم کرد. بخش بوت شامل برنامه ای است که گاهی اوقات بوت لودر اصلی نامیده می شود. به طور کلی، وظیفه بوت لودر راه اندازی سیستم عامل است. فرآیند بارگذاری یک سیستم عامل می تواند بسیار خاص و بسیار وابسته به ویژگی های آن باشد. بنابراین، بارگذار اولیه مستقیماً توسط توسعه دهندگان سیستم عامل نوشته می شود و در هنگام نصب در بخش بوت نوشته می شود. هنگامی که بوت لودر راه اندازی می شود، پردازنده در حالت واقعی است.
تصویر سطح درایو دیسک را نشان می دهد. فلاپی دیسک دارای 2 سطح است. در هر سطح آهنگ های حلقه ای شکل (آهنگ) وجود دارد. هر مسیر به قطعات کوچک کمانی شکل به نام بخش تقسیم می شود. بنابراین، از نظر تاریخی، یک بخش فلاپی دیسک دارای اندازه 512 بایت است. اولین سکتور روی دیسک، بخش بوت، توسط BIOS "در قسمت حافظه صفر با offset 0x7С00 خوانده می شود و سپس کنترل به این آدرس منتقل می شود. بوت لودر معمولاً نه خود سیستم عامل، بلکه دیگری را در حافظه بارگذاری می کند. برنامه بوت لودر بر روی دیسک ذخیره می شود، اما به دلایلی (به احتمال زیاد، این دلیل اندازه است) که در یک بخش قرار نمی گیرد. و از آنجایی که تاکنون نقش سیستم عامل ما توسط یک Helloworld پیش پا افتاده ایفا می شود، هدف اصلی ما این است که کامپیوتر را به وجود سیستم عامل ما باور کند، حتی اگر در یک بخش باشد، و آن را اجرا کنید.
بوت سکتور چگونه مرتب شده است؟ در رایانه شخصی، تنها شرط لازم برای بخش بوت این است که دو بایت آخر آن حاوی مقادیر 0x55 و 0xAA، امضای بخش بوت باشد. بنابراین، کم و بیش روشن است که چه کاری باید انجام دهیم. بیا کد بنویسیم! کد بالا برای اسمبلر yasm نوشته شده است.
بخش. متن
استفاده 16
org 0x7C00 ; برنامه ما در 0x7C00 بارگذاری شده است
شروع:
mov ax , cs
mov ds , ax ; بخش داده را انتخاب کنید
mov si , پیام
cld ; جهت دستورات رشته
mov ah، 0x0E ; شماره عملکرد بایوس
mov bh , 0x00 ; صفحه حافظه ویدیویی
puts_loop:
lodsb ; کاراکتر بعدی را در al بارگذاری کنید
تست al, al ; کاراکتر null به معنای پایان رشته است
jz puts_loop_exit
int 0x10 ; فراخوانی تابع BIOS
jmp puts_loop
puts_loop_exit:
jmp$; چرخه ابدی
پیام:
db "سلام دنیا!" 0
تمام کردن:
بار 0x1FE - پایان + شروع db 0
db 0x55، 0xAA ; امضای بخش بوت
این برنامه کوتاه به تعدادی توضیحات مهم نیاز دارد. خط org 0x7C00 مورد نیاز است تا اسمبلر (به معنای برنامه، نه زبان) به درستی آدرس برچسب ها و متغیرها (puts_loop، puts_loop_exit، پیام) را محاسبه کند. بنابراین ما به او می گوییم که برنامه در حافظه 0x7C00 بارگذاری می شود.
در خطوط
mov ax , csبخش داده (ds) برابر با بخش کد (cs) تنظیم شده است، زیرا در برنامه ما هر دو داده و کد در یک بخش ذخیره می شوند.
mov ds , ax
سپس پیام «Hello World!» کاراکتر به کاراکتر در حلقه نمایش داده می شود. برای این کار از تابع 0x0E وقفه 0x10 استفاده می شود. گزینه های زیر را دارد:
AH = 0x0E (شماره تابع)
BH = شماره صفحه ویدیو (هنوز زحمت نکشید، 0 را نشان دهید)
AL = کد کاراکتر ASCII
در خط "jmp $" برنامه آویزان می شود. و به درستی، نیازی به اجرای کد اضافی برای او نیست. با این حال، برای اینکه کامپیوتر دوباره کار کند، باید راه اندازی مجدد شود.
در سطر "times 0x1FE-finish+start db 0" بقیه کد برنامه (به جز دو بایت آخر) با صفر پر می شود. این کار به این صورت انجام می شود که پس از کامپایل، امضای بخش بوت در دو بایت آخر برنامه ظاهر شود.
ما به نوعی کد برنامه را فهمیدیم، اکنون بیایید سعی کنیم این شادی را کامپایل کنیم. برای کامپایل، در واقع به یک اسمبلر نیاز داریم - آنچه در بالا ذکر شد
ابتدا برنامه نویسی را یاد بگیرید.دانش اسمبلر ضروری است. به شدت توصیه می شود که از سایر زبان های برنامه نویسی سطح پایین تر مانند C نیز آگاهی داشته باشید.
تصمیم بگیرید که در کدام دستگاه می خواهید سیستم عامل را بوت کنید.این می تواند یک سی دی، دی وی دی، درایو فلش، هارد دیسک یا رایانه دیگری باشد.
تصمیم بگیرید که می خواهید سیستم عامل شما چگونه باشد.آیا باید یک نسخه کامل از سیستم عامل با رابط کاربری گرافیکی (GUI) باشد یا شاید چیزی حداقلی تر باشد؟ قبل از شروع فرآیند باید بدانید که به کدام سمت بروید.
بررسی کنید که سیستم عامل شما از کدام پلتفرم پردازنده پشتیبانی می کند. AI-32 و x86_64 دو نسخه رایج برای رایانه های شخصی هستند، بنابراین می توان آنها را بهترین انتخاب در نظر گرفت.
تصمیم بگیرید که آیا ترجیح میدهید همه کارها را خودتان از ابتدا انجام دهید، یا هستههایی وجود دارند که میخواهید روی آنها بسازید. Linux From Scratch پروژه ای برای کسانی است که می خواهند، به عنوان مثال، توزیع لینوکس خود را ایجاد کنند.
انتخاب کنید که آیا می خواهید از بوت لودر خود استفاده کنید یا از بوت لودر بزرگ متحد (GRUB) از پیش ساخته شده. از آنجایی که کدنویسی برنامه بوت خود نیاز به نرم افزار کامپیوتری و دانش بایوس دارد، این می تواند برنامه برنامه نویسی هسته زنده را به عقب براند.
در مورد زبان برنامه نویسی که قرار است استفاده کنید تصمیم بگیرید.البته، توسعه سیستم عامل به زبانی مانند پاسکال یا بیسیک کاملاً امکان پذیر است، اما بهتر است آن را به زبان C یا اسمبلی بنویسید. اسمبلر کاملا ضروری است، زیرا برخی از بخش های مهم سیستم عامل نیاز به دانش این زبان خاص دارد. از سوی دیگر، C++ حاوی کلمات کلیدی مورد نیاز برای اجرای کامل سیستم عامل است.
- برای ساختن یک سیستم عامل با استفاده از کدهای C یا C++، مطمئناً از کامپایلرهای یکی پس از دیگری استفاده خواهید کرد. این بدان معنی است که شما باید کتابچه راهنمای/دستورالعمل ها/مستندات کامپایلر انتخابی C/C++ را که همراه با نرم افزار ارائه می شود یا از وب سایت توزیع کننده موجود است، مطالعه کنید. شما باید چیزهای پیچیده زیادی را در مورد کامپایلر یاد بگیرید و برای بهبود C++ باید طرحواره و ABI آن را یاد بگیرید. از شما انتظار می رود که فرمت های مختلف کار اجرایی (ELF، PE، COFF، باینری معمولی، و غیره) را درک کنید و متوجه شوید که فرمت اصلی ویندوز، PE (.exe)، دارای حق چاپ است.
یک رابط برنامه نویسی برنامه (API) را انتخاب کنید.یک مجموعه از APIهای خوب POSIX است، زیرا به خوبی مستند شده است. همه سیستمهای یونیکس حداقل پشتیبانی جزئی از POSIX دارند، بنابراین پیوستن برنامههای یونیکس به سیستم عامل شما امری بیاهمیت است.
در مورد یک طرح تصمیم بگیرید.هسته های یکپارچه و میکروکرنل وجود دارد. هستههای یکپارچه همه سرویسهای موجود در هسته را اجرا میکنند، در حالی که میکروکرنلها دارای یک هسته کوچک همراه با اجرای سرویس سفارشی هستند. به طور کلی، هستههای یکپارچه سریعتر هستند، اما میکروکرنلها جداسازی و محافظت بهتری در برابر خطاهای احتمالی دارند.
توسعه و کار تیمی را در نظر بگیرید.بنابراین، برای حل مشکلات بزرگ به زمان کمتری نیاز خواهید داشت که به شما امکان می دهد در زمان کوتاه تری سیستم عامل بهتری ایجاد کنید.
هارد دیسک خود را به طور کامل پاک نکنید.به یاد داشته باشید، فرمت کردن یک درایو تمام اطلاعات شما را برای همیشه پاک می کند! از GRUB یا مدیر دیگری برای بوت کردن رایانه خود از یک سیستم عامل دیگر استفاده کنید تا زمانی که نسخه شما کاملاً کاربردی شود.
از کوچک شروع کنید.قبل از اینکه به سراغ عناصر پیچیده مانند مدیریت حافظه و چندوظیفه بروید، ابتدا به موارد کوچک مانند نمایش متن و وقفه ها توجه کنید.
یک نسخه پشتیبان از آخرین نسخه کار نگه دارید.این به شما آرامش می دهد در صورتی که مشکلی در نسخه فعلی سیستم عامل یا برنامه های توسعه آینده شما کاملاً اشتباه باشد. در صورتی که کامپیوتر شما خراب شود و نتواند بوت شود، همانطور که خودتان متوجه شدید، فرصتی عالی برای داشتن نسخه دوم برای کار با آن است تا بتوانید مشکلات موجود را عیب یابی کنید.
سیستم عامل جدید خود را در ماشین مجازی تست کنید.به جای اینکه هر بار که تغییراتی ایجاد میکنید یا فایلها را از رایانه کاری خود به دستگاه آزمایشی خود انتقال میدهید، رایانه خود را مجدداً راهاندازی کنید، میتوانید از برنامهای برای اجرای سیستمعامل در یک ماشین مجازی در حالی که سیستمعامل فعلی شما به کار خود ادامه میدهد استفاده کنید. برنامه های کاربردی VM شامل VMWare (که یک سرور رایگان نیز دارد)، منبع باز جایگزین، Bochs، Microsoft Virtual PC (ناسازگار با لینوکس) و XVM VirtualBox است.
نسخه انتشاری را منتشر کنید.این به کاربران اجازه می دهد تا در مورد نقص های احتمالی در سیستم عامل شما به شما اطلاع دهند.
سیستم عامل نیز باید کاربرپسند باشد، بنابراین فراموش نکنید که ویژگی های مفیدی را اضافه کنید که بخشی جدایی ناپذیر از طراحی شما خواهد شد.
- پس از تکمیل توسعه، در نظر بگیرید که آیا میخواهید کد را در دسترس عموم قرار دهید یا حقوق خصوصی برای آن تنظیم کنید.
- اگر میخواهید سیستم شما قابل دوام باشد، حتماً ویژگیهای امنیتی را در اولویت خود قرار دهید.
- یک پروژه توسعه سیستم عامل را با هدف یادگیری نحوه برنامه نویسی شروع نکنید. اگر C، C++، Pascal، یا هر زبان و ویژگی مرتبط دیگری، از جمله انواع اشاره گر، عملیات بیت سطح پایین، سوئیچینگ بیت، اسمبلر درون خطی و غیره را نمی دانید، پس هنوز برای ساختن آماده نیستید. سیستم عامل
- برای کمک به بهبود سیستم عامل خود، پورتال هایی مانند OSDev و OSDever را مرور کنید. لطفاً توجه داشته باشید که برای اکثر مسائل، جامعه OSDev.org ترجیح میدهد به جای پیوستن به انجمن، خودتان به محتوای سایت دسترسی داشته باشید. اگر همچنان تصمیم به پیوستن به جمع اعضای انجمن دارید، باید پیش نیازهای خاصی برای این امر وجود داشته باشد. شما باید دانش کاملی از C یا C++ و زبان اسمبلی x86 داشته باشید. همچنین باید مفاهیم کلی و پیچیده برنامه نویسی مانند لیست های پیوندی، صف و غیره را درک کنید. جامعه OSDev به صراحت در قوانین خود می گوید که هیچ کس قرار نیست از برنامه نویسان جدید مراقبت کند. اگر در حال تلاش برای توسعه یک سیستم عامل هستید، ناگفته نماند که در برنامه نویسی یک "خدا" هستید. همچنین باید دفترچه راهنمای پردازنده را برای معماری انتخابی خود بخوانید. به عنوان مثال x86 (اینتل)، ARM، MIPS، PPC و غیره. چنین اشاره ای به ساختار پردازنده را می توان به راحتی با جستجو در گوگل ("Intel Manuals"، "ARM manuals" و غیره) یافت. برای پرسیدن سوالات واضح در انجمن OSDev.org ثبت نام نکنید. این فقط به پاسخ هایی مانند "دستورالعمل f***ing" را بخوانید. برای شروع، باید ویکیپدیا، کتابچه راهنمای ابزارهای مختلفی را که قرار است استفاده کنید، بخوانید.
- نقاط مرده احتمالی و سایر خطاها را بررسی کنید. اشکالات، بن بست ها و سایر مسائل می توانند بر طراحی سیستم عامل شما تأثیر بگذارند.
- اگر راه سادهتری میخواهید، توزیعهای لینوکس مانند Fedora Revisor، Custom Nimble X، Puppy Remaster، PCLinuxOS mklivecd یا SUSE Studio و SUSE KIWI را تصور کنید. با این حال، سیستمعاملی که ایجاد میکنید متعلق به شرکتی است که برای اولین بار این سرویس را معرفی کرده است (اگرچه شما حق دارید آزادانه آن را توزیع کنید، آن را تغییر دهید و هر طور که میخواهید تحت GPL اجرا کنید).
- یک راه حل خوب ایجاد یک پارتیشن کاملا جدید برای سیستم عامل در حال توسعه است.
هشدارها
- بازنویسی بی دقت سیستم عامل روی هارد دیسک می تواند به طور کامل به آن آسیب برساند. مراقب باش
- تا دو هفته دیگر یک سیستم کاملاً تمام شده نخواهید داشت. با یک سیستم عامل قابل بوت شروع کنید و سپس به چیزهای جالب تر بروید.
- اگر کاری بی پروا انجام دهید، مانند نوشتن بایت های تصادفی در پورت های ورودی/خروجی دلخواه، سیستم عامل خود را از بین می برید و می توانید (در تئوری) سخت افزار خود را بسوزانید.
- انتظار نداشته باشید که ساخت یک سیستم عامل با کیفیت آسان باشد. بسیاری از وابستگی های متقابل پیچیده وجود دارد. به عنوان مثال، برای اینکه یک سیستم عامل بتواند چندین پردازنده را مدیریت کند، مدیر حافظه شما باید مکانیسمهای "قفل کردن" را برای جلوگیری از دسترسی همزمان پردازندههای اضافی به یک منبع داشته باشد. بلوکهای مورد استفاده وجود یک زمانبندی را فرض میکنند تا اطمینان حاصل شود که فقط یک پردازنده در هر زمان معین به یک منبع حیاتی دسترسی دارد، در حالی که بقیه بیکار هستند. با این حال، عملکرد زمانبندی بستگی به حضور مدیر حافظه دارد. این نمونه ای از وابستگی بن بست است. هیچ راه استانداردی برای حل چنین مشکلاتی وجود ندارد. انتظار می رود هر سازنده سیستم عامل به اندازه کافی مهارت داشته باشد تا راه حل خود را ارائه دهد.
منابع
چه چیزی نیاز خواهید داشت
- یک کامپیوتر
- پردازنده ای که قرار است روی آن بسازید
- حافظه دسترسی تصادفی (RAM) کافی برای ماشین مجازی
- سیستمعامل اصلی (برای توسعه کد منبع اسمبلر (و غیره) و ساخت و بستهبندی اولیه استفاده میشود؛ سیستمعامل شما در نهایت تبدیل به اولیه میشود)
- ویرایشگر کد رنگ نحوی (زمانی که محیط توسعه یکپارچه در دسترس نباشد استفاده می شود)
- کامپایلر
- درایو CD/DVD
ایلیا الکساندروف
سیستم عامل خود را بر اساس لینوکس بسازید
صدها توزیع لینوکس در آنجا وجود دارد، و مشخص نیست که چند توزیع دیگر ظاهر می شود. ده ها شرکت و هزاران برنامه نویس برای ایجاد بهترین پروژه لینوکس با هم رقابت می کنند و در این میان هر کاربر با تجربه می تواند نویسنده یک سیستم رایانه شخصی خانگی باشد که از محصولات غول های صنعت فناوری اطلاعات کم ندارد.
در طول سال ها کار با لینوکس، من از تعداد زیادی توزیع مختلف استفاده کرده ام: Mandriva، Fedora، SlackWare، Debian، Ubuntu و بسیاری دیگر. برخی از پروژه ها را بیشتر دوست داشتم، برخی را کمتر. اما در همه توزیع ها، ناگزیر باید با کاستی های جدی دست و پنجه نرم کرد که کار را بسیار دشوار می کرد. یکی از منابع بسیار خواستار است، دیگری تمام تجهیزات لازم را پشتیبانی نمی کند، سومی فاقد نرم افزارهای مختلف است. آن وقت بود که به یاد حکمت معروف شرقی افتادم: اگر لازم است کاری را به خوبی انجام دهی، خودت انجامش بده.
لینوکس از ابتدا
من تنها کسی نیستم که تصمیم گرفتم نسخه لینوکس خود را شروع کنم - سیستم عاملی که در آن قسمت پایه سیستم و هسته به عنوان پایه در نظر گرفته می شود، اما جایی که حتی یک کیلوبایت اضافی از آن وجود نخواهد داشت. توسعه دهنده، یعنی از طرف شما. تعداد زیادی از توزیعهای لینوکس که نیازهای کاربران را برآورده نمیکنند، جرارد بیکمنز را بر آن داشت تا یک کیت توزیع ایجاد کند که همه را قادر میسازد فقط با اجزا و عملکردهایی که نیاز دارند سیستمی بسازند.
میل یک برنامه نویس با استعداد منجر به پروژه Linux from Scratch (www.linuxfromscratch.org) شد که به اختصار LFS نامیده می شود. این پروژه به شما اجازه می دهد تا از ابتدا، از کدهای منبع، سیستم عامل مبتنی بر لینوکس خود را بسازید. کامپایل LFS روی رایانه ای با سیستم لینوکس از قبل نصب شده انجام می شود، با این حال، یک Live-CD "پیشرفته" مانند Knoppix نیز مناسب است.
در عین حال، سیستم لینوکس مورد استفاده برای مونتاژ می تواند هر نوع باشد - فقط وجود یک کامپایلر و کتابخانه های سیستم مورد نیاز است. Linux From Scratch را به سختی می توان یک توزیع به معنای معمول کلمه نامید - چیزی شبیه نرم افزار کمکی است که همراه با بخش اصلی سیستم عامل به شما امکان می دهد نسخه منحصر به فرد خود را از سیستم عامل ایجاد کنید.
همانطور که می دانید لینوس توروالدز سیستم عامل خود را با شعار "فقط برای سرگرمی!" - یعنی فقط برای سرگرمی. باید اعتراف کرد که LFS واقعاً اغلب در سرورها یافت نمی شود ، به عنوان یک قاعده ، علاقه مندان به رایانه از این سیستم استفاده می کنند. نصب و کار با لینوکس از ابتدا به شما کمک می کند تا رابطه بین اجزای سیستم عامل را درک کنید، که برای توسعه یک توزیع لینوکس و نه تنها بر اساس LFS مفید خواهد بود. بنابراین، LFS تا حد زیادی برای افرادی طراحی شده است که فرآیند ساخت توزیع خود برای آنها هیجان انگیز و جالب است - و باور کنید چنین افراد زیادی وجود دارد.
بنابراین، اگر آماده هستید یک روز کامل (یا حتی بیشتر) را برای طراحی سیستم صرف کنید، توصیه می کنم از سایت (2) LFS-packages-6.0، LFS-book دانلود کنید و به خواندن این مقاله ادامه دهید.
پارتیشن بندی یک دیسک و ایجاد درخت دایرکتوری
برای درک بهتر مواد، کل دوره فرآیند را به صورت کلی توصیف می کنیم (شکل 1 را ببینید).
در مرحله اول، با استفاده از یک کیت توزیع از قبل نصب شده یا LiveCD، دیسک شکسته می شود. یک پارتیشن بر روی هارد دیسک برای سیستم جدید اختصاص داده شده است. پس از آن، در این پارتیشن، باید تمام برنامه های لازم و هسته سیستم را به صورت استاتیک کامپایل کنید. سپس، دایرکتوری ریشه به یک پارتیشن دیسک سخت که برای سیستم عامل جدید ما رزرو شده است، تغییر می کند. باید کامپایل را تکرار کنید، اما این بار نرم افزار باید به صورت پویا ساخته شود (تفاوت بین کامپایل پویا و استاتیک در زیر توضیح داده خواهد شد). آخرین مرحله شامل ساخت کتابخانه حیاتی glibc و پیکربندی سیستم عامل نصب شده است. همانطور که می بینید، لازم نیست کار خاصی انجام دهید.
در طول فرآیند، دستیار اصلی شما مستندات بسته کتاب LFS است که ترجمه روسی آن را میتوانید در اینجا بیابید: http://multilinux.sakh.com/download/lfsbook.tar.bz2. کتاب جزئیات هر مرحله از ایجاد یک سیستم عامل را نشان می دهد، بنابراین اگر با مشکلاتی مواجه شدید، حتما به این راهنما مراجعه کنید (این مقاله برای جایگزینی چنین اسناد گسترده ای در نظر گرفته نشده است).
ما یک پارتیشن جدید ایجاد می کنیم - در مورد من / dev/hda5 است، زیرا پارتیشن /dev/hda1 قبلاً توسط Linux Slackware نصب شده روی هارد دیسک اشغال شده است. توصیه می شود ابتدا از سیستم یک نسخه پشتیبان تهیه کنید تا در صورت آسیب بتوانید آن را بازیابی کنید، البته احتمال این امر نزدیک به صفر است. و در اینجا، فکر می کنم، همه چیز واضح است: ما مقدار مورد نیاز (23 گیگابایت کافی است) را برای دایرکتوری ریشه اختصاص می دهیم، فضایی معادل دو برابر مقدار رم برای پارتیشن swap، در صورت تمایل، می توانید پارتیشن های جداگانه ای برای فهرست اصلی (/ home) و برای / بوت. با این حال، گزینه پارتیشن بندی مورد علاقه بسیاری - تخصیص تمام فضای موجود منهای swap به دایرکتوری ریشه و سپس ایجاد خود swap - هنگام ساخت LFS نیز کاملاً قابل قبول است. در رایانه نویسنده، هم Linux Slackware، که سیستم عامل اصلی است، و هم LFS از یک هارد دیسک استفاده می کنند، با این حال، نصب LFS بر روی هارد دیسک دیگر نیز دشوار نیست.
سیستم فایل را به صلاحدید خود انتخاب کنید: هیچ مشکلی با Ext3 و ReiserFS تحت LFS وجود ندارد. اما طرفداران XFS باید ناامید شوند - تلاش ها برای استفاده از Linux From Scratch برای کار با این FS موفقیت آمیز نبوده است.
اکنون پارتیشن رزرو شده برای سیستم عامل جدید را سوار می کنیم:
$ mount /dev/hda5 /mnt/mylin
برای راحتی، اجازه دهید متغیر MYLIN را تعریف کنیم:
$ صادرات MYLIN=/mnt/mylin
عالی است، برای کار بیشتر بهتر است یک کاربر mylin جداگانه ایجاد کنید که ما آن را به عنوان صاحب پارتیشن نصب شده اختصاص می دهیم.
$ useradd mylin
$ chown -R mylin $MYLIN
شما باید یک درخت دایرکتوری در ریشه پارتیشن جدید ایجاد کنید:
$ سی دی $MYLIN
$ mkdir –p bin boot dev و غیره home lib mnt opt root sbin usr/(X11R6,local) var
در دایرکتوری های usr, usr/X11R6, usr/local ما ساختار لازم را ایجاد می کنیم: زیر شاخه ها bin و غیره شامل، lib، sbin، share، src.
سپس همین کار را برای دایرکتوری های /var و /opt سیستم آینده انجام خواهیم داد:
$ mkdir var/(cache,lib,local,lock,log,opt,run,spool)
$ mkdir opt/(bin,doc,include,info,lib,man)
فراموش نکنیم که سلسله مراتب عمیق تری مانند /usr/share/man/man1 وجود دارد. اما حجم مقاله اجازه نمی دهد در اینجا تمام اطلاعات مربوط به ساختار درخت فایل ارائه شود، بنابراین شما باید از سند استاندارد سلسله مراتبی سیستم فایل (موجود در: http://linux-ve.net/MyLDP/) استفاده کنید. file-sys/fhs-2.2-rus)، یا ساختار سیستم عامل خانواده لینوکس را که قبلاً نصب کرده اید، به دقت مطالعه کنید. پس از آماده سازی هارد، به مونتاژ استاتیک می رویم.
مونتاژ استاتیک
چرا از مونتاژ استاتیک استفاده می کنیم؟ با کامپایل استاتیک، کد منبع کتابخانه به کد برنامه متصل می شود که منجر به افزایش اندازه آن می شود، اما در عین حال یکپارچگی حفظ می شود. با کامپایل پویا، کتابخانه در یک فایل جداگانه قرار دارد که در صورت نیاز توسط اپلیکیشن ها قابل دسترسی است. در نتیجه، همه برنامه ها با یک نسخه از کتابخانه کار می کنند
اما هنگامی که از دستور chroot برای تنظیم دایرکتوری ریشه برای سیستم تازه اسمبل شده استفاده می کنیم، کتابخانه های "والد"، سیستم نصب شده، واقع در / lib، / usr / lib و موارد دیگر، دیگر در دسترس نخواهند بود، بنابراین به صورت پویا برنامه های کامپایل شده از کار کردن خودداری می کنند، علاوه بر این، سازگاری نسخه توسط هیچ کس تضمین نشده است.
برای جلوگیری از این امر، ابتدا تمام نرم افزارهای لازم برای سیستم آینده خود را به صورت استاتیک کامپایل می کنیم. بیایید با پوسته bash شروع کنیم. (طرفداران ZSH یا TCSH می توانند مفسرهای مورد علاقه خود را پس از نصب سیستم نصب کنند، اما استفاده از آنها در مرحله ساخت توسط نویسنده LFS در نظر گرفته نشده است). باید بررسی کنید که آیا فایل /usr/lib/libcurses.a را دارید یا نه، بسته ncursesdev را نصب کنید. همه بستهها باید با پرچمهای ساخت استاتیک ساخته شوند: «--enable-static-link»، «--disable-shared» یا «--static». کدام یک در هر مورد خاص مناسب است را می توان در مستندات یک بسته خاص یا از خروجی یک اسکریپت پیکربندی اجرا شده با پارامتر "--help" یافت.
$ ./configure --help
برای اینکه برنامه های کامپایل شده بعدی را با برنامه های "دینامیک" اشتباه نگیریم، یک دایرکتوری ویژه برای آنها ایجاد می کنیم:
$ mkdir $MYLIN/stat
هنگام ساخت و نصب بسته ها، فراموش نکنید که پارامتر "--prefix=$MYLIN/stat" را برای انتقال فایل ها به این دایرکتوری اضافه کنید. و در نهایت bash را نصب کنید:
$ ./configure --enable-static-link --prefix=$MYLIN/stat
$ساخت
$ را نصب کنید
بقیه بسته های لازم را نیز به همین ترتیب جمع آوری می کنیم. : binutils، bzip2، textutils، texinfo، tar، sh-utils، gcc، grep، gzip، gawk، diffutils، fileutils، make، patch، sed،و در واقع لینوکس کرنل.
بله، هنگام کامپایل کرنل، فراموش نکنید که برای نسخه های قدیمی هسته (2.2.x-2.4.x) باید از gcc 2.95 استفاده کنید و برای نسخه فعلی 2.6.x توصیه می شود از gcc 3.x استفاده کنید تا هیچ مشکلی وجود ندارد
فراموش نکنید که به بخش های مربوطه کتاب LFS نگاه کنید، در مورد این و بسیاری از تفاوت های ظریف دیگر می گوید. به طور کلی، کامپایل هسته در LFS با روش مشابهی که هنگام استفاده از کیت توزیع نصب شده بر روی HDD انجام می شود، تفاوتی ندارد. منبع هسته را در $MYLIN/usr/src/linux-2.6.xx از حالت فشرده خارج کنید، سپس آن را با اجرای:
$ make menuconfig
فرآیند پیکربندی پارامترهای هسته بارها در اینترنت توضیح داده شده است (6)، به سختی نیازی به پرداختن به جزئیات بیشتر در این مورد نیست. سپس دستورات زیر را در پوشه منبع Linux-kernel می دهیم:
$ ساخت bzImage
$ ساخت ماژول
همه چیز، در $MYLIN/usr/src/linux-2.6.xx/arch/i386/boot/bzImage هسته جدید است.
سپس، $MYLIN/etc/passwd و $MYLIN/etc/group را ایجاد می کنیم. در اولی، ما تا کنون تنها کاربر - root را با هر رمز عبور و در دومی، گروه های کاربری را تجویز می کنیم (برای شروع با یک گروه ریشه نیز کافی است).
این کار آماده سازی ما را برای مرحله بعدی کامل می کند و ما به مونتاژ پویا ظریف تر می رویم.
مونتاژ دینامیک
اکنون باید دایرکتوری ریشه را به /mnt/mylin تغییر دهیم، جایی که فقط از ابزارهای کامپایل شده استاتیک استفاده می کنیم - دیگر نمی توانیم به کمک ابزارهای سیستم عامل "والد" متوسل شویم. ما این دستور را در کنسول می دهیم:
$ chroot $MYLIN/usr/bin/env -i
>HOME=/root TERM=$TERM PS1='u:w$'
>PATH=/bin: /usr/bin: /sbin: /usr/sbin: /stat/sbin
>/stat/bin/bash --ورود به سیستم
با این دستور مسیرهای فایل های اجرایی، نوع ترمینال، مفسر و نوع خط فرمان را مشخص کردیم.
برای اینکه برخی از برنامه ها کار کنند، باید فایل سیستم proc را روی سیستم جدید نصب کنید.
$ mount proc /proc -t proc
حساس ترین لحظه فرا رسیده است. ساخت کتابخانه glibc این بیشترین مسئولیت را دارد زیرا اکثر برنامه های ضروری بدون آن کار نمی کنند و استفاده از لینوکس بدون کتابخانه اصلی فایده ای ندارد. از طرف دیگر ساختن glibc اغلب مشکلات زیادی را ایجاد می کند.
هنگام ساخت، ما پارامتر "--prefix=$MYLIN/stat" را مشخص کردیم، بنابراین هنگام تغییر ریشه، تمام بسته های استاتیک ساخته شده در فهرست /stat پارتیشن جدید سیستم عامل قرار می گیرند.
بنابراین، بایگانی glibc-2.x.x.tar.gz را باز کنید (به عنوان مثال، در پوشه /usr/src/) و به دایرکتوری glibclinuxthreads بروید. با توجه به اینکه در این مرحله شناسایی کاربر با نام در سیستم غیرممکن است (فقط به دلیل عدم وجود glibc و سایر کتابخانه ها) و نصب glibc نیاز به کمی تغییر کد منبع را داریم. مفسر پرل که ما نداریم.
نام کاربری ریشه در login/Makefile را با uid آن، یعنی 0 جایگزین می کنیم، و متغیر $PERL در malloc/Makefile باید با مسیر مفسر - /usr/bin/perl - جایگزین شود و به سادگی این کار را انجام می دهد. در طول پیکربندی نادیده گرفته شود.
$ /usr/src/glibc-2.x.x/configure --prefix=/usr --enable-add-ons --libexecdir=/usr/bin &&
& درست کن
و نصب کنید
$ make localedata/install-locales
$ /stat/bash --login
اگر همه کارها را به درستی انجام داده باشید، glibc کامپایل می شود، "root" در نهایت در اعلان ظاهر می شود، و همه برنامه ها را می توان به صورت پویا دوباره کامپایل کرد.
نصب کرنل را تمام کنید:
$ make modules_install
$ را نصب کنید
برای انتقال هسته جدید به پوشه /boot، یک دستور دیگر را اجرا کنید:
$ را نصب کنید
ما همه برنامه های نصب شده و برخی از برنامه های جدید را جمع آوری می کنیم، اکنون بدون پرچم های کامپایل ایستا. ما نیاز داریم (در این مرحله بسیار مهم است که کامپایل همه موارد زیر را فراموش نکنید) (جدول 1 را ببینید).
جدول 1. مجموعه مورد نیاز از بسته ها برای مونتاژ
تنظیم خودکار |
grep |
پرل |
خودروسازی |
groff |
|
بش |
gzip |
procinfo |
bin86 |
لوازم |
|
بینوتیل |
کمتر |
pmisc |
bzip2 |
reiserfs-progs |
|
دیفیوتیل ها |
libtool |
|
e2fsprogs |
لیلو |
sh-utils |
سایه |
||
فایل |
ساختن |
syslogd |
fileutils |
makedev |
sysvinit |
یافته ها |
صفحات مرد |
|
خم شدن |
مدوتیل ها |
texinfo |
گاو |
نفرین می کند |
پارچه های پارچه ای |
netkitbase |
استفاده از لینوکس |
|
بیسون |
ابزارهای شبکه |
|
دریافت متن |
پچ |
پس از انجام کامپایل مجدد پویا، می توانید دایرکتوری را با بسته های ایستا ساخته شده حذف کنید:
$ rm -rf /stat
می توانید نفس راحتی بکشید و قهوه بنوشید - سخت ترین و روتین پشت سر گذاشته می شود. ما به مرحله بعدی می رویم - پیکربندی اولیه سیستم ما.
پیکربندی اولیه سیستم
قبل از ادامه پیکربندی، توجه داشته باشم که همه تغییرات باید در فایل های دایرکتوری سیستم عامل جدید و نه سیستم والد انجام شود.
برای تنظیم زمان سیستم، اجازه دهید فایل /etc/sysconfig/clock حاوی فقط یک خط ایجاد کنیم:
UTC=0
اکنون ساعت رایانه زمان را در منطقه زمانی شما نمایش می دهد - به شرطی که مقدار زمان در BIOS به درستی تنظیم شده باشد.
بیایید یک نام برای رایانه بگذاریم:
echo "HOSTNAME=my_linux" > /etc/sysconfig/network
اکنون پارتیشن هایی را که سیستم باید در هنگام بوت در /etc/fstab mount کند را مشخص می کنیم:
# گزینه های سیستم فایل mount-point fs-type dump fsck-order
/dev/hda5 / ext3 پیشفرض 1 1
/dev/hda3 swap swap pri=1 0 0
proc /proc proc پیشفرض 0 0 است
به جای /dev/hda3 و /dev/hda5 پارتیشنهای خود را بنویسید (روت و مبادله)، در صورت لزوم فایل را با نقاط نصب برای سایر پارتیشنهای هارد دیسک و CD-ROM تکمیل کنید.
حالا بیایید سیستم خود را قابل بوت کنیم.
اگر علاوه بر lFS از سایر توزیع های لینوکس استفاده می کنید، اکنون باید وارد سیستم قدیمی شوید - برای انجام این کار، دستور را اجرا کنید:
خروج $
قبلاً در سیستم عامل والد، موارد زیر را به فایل /etc/lilo.conf اضافه کنید:
# LFS
image=/boot/bzImage
برچسب = lfs
ریشه =
فقط خواندنی
واضح است که "/boot/bzImage" مسیر هسته سیستمی است که شما کامپایل کرده اید، و "پارتیشن" پارتیشن دیسکی است که دایرکتوری ریشه در آن قرار دارد.
اگر قصد استفاده از سیستم عامل های دیگر و توزیع های لینوکس را ندارید، بلافاصله به راه اندازی LILO در LFS اقدام کنید.
در این مورد، lilo.conf چیزی شبیه به این خواهد بود:
boot=/dev/hda
تاخیر=40
فشرده - جمع و جور
Vga = نرمال
Root=/dev/hda1
فقط خواندنی
Image=/boot/zImage-2.6.12
برچسب = لینوکس
بسته به پیکربندی خود تغییرات لازم را انجام دهید. بوت لودر را با دستور زیر به روز کنید:
$ /sbin/lilo -v
و اگر تمام مراحل قبلی به درستی انجام شود، خود را در یک سیستم جدید خواهیم دید. با این حال، مرحله طولانی تنظیم "زیبا" (توجه ویژه ای باید به امنیت سیستم جدید شود، زیرا LFS به طور پیش فرض مانند هر سیستم عامل تازه نصب شده ای بسیار ناامن به نظر می رسد) هنوز در پیش است. اما شما در حال حاضر نسخه کامپایل شده لینوکس خود را دارید.
P.S
جرارد بیکمنز تنها کسی نیست که ایده ساخت لینوکس خود را دارد. پروژه دیگری، BYOLinux، به رهبری جاناتان تورپ، امروز توسعه خود را متوقف کرده است، اگرچه اسناد نوشته شده توسط او حتی در حال حاضر نیز مرتبط است، اما به اندازه کتاب LFS جزئیات نیست و به روسی ترجمه نشده است. تفاوت اصلی روش جان این است که کتابخانه glibc از سیستم والد به سیستم فرزند بدون کامپایل مجدد منتقل می شود، این کار آنقدرها کارآمد نیست، اما از بسیاری از مشکلات ساخت جلوگیری می کند. برخی از کاربران FreeBSD نیز تمایل به احساس طراح سیستم عامل را دارند.
اکنون این کاملاً امکان پذیر است - در http://ezine.daemonnews.org/200302/fbsdscratch.html مقاله ای در مورد ساخت FreeBSD از منابع کاملاً - از توزیع ها تا پورت ها و با روشی غیر شبیه به "بازسازی" معمولی وجود دارد. از سیستم، اما شبیه به روش جرارد بیکمنز است. خوب، اکنون شما یک سیستم شخصی و منحصر به فرد دارید که بر روی لینوکس ساخته شده است. در صورت بروز مشکل، راه حل آنها را در کتاب LFS جستجو کنید، همه چیز در آنجا با جزئیات شرح داده شده است. من همچنین توصیه می کنم راهنمای مدیر شبکه لینوکس را از پورتال http://www.tldp.org دانلود کنید، اگرچه مستقیماً برای LFS اعمال نمی شود، اما در مرحله پیکربندی سیستم مفید خواهد بود. فراموش نکنید که صفحات مختلف man و info نیز به همراه هر برنامه ارائه شده است که همچنین برای آسان کردن زندگی یک کاربر لینوکس طراحی شده است.
- کتاب LFS به زبان روسی - http://multilinux.sakh.com/lfs.
- پورتال رسمی پروژه LFS http://www.linuxfromscratch.org است.
- پورتال ByoLinux - http://www.byolinux.org.
- مقاله درباره FreeBSD از ابتدا - http://ezine.daemonnews.org/200302/fbsdscratch.html.
- مقاله ای در مورد کامپایل هسته لینوکس - http://vikos.lrn.ru/MyLDP/kernel/kompil-2-6.html .
- Bairak A. مروری بر Knoppix 3.7 نسخه روسی. - مجله «مدیر سیستم»، شماره 3، اسفند 1384 - 4-6 ص. ().
این سری از مقالات به برنامه نویسی سطح پایین، یعنی معماری کامپیوتر، طراحی سیستم عامل، برنامه نویسی به زبان اسمبلی و حوزه های مرتبط اختصاص دارد. تا به حال دو حبراسر مشغول نوشتن هستند - ایلی و پهات. برای بسیاری از دانش آموزان دبیرستانی، دانش آموزان و حتی برنامه نویسان حرفه ای، یادگیری این موضوعات بسیار دشوار است. ادبیات و دوره های زیادی به برنامه نویسی سطح پایین اختصاص داده شده است، اما به سختی می توان تصویری کامل و جامع از آنها به دست آورد. پس از خواندن یک یا دو کتاب در مورد اسمبلر و سیستم عامل، تصور اینکه حداقل به طور کلی چگونه این سیستم پیچیده از آهن، سیلیکون و بسیاری از برنامه ها - یک کامپیوتر - واقعاً چگونه کار می کند، دشوار است.
هرکسی به روش خود مشکل یادگیری را حل می کند. کسی ادبیات زیادی می خواند، کسی سعی می کند به سرعت به تمرین و درک در طول راه ادامه دهد، کسی سعی می کند همه چیزهایی را که در حال مطالعه است برای دوستان توضیح دهد. و ما تصمیم گرفتیم این رویکردها را ترکیب کنیم. بنابراین، در این دوره از مقالات، گام به گام نحوه نوشتن یک سیستم عامل ساده را نشان خواهیم داد. مقالات ماهیت کلی خواهند داشت، یعنی حاوی اطلاعات نظری جامعی نیستند، با این حال، ما همیشه سعی خواهیم کرد پیوندهایی به مطالب نظری خوب ارائه دهیم و به تمام سوالاتی که پیش می آید پاسخ دهیم. ما برنامه مشخصی نداریم، بنابراین تصمیمات مهم بسیاری در طول مسیر با در نظر گرفتن نظرات شما اتخاذ خواهد شد.
ممکن است ما عمداً فرآیند توسعه را به بنبست سوق دهیم تا به شما و خودمان اجازه دهیم تا عواقب یک تصمیم اشتباه را کاملاً درک کنیم و همچنین برخی از مهارتهای فنی را در آن تقویت کنیم. پس تصمیمات ما را تنها تصمیم واقعی نگیرید و کورکورانه ما را باور کنید. ما بار دیگر تاکید می کنیم که انتظار داریم خوانندگان در بحث مقالات فعال باشند، که باید بر روند کلی توسعه و نوشتن مقالات بعدی تأثیر زیادی بگذارد. در حالت ایده آل، من دوست دارم برخی از خوانندگان به مرور زمان به توسعه سیستم بپیوندند.
فرض میکنیم که خواننده قبلاً با اصول اسمبلی و زبانهای C و همچنین مفاهیم اولیه معماری رایانه آشنا است. یعنی ما توضیح نمی دهیم که رجیستر یا مثلا رم چیست. اگر دانش ندارید، همیشه می توانید به ادبیات اضافی روی بیاورید. فهرست کوتاهی از مراجع و لینک های سایت هایی با مقالات خوب در انتهای مقاله آمده است. همچنین مطلوب است که بتوان از لینوکس استفاده کرد، زیرا تمام دستورالعمل های کامپایل برای این سیستم ارائه خواهد شد.
و اکنون - به اصل مطلب نزدیک تر است. در ادامه مطلب من و شما برنامه کلاسیک سلام دنیا را می نویسیم. دنیای هالووین ما کمی خاص خواهد بود. این از هیچ سیستم عاملی اجرا نمی شود، بلکه به طور مستقیم، به اصطلاح "روی فلز خالی" اجرا می شود. قبل از اینکه مستقیماً به نوشتن کد بپردازیم، بیایید بفهمیم که دقیقاً چگونه می خواهیم این کار را انجام دهیم. و برای این کار باید فرآیند بوت شدن کامپیوتر را در نظر بگیرید.
بنابراین، کامپیوتر مورد علاقه خود را بردارید و بزرگترین دکمه را در واحد سیستم فشار دهید. ما یک محافظ صفحه نمایش شاد می بینیم ، واحد سیستم با خوشحالی با بلندگو جیر می کشد و پس از مدتی سیستم عامل بارگیری می شود. همانطور که می دانید، سیستم عامل بر روی هارد دیسک ذخیره می شود و در اینجا این سوال مطرح می شود: چگونه سیستم عامل به طور جادویی در RAM بوت شد و شروع به کار کرد؟
این را بدانید: سیستمی که در هر رایانه ای است مسئول این است و نام آن نه، ویندوز نیست، پیپ روی زبان شماست - به آن BIOS می گویند. نام آن مخفف Basic Input-Output System است، یعنی سیستم ورودی-خروجی اولیه. بایوس روی یک ریزمدار کوچک روی مادربرد قرار دارد و بلافاصله پس از فشار دادن دکمه بزرگ ON شروع به کار می کند. BIOS سه وظیفه اصلی دارد:
- همه دستگاههای متصل (پردازنده، صفحهکلید، مانیتور، رم، کارت گرافیک، سر، بازوها، بالها، پاها و دمها...) را شناسایی کرده و آنها را از نظر عملکرد آزمایش کنید. برنامه POST (Power On Self Test) این وظیفه را بر عهده دارد. اگر سخت افزار حیاتی پیدا نشود، هیچ نرم افزاری نمی تواند کمک کند و در این مرحله بلندگوی سیستم چیزی شوم را به صدا در می آورد و اصلاً به سیستم عامل نمی رسد. بیایید در مورد چیزهای غم انگیز صحبت نکنیم، بیایید فرض کنیم که یک رایانه کاملاً کار می کنیم، خوشحال باشیم و به بررسی عملکرد دوم BIOS ادامه دهیم:
- ارائه سیستم عامل با مجموعه ای از عملکردهای اساسی برای کار با آهن. به عنوان مثال، از طریق توابع BIOS، می توانید متن را روی صفحه نمایش دهید یا داده ها را از صفحه کلید بخوانید. به همین دلیل است که به آن سیستم ورودی-خروجی اولیه می گویند. به طور معمول، سیستم عامل از طریق وقفه به این توابع دسترسی پیدا می کند.
- راه اندازی لودر سیستم عامل. در این مورد، به عنوان یک قاعده، بخش بوت خوانده می شود - اولین بخش حامل اطلاعات (فلاپی دیسک، دیسک سخت، سی دی، درایو فلش). ترتیب نظرسنجی رسانه را می توان در BIOS SETUP تنظیم کرد. بخش بوت شامل برنامه ای است که گاهی اوقات بوت لودر اصلی نامیده می شود. به طور کلی، وظیفه بوت لودر راه اندازی سیستم عامل است. فرآیند بارگذاری یک سیستم عامل می تواند بسیار خاص و بسیار وابسته به ویژگی های آن باشد. بنابراین، بارگذار اولیه مستقیماً توسط توسعه دهندگان سیستم عامل نوشته می شود و در هنگام نصب در بخش بوت نوشته می شود. هنگامی که بوت لودر راه اندازی می شود، پردازنده در حالت واقعی است.
تصویر سطح درایو دیسک را نشان می دهد. فلاپی دیسک دارای 2 سطح است. در هر سطح آهنگ های حلقه ای شکل (آهنگ) وجود دارد. هر مسیر به قطعات کوچک کمانی شکل به نام بخش تقسیم می شود. بنابراین، از نظر تاریخی، یک بخش فلاپی دیسک دارای اندازه 512 بایت است. اولین سکتور روی دیسک، بخش بوت، توسط BIOS "در قسمت حافظه صفر با offset 0x7С00 خوانده می شود و سپس کنترل به این آدرس منتقل می شود. بوت لودر معمولاً نه خود سیستم عامل، بلکه دیگری را در حافظه بارگذاری می کند. برنامه بوت لودر بر روی دیسک ذخیره می شود، اما به دلایلی (به احتمال زیاد، این دلیل اندازه است) که در یک بخش قرار نمی گیرد. و از آنجایی که تاکنون نقش سیستم عامل ما توسط یک Helloworld پیش پا افتاده ایفا می شود، هدف اصلی ما این است که کامپیوتر را به وجود سیستم عامل ما باور کند، حتی اگر در یک بخش باشد، و آن را اجرا کنید.
بوت سکتور چگونه مرتب شده است؟ در رایانه شخصی، تنها شرط لازم برای بخش بوت این است که دو بایت آخر آن حاوی مقادیر 0x55 و 0xAA، امضای بخش بوت باشد. بنابراین، کم و بیش روشن است که چه کاری باید انجام دهیم. بیا کد بنویسیم! کد بالا برای اسمبلر yasm نوشته شده است.
بخش. متن
استفاده 16
org 0x7C00 ; برنامه ما در 0x7C00 بارگذاری شده است
شروع:
mov ax , cs
mov ds , ax ; بخش داده را انتخاب کنید
mov si , پیام
cld ; جهت دستورات رشته
mov ah، 0x0E ; شماره عملکرد بایوس
mov bh , 0x00 ; صفحه حافظه ویدیویی
puts_loop:
lodsb ; کاراکتر بعدی را در al بارگذاری کنید
تست al, al ; کاراکتر null به معنای پایان رشته است
jz puts_loop_exit
int 0x10 ; فراخوانی تابع BIOS
jmp puts_loop
puts_loop_exit:
jmp$; چرخه ابدی
پیام:
db "سلام دنیا!" 0
تمام کردن:
بار 0x1FE - پایان + شروع db 0
db 0x55، 0xAA ; امضای بخش بوت
این برنامه کوتاه به تعدادی توضیحات مهم نیاز دارد. خط org 0x7C00 مورد نیاز است تا اسمبلر (به معنای برنامه، نه زبان) به درستی آدرس برچسب ها و متغیرها (puts_loop، puts_loop_exit، پیام) را محاسبه کند. بنابراین ما به او می گوییم که برنامه در حافظه 0x7C00 بارگذاری می شود.
در خطوط
mov ax , csبخش داده (ds) برابر با بخش کد (cs) تنظیم شده است، زیرا در برنامه ما هر دو داده و کد در یک بخش ذخیره می شوند.
mov ds , ax
سپس پیام «Hello World!» کاراکتر به کاراکتر در حلقه نمایش داده می شود. برای این کار از تابع 0x0E وقفه 0x10 استفاده می شود. گزینه های زیر را دارد:
AH = 0x0E (شماره تابع)
BH = شماره صفحه ویدیو (هنوز زحمت نکشید، 0 را نشان دهید)
AL = کد کاراکتر ASCII
در خط "jmp $" برنامه آویزان می شود. و به درستی، نیازی به اجرای کد اضافی برای او نیست. با این حال، برای اینکه کامپیوتر دوباره کار کند، باید راه اندازی مجدد شود.
در سطر "times 0x1FE-finish+start db 0" بقیه کد برنامه (به جز دو بایت آخر) با صفر پر می شود. این کار به این صورت انجام می شود که پس از کامپایل، امضای بخش بوت در دو بایت آخر برنامه ظاهر شود.
ما به نوعی کد برنامه را فهمیدیم، اکنون بیایید سعی کنیم این شادی را کامپایل کنیم. برای کامپایل، در واقع به یک اسمبلر نیاز داریم - آنچه در بالا ذکر شد
دیر یا زود، هر کاربر لینوکس به ایجاد توزیع خود فکر می کند. برخی استدلال می کنند که شما می توانید "همه چیز را برای خودتان سفارشی کنید." دیگران شکایت دارند که در میان توزیع هایی که قبلاً در Vetka ارائه شده است، هیچ توزیع ایده آلی وجود ندارد. و آنها ظاهراً ایده های فوق مفهومی برای سیستم خود دارند. چرا این همه روانشناسی را شروع کردم؟ به منظور قطع فوری اکسیژن برای مبتدیانی که با لینوکس بازی می کنند و کاری ندارند. اگر از قبل به ایجاد یک سیستم عامل فکر می کنید، تا انتها فکر کنید. بنابراین،
من می خواهم یک سیستم عامل مبتنی بر لینوکس ایجاد کنم.
فوراً به شما هشدار می دهم: اگر قرن هجدهم بود، همه کسانی که کیت توزیع توسعه یافته دیگری (و خدای ناکرده محبوب ...) را برای اساس سیستم آینده خود انتخاب می کردند به دار آویخته می شدند. این پست در مورد ایجاد یک سیستم از ابتدا است، به این معنی که ما به هیچ Slax و Linux Mint دست نخواهیم داد.
مرحله 1: یک رسانه را انتخاب کنید
گزینه های کمی وجود دارد: یا سیستم عامل شما از یک LiveCD شروع می شود، یا از یک هارد دیسک، یا از یک دستگاه فلش. من فوراً رزرو می کنم: در پست هیچ کلمه ای در مورد هارد دیسک نمی گویم، زیرا ایجاد یک کیت توزیع انعطاف پذیر از سری "من همه چیز را با خود حمل می کنم" یا یک توزیع قفل شده بسیار راحت تر است. کیت روی یک دیسک نوری اگر یاد بگیرید که چگونه یک سیستم LiveCD یا LiveUSB ایجاد کنید، هیچ مشکلی برای نصب روی هارد دیسک وجود نخواهد داشت.
در هر صورت یک فلش خالی، سی دی تهیه کنید و در نهایت Virtualbox را نصب کنید.
مرحله 2 کامپایل کرنل
با توجه به انتشار سومین هسته لینوکس، این مرحله توسعه بیشتر را تشویق می کند ... بنابراین، ما به منابع هسته نیاز داریم. هر کاربر می داند که آنها را می توان از kernel.org به دست آورد. به هیچ وجه، آیا می شنوید؟، هرگز یک هسته خارجی که توسط شما کامپایل نشده است را به سیستم خود پیچ نکنید!
از آنجایی که تنبلی من از مقیاس خارج شد، یک پوشه / لینوکس کرنل ایجاد کردم و آرشیو را با منابع موجود در آن باز کردم. با ورود به عنوان روت، موارد زیر را انجام دادم:
سی دی /linuxkernel
منوی پیکربندی را انجام دهید
در اصل، هسته را می توان به سه روش پیکربندی کرد: پیکربندی (پیکربندی دیالوگ)، ساخت منوکانفیگ (پیکربندی شبه گرافیکی از طریق ncurses) و ساخت xconfig (پیکربندی گرافیکی). نکته اصلی این است که make config برای مدت طولانی روحیه شما را خراب می کند، زیرا. او تمام سوالات ممکن را در تمام جنبه های همه موضوعات مطرح خواهد کرد. مشکل make xconfig در همه یافت نمی شود، اما من ملاقات کرده ام و هنوز هم دارم. اگر دوست دارید این کار را از طریق X انجام دهید، خودتان آن را کشف کنید. بهترین گزینه make menuconfig است. این مورد یک رابط شبه گرافیکی را برای شما باز می کند که از طریق آن می توانید هسته را به روش خود شخصی سازی کنید. این مورد به کتابخانه ncurses نیاز دارد که نصب آن آسان است.
در اصل، اگر مغز شما اصلاً لینوکس را بفهمد، پیکربندی را متوجه خواهید شد. روند جالب است، واقعا گزینه های زیادی وجود دارد، و کمک، اگرچه به زبان انگلیسی است، اما همچنان از دسترسی و سادگی آن خوشحال است.
با این حال، هنوز باید هدایت شوید. به File Systems ---> بروید و ستاره های مورد نیاز را قرار دهید. حرف M به این معنی است که پشتیبانی از یک درایور خاص با اتصال یک ماژول خارجی به هسته انجام می شود (من از آنها متنفرم!). همچنین برای خواندن دیسک به پشتیبانی isofs نیاز داریم. سیستم های فایل ---> سیستم های فایل CD-ROM/DVD ---> پشتیبانی از سیستم فایل CDROM ISO 9660. هنوز هم میتوانید از سیستمهای dos قدیمی پشتیبانی کنید.
توسعه دهندگان عجیب و غریب Mandriva فراموش کردند که به سیستم های فایل ---> فایل سیستم های فایل DOS/FAT/NT ---> NTFS پشتیبانی نوشتن اجازه دهند، و در یکی از توزیع های آنها من با دسترسی به پارتیشن قدیمی ویندوز مشکل داشتم.
نگاه کنید نوع و ویژگی های پردازنده ---> خانواده پردازنده، به من توصیه شد Pentium-MMX را انتخاب کنم.
درایورهای دستگاه را نیز بررسی کنید، مفید است. برای سرگرمی، می توانید همه چیز را در آنجا انتخاب کنید و یک هسته با وزن بیش از 50 مگابایت کامپایل کنید.
به علاوه. هسته، پس از بارگذاری خود، باید در واقع سیستم را بارگیری کند. یا از فایل های خود کامپایل شده (مورد استفاده در سیستم های جاسازی شده)، یا از آرشیو CPIO فشرده شده با چیزی، یا از Initrd. این DOS برای شما نیست، در اینجا نمی توان بلافاصله به برخی از فایل های init "جدید در دایرکتوری ریشه دیسک یا فلش درایو مراجعه کرد. در واقع کار می کند، به Uncle Annix گوش ندهید! این اشتباه است. ، اگرچه در حال حاضر یک بحث شدید در اینترنت در مورد این موضوع وجود دارد. ما از initrd برای سیستم خود استفاده خواهیم کرد، زیرا راحت است و برخلاف بایگانی CPIO باعث عبارات ناپسند توسعه دهندگان شخص ثالث نمی شود.
اوه بله، هسته را با دستور کامپایل کنید
اگر x86 دارید، می توانید آن را در /linuxkernel/arch/x86/boot/bzImage پیدا کنید.
برای برنامه نویسان خشن چلیابینسک، می توانید از کامپایل متقابل استفاده کنید ...
Ramdisk را ایجاد کنید.
اکنون به یک initrd با یک پوسته ساده نصب شده در آنجا نیاز داریم. ما از busybox استفاده خواهیم کرد زیرا این nyasha می تواند هر کاری را انجام دهد. ما این روش را از روبرتو د لئو، خالق موویکس میدزدیم (اگر عشق متعالی به پرل نبود، حتی به او احترام میگذارم):
dd if=/dev/zero of=/dev/ram0 bs=1k count=5000 - یک Ramdisk در RAM کامپیوتر خود ایجاد کنید.
mke2fs -m0 /dev/ram0 5000 - فرمت Ramdisk در سیستم Ext2
mkdir /distro - یک پوشه ایجاد کنید
mount /dev/ram0 /distro - به پوشه /distro سوار شوید
همه چیز، حالا ما یک Ramdisk با ظرفیت 5 مگابایت داریم. شما می توانید کارهای بیشتری انجام دهید، اما نیازی به این کار ندارید. برخلاف Thomas Mathejisek، من قصد ندارم initrds را با ماژول های Squashfs فشرده LZMA پر کنم. هر چیزی که مورد نیاز است با هسته کامپایل می شود. بله، این خیلی منطقی و درست نیست، اما دردسر صد برابر کمتر است. و به خصوص برای کسانی که این رویکرد را محکوم می کنند، می توانید گزینه مدولاریته را در هسته فعال کنید: پشتیبانی از ماژول قابل بارگذاری را فعال کنید.
در Ramdisk ما، نصب شده بر روی / توزیع، چنین پوشه ای وجود دارد، گم شده + یافت شده است. این به این دلیل است که ما آن را در ext2 فرمت کردیم. برای قرار دادن busybox در ابتدا ...
نصب Busybox
چرا چنین پروژه های بزرگی چنین وب سایت های مزخرفی دارند؟ اگر چه... دیگر اهمیتی ندارد که منابع دانلود شده و با موفقیت در پوشه /busybox باز شوند.
شما می توانید busybox را به همین روش پیکربندی کنید:
سی دی /busybox
منوی پیکربندی را انجام دهید
اگر هنوز متوجه نشدید چیست، توضیح می دهم. Busybox جایگزین هزاران برنامه یونیکس ذخیره شده در پوشه های /bin، /sbin، /usr/bin، /usr/sbin می شود. در عوض، تنها یک برنامه ایجاد می شود: /bin/busybox، و دسته ای از پیوندها به آن در پوشه های بالا ایجاد می شود. با دستور زیر busybox را نصب کنید:
CONFIG_PREFIX=/distro را نصب کنید
Busybox همچنین فایل های /sbin/init و بنا به دلایلی /linuxrc را ایجاد می کند تا سیستم شما به درستی راه اندازی شود. اما همه پوشه های لازم ایجاد نشده اند. بنابراین ما همه چیز را با دستان خود تمام می کنیم و ایجاد می کنیم:
/distro/و غیره
/distro/lib
/distro/dev
/distro/mnt
توزیع / پروک
/distro/root
/distro/tmp
/distro/root
اگر چیزی را فراموش کردید، به خاطر بسپارید، زیرا فراموش کردن این دایرکتوری ها سخت است.
همه چیز خوب خواهد بود، اما busybox به کتابخانه ها نیاز دارد تا کار کنند، که باید در توزیع ما کپی شوند. خیلی راحت میشه فهمید که:
ldd /distro/bin/busybox
این برنامه کتابخانه های مورد نیاز پوسته را به ما نشان می دهد. فوراً می گویم: گیت لینوکس توسط هسته ایجاد می شود و نمی توان آن را کپی کرد.
هنگام کپی کردن کتابخانه ها، می توانید اطلاعات اشکال زدایی را قطع کنید (همانطور که روبرتو توصیه می کند):
objcopy --strip-debug from where to
ساخت لینوکس از لینوکس
شما باید چندین فایل متنی سیستم ایجاد کنید:
ما به /etc/inittab نیاز داریم. من شما را شگفت زده خواهم کرد: در ابتدای زندگی، سیستم حتی نمی داند که Root چیست. ما حتی یک کاربر بی نام داریم، اما فایل ویژگی های سطح پایین سیستم (ONF) باید وجود داشته باشد. محتوای آزمایشی فایل به شرح زیر است:
# اولین فایلی که اجرا می شود، /sbin/init پس از آن.
::sysinit:/etc/rc.d/rc.S
# یک پوسته در کنسول اجرا کنید.
::respawn:-/bin/sh
# دستورات برای اجرا قبل از خاموش شدن و راه اندازی مجدد.
:: shutdown:/sbin/swapoff -a >/dev/null 2>&1
:: shutdown:/bin/umount -a -r >/dev/null 2>&1
فایل بعدی /etc/fstab است. این جدولی است که توضیح میدهد در هنگام بوت چه چیزی و کجا باید نصب شود. چیز بیهوده است! ما باید proc را مونت کنیم، در غیر این صورت هیچ چیز کار نمی کند، بنابراین در فایل می نویسیم:
none /proc proc پیشفرض 0 0 است
Mount همچنین به /etc/mtab نیاز دارد. آن را ایجاد کنید و آن را خالی بگذارید.
اما mount تنها زمانی کاری را انجام میدهد که ما صریحاً از آن بخواهیم. و ما در همان فایل بوت /etc/rc.d/rc.S می پرسیم (rc.d یک پوشه است). مودبانه می پرسیم:
/bin/mount -av -t nonfs
ما همچنین به یک فایل پروفایل (b) (a) sh نیاز داریم، به طور کلی آزادی برای تخیل وجود دارد. یک فایل /etc/profile ایجاد کنید و آن را با موارد زیر پر کنید:
PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin:"
کمتر = - میلی متر
TERM=لینوکس
HOME=/root
PS1=">"
PS2=">"
ignoreeof=10
صادرات PATH DISPLAY LESS TERM PS1 PS2 HOME ignoreeof
شما همچنین به فایل /etc/shell نیاز دارید که نشان می دهد یک پوسته وجود دارد:
/bin/sh
/bin/ash
/bin/bash
این در واقع تمام است. ما می توانیم Ramdisk خود را در یک فایل بنویسیم.
mkdir /os - پوشه "آماده".
umount /dev/ram0 - یک قطعه از RAM را جدا کنید.
dd if=/dev/ram0 of=/os/initrd bs=1k count=5000 - فایل ایجاد کنید.
gzip /os/initrd - فایل initrd را فشرده کنید
یک درایو فلش قابل بوت بسازید
"خط پایان" توسعه کوچک ما. ما یک درایو فلش USB می گیریم، آن را وارد می کنیم، آن را در vfat فرمت می کنیم (در ext نیز امکان پذیر است، اما فراموش نکنید که همه کاربران ویندوز هنوز خود را شلیک نکرده اند).
در درایو فلش، یک پوشه بوت ایجاد کنید، این پوشه حاوی فولدرهای initrd و kernel است.
از پوشه / os، Ramdisk فشرده شده را در پوشه boot/initrd در درایو فلش USB کپی کنید، آن را "main.gz" نامید. از پوشه حاوی منابع هسته، bzImage را در پوشه بوت / هسته در درایو فلش USB کپی کنید، آن را "main.lk" نامید. ما فایل های بوت لودر Syslinux را دریافت می کنیم (در اینترنت یا از توزیع دیگری: اینجا مهم نیست)، یعنی syslinux.bin، syslinux.boot، syslinux.cfg. ما آنها را در پوشه اصلی فلش مموری کپی می کنیم. در فایل syslinux.cfg چیزی شبیه این می نویسیم:
میلی متر پیش فرض
درخواست 1
تایم اوت 100
برچسب میلی متر
هسته /boot/kernel/main.lk
برچسب mc
هسته /boot/kernel/main.lk
برچسب سانتی متر
هسته /boot/kernel/custom.lk
اضافه کردن initrd=/boot/initrd/main.gz load_ramdisk=1 ramdisk_size=5000 rw root=/dev/ram0
برچسب سی سی
هسته /boot/kernel/custom.lk
اضافه کردن initrd=/boot/initrd/custom.gz load_ramdisk=1 ramdisk_size=5000 rw root=/dev/ram0
برچسب hd
لوکال بوت 0x80
بنابراین، ما از initrdهای سفارشی و هسته پشتیبانی میکنیم، که برای آزمایش، میتوانند به توزیع ما متصل شوند.
بیایید دریابیم که درایو فلش ما در سیستم چه دستگاهی است (می توانید mount را بدون پارامتر اجرا کنید و ببینید). این یا /dev/sdb1 یا /dev/sdc1 یا /dev/sdd1 است. قبل از شروع نصب، ارزش آن را دارد که درایو فلش را جدا کنید.
syslinux را نصب کنید (اگر بسته در سیستم نیست، apt-get install syslinux):
syslinux -d device_path
فایل ldlinux.sys باید در دایرکتوری ریشه فلش درایو ظاهر شود. اگر چنین است، syslinux.bin، syslinux.boot دیگر مورد نیاز نیست.
من به شما نمی گویم که چگونه بایوس را برای بوت شدن از درایو فلش USB تنظیم کنید - آسان است. بگذارید فقط بگویم که ایجاد پوشه /boot/initrd/init که می توانید /boot/initrd/main را در آن برای کار بعدی با آن سوار کنید بسیار راحت است. فقط فراموش نکنید که آن را با gzip از حالت فشرده خارج کرده و فشرده کنید.
خودشه.
همانطور که من به شما گفتم چگونه یک سیستم لینوکس را از ابتدا بسازید. آسان است، اینطور نیست؟ سپس می توانید اسکریپت /sbin/init را ویرایش کنید، زیرا هنوز کار زیادی برای انجام دادن دارید! شما باید یک اسکریپت بنویسید تا فلش درایو را که در دایرکتوری ریشه chroot می شود، سوار کنید. در غیر این صورت مجبور خواهید شد با یک پارتیشن ReadOnly 5 مگابایتی کار کنید. اما این یک داستان کاملا متفاوت است.