نحوه کامپایل کردن کرنل لینوکس - زیپ
X
تبلیغات
رایتل
دوشنبه 2 اردیبهشت 1392 @ 07:08 ب.ظ

نحوه کامپایل کردن کرنل لینوکس

مقدمه :

 سیستم عامل لینوکس که یکی از برنامه های Open Source قابل دسترس در اینترنت می باشد، قابلیت تغییر یافتن بر اساس نیازهای واقعی یک دستگاه را نیز دارا میباشد. به طور مثال میتوانیم کرنل را طوری تصحیح کنیم که تنها برای یک سرور و یا یک مسیریاب شبکه کارایی داشته باشد و بار اضافی مربوط به Task های دیگر در سیستم که برای این هدف ما یعنی یک مسیریاب لازم نیستند را از روی پردازنده برداریم. همچنین ممکن است برای یک سیستم با مقدار حافظه زیاد یا مثلاً تعداد کارت شبکه زیاد سیستم عامل خاصی یافت نشود بنابر این باید به دنبال ایجاد کرنل دلخواه باشیم. برای این کار نیاز داریم تا با نحوه کامپایل کردن کرنل که هسته اصلی سیستم عامل محسوب می شود آشنا شویم. بعد از آن با نحوه اجرا کردن این کرنل بر روی سیستم نیز که یکی از مشکلترین مراحل در بهینه سازی کرنل میباشد آشنا خواهیم شد.


تعریف کرنل[۱] :

            کرنل لینوکس نقش یک برنامه کنترل مرکزی در کامپیوتر را نسبت به برنامه ها، چگونگی تعامل آنها با یکدیگر و هدایت آنها برای استفاده از منابع اصلی سیستم مانند حافظه، دیسکها، پردازنده ها، دستگاههای جانبی و غیره را بر عهده دارد[۲]. درایورهای لینوکس، برنامه هایی که برای مدیریت ورودی/خروجی دستگاههای جانبی (I/O Devices ) می باشند، نقش مجری سیاستهای کرنل را بر عهده دارند. کرنل نیز وظیفه کنترل اینها را برعهده دارد. به این ترتیب هرچه تعداد این دستگاهها زیاد شود سرعت سیستم کمتر میشود. در ضمن همانطور که بعداً نیز خواهید دید هر چه حجم کرنل بیشتر باشد، حافظه کمتری برای نرم افزارهای دیگر در اختیار می گذارد.

کرنلهایی که هم اکنون در لینوکس Fedora یافت می شوند به شرح زیر میباشند.

Table 1  .Kernels Found On Fedora Installation CDs

Processor Type

Configuration

i586

Single processor

i586

Multiprocessor (SMP)

i686

Single processor

i686

Multiprocessor (SMP)

 این کرنل که یک فایل به نام vmlinuz می باشد، معمولاً در دایرکتوری /boot در سیستم یافت میشود. بدلیل اینکه کرنل تماماً در حافظه بارگذاری میشود بنابر این هرچه حجم آن کمتر باشد سریعتر اجرا می شود. به جای اینکه کرنل همه درایورهای احتمالی مورد نیاز را در حافظه بارگذاری کند، تنها درایورهایی که مورد نیاز باشند توسط کرنل بارگذاری می شوند. زمانی یک کرنل را برای کار خود کامپایل میکند می توانید یا درایورهای مورد نیاز خود را دقیقاً برای مشخض کنید یا درایورهایی که میدانید سیستم نیازی به آنها ندارد را حذف کنید. به این ترتیب از اشغال حافظه اضافی جلوگیری خواهد شد. در جدیدترین نسخه های سیستم عامل لینوکی قابلیت اضافه کردن Module ها نیز به کد کرنل نیز اضافه شده. این قابلیت به شما اجازه میدهد درایورهای خود را به کرنل اضافه کنید در حالیکه کرنل همچنان کوچک باقی می ماند.

تفاوت Default Kernel ها و Customized Kernel ها:

            کامپایل کردن کرنل یک روش معمول به حساب نمی آید زیرا کرنل های امروزی به قدری Dynamic (پویا) می باشند و با دستگاههای جانبی که به سیستم متصل هستند سازگارند که نیازی به اضافه کردن Module ها و یا حتی کامپایل کردن دوباره کرنل نیز نمی باشد.

به هر حال کرنلی که شما خود کامپایل می کنید با کرنلی که به صورت عادی نصب میکنید تفاوتهایی دارد، زیرا کرنل معمول احتمالاً قابلیت های اضافه ای نیز دارد. در ضمن معمولاً کرنلها را بر اساس پردازنده های مختلف طبقه بندی می کنند که در اینجا بر روی پردازنده های Pentium بیشتر توضیح خواهیم داد. ولی شرکت Red Hat کرنل هایی برای دسته وسیعی از سیستمها بدون توجه به سخت افزار و دستگاههای جانبی متصل به دستگاه تولید نموده است. بدون نیاز به اضافه کردن درایورهای مورد نیاز به صورت کد درون کرنل میتوانیم با استفاده از Module ها هر زمان که خواستیم Module ها را در حافظه بارگذاری کنیم و زمانی که به آنها نیازی نبود آنها را از حافظه برداریم. این باعث سرعت بیشتر سیستم خواهد شد. باز هم یادآوری می شود از آنجاییکه کرنل همواره در حافظه می باشد و درحال اجرا، لذا هر چه حجم کمتری داشته باشد منابع سیستم مانند CPU و حافظه (RAM) را برای نرم افزارهای دیگر آزاد نگه می دارد. در حال حاضر این امکان وجود دارد که به دو صورت کرنل را کامپایل کنیم : ۱) Modularized kernel  و ۲) Monolithic kernel . Modularized زمانی به کار میرود که Module ها را با کرنل یکی می کنیم. به دلیل وجود قطعات جانبی که به یک کامپیوتر متصل می کنند کسانی که نیاز به راه اندازی یک سیستم با کارایی بالا میباشند مانند مدیران شبکه کرنلها را به صورت Monolithic کامپایل می کنند. ولی برای سیستم های کوچک و قدیمی بهتر است از Modularized برای کامپایل کردن استفاده کنید. کرنل سیستم عامل Red Hat Linux در حدود ۵۰۰ KByte تا ۱٫۲ MByte می باشد که بستگی به این دارد که ما درایورها را به صورت Module به کار ببریم یا با کرنل کامپایل کنیم. به خاطر بسپارید که Modularized Kernel از Monolithic Kernel حجم کمتری دارد. کرنلهای معمولی اغلب درایورهای مورد نیاز را به صورت Module به کار برده اند. این کار باعث میشود که کرنل با بیشتر سخت افزارها بتواند کار کند بدون نیاز به داشتن کرنل با حجم بسیار بالا. اگر می خواهید یک کرنل را کامپایل کنید بهتر است از کامپایل کردن درایورهای اضافی به صورت Module به کرنل فروگذار نکنید.

مزیتهای استفاده از  Module ها:

۱)      برای اضافه کردن دستگاه جانبی (Device) به کامپیوترتان نیازی به کامپایل کردن دوباره کرنل با درایورهای آن ندارید، کافی است آنرا به عنوان یک Module به تنهایی کامپایل کنیم.

۲)      اگر مشکلی در درایور باشد در حالتی که از Module استفاده نمی کنیم میتواند باعث شود سیستم به طور کامل بالا نیاید و دچار مشکل شود و مجبور هستیم کرنل را دوباره کامپایل کنیم. و در حالت Modular تنها کافی است که در فایل /etc/modprobe.conf مشخص کنیم که این درایور در موقع بالا آمدن سیستم اجرا  نشود. یا با استفاده از دستود rmmod در موقع بالا آمدن این کار را انجام دهیم.

۳)      به روز رسانی درایورها نیازی به reboot کردن ندارد. تنها لازم است که درایور قبلی را unload کنیم و درایور جدید را load کنیم.

۴)      می توانید بدون کامپایل دوباره کرنل دستگاههای جانبی بیشتری را به کامپیوتر خود اضافه کنید.

:: به هر حال برخی از Module ها هستند که اضافه کردن آنها به کرنل اجباری است و نمی توان آنها را به صورت Module تعریف کرد، مانند توابع کار با فایلها. به هر حال Module ها برای کار با فایل سیستم های جدید، کارتهای شبکه و … می باشند. Module ها همچنین باید برای هر کرنل به طور جداگانه کامپایل شوند یا دقیقاً Module مربوط به آن کرنل را استفاده کنیم. کرنل همواره دنبال Module با نگارش مطابق با کرنل در آدرس /lib/modules/ می گردد و آنها را برای سرعت بیشتر در حافظه بارگذاری می کند. باقی آنها نیز باید در فایل /etc/modprobe.conf به طور صریح مشخص شوند.

چگونگی اجرای Module ها هنگام بالا آمدن لینوکس:

             سؤال مهمی که در این بخش مطرح است اینست که «چگونه میتوانیم Module هایی را که مربوط به فایل سیستم هستند را اجرا کنیم در حالیکه این Module در بخشی قرار گرفته که هنوز دسترسی به آن مقدور نمی باشد، به عبارتی هنوز Mount نشده اند ؟»

یک Boot Loader به نام Grub وجود دارد که بر روی یک پارتیشن مخصوص به خود در هارددیسک وجود دارد و از فایل /etc/grub.conf اطلاعات مورد نیاز خود برای بالا آوردن لینوکس را بدست می آورد. این فایل اطلاعات مربوط به مکان کرنل فعلی درهارد، آدرس دایرکتوری اصلی (root) و Ramdisk Image ای که در حافظه بارگذاری میشود تا بتواند root filesystem را Mount کند.

:: به طور مثال سروری که از آن استفاده میکنم مشخصات زیر را در grub.conf خود دارد.

اطلاعات مورد بحث به حالت Bold در آمده اند. همانطور که ملاحظه می فرمائید پارتیشن root همان (hd0,0) می باشد، کرنل که در دایرکتوری /boot قرار دارد با نام vmlinuz-2.6.9-1.667smp مشخص شده و RAM Disk نیز درهمان دایرکتوری با نام

 initrd-2.6.9-1.667smp.img مشخص شده.

:: فایل .img درهنگام ساختن کرنل جدید به دست می آید ولی میتوانید بنا به نیاز با دستور mkinitrd آنرا بسازید.

:: ممکن است معنای (hd0,0) کمی برای شما غریب به نظر برسد، ولی فایلی وجود دارد به نام /boot/grub/device.map  که معادل hd0 را به شما می دهد. در این مثال /dev/hdb ذکر شده.

در قسمت بعد کرنل Load شده برنامه ای به نام init را که در RAM Disk وجود دارد را اجرا می کند که این برنامه فایل سیستم root را Mount میکند و Module های باقیمانده ای که در فایل /etc/modprobe.conf مشخص شده را قبل از اجرای سایر برنامه ها در هنگام بالا آمدن لینوکس اجرا می کند.

Moudle های مربوط به درایورهای دستگاه مثلاً درایور کارت شبکه در فایل /etc/modprobe.conf با نام مستعار کارت شبکه که eth0 یا eth1 می باشد مشخص شده اند.

همانطور که مشاهده می کنید، درایورهای مربوط به eth0 و eth1 به ترتیب ۳c59x و sk98lin می باشند.

ü      لینوکس دستوری به نام lsmod دارد که لیست Module های اجرا شده را برای شما نشان می دهد. میتوانید برای Load و یا Unload کردن هر کدام از آنها از دستور modprobe کمک بگیرید. همچنین دستورات insmodوrmmodنیز می توانند این کار را انجام دهند.

ü       برای به دست آوردن اطلاعات دقیقتر از نحوه کار این دستورات به Manual آنها با استفاده از تایپ کردن دستورman insmodمراجعه فرمائید.

ü      برای مشاهده Module هایی که از کارتهای PCI استفاده میکنند از دستور lspciاستفاده نمایید.

چگونه Module ها را در هر زمان که نیاز داشتیم اجرا کنیم ؟

            می توانید Module هایی که نیاز دارید در هنگام کار کردن با لینوکس با دستور modprobeاجرا کنید. Module ها را می توانید از دایرکتوری /lib/modules/ اجرا کنید. به عنوان مثال اگر نیاز دارید که iptables را که برای کنترل ترافیکهای مختلف در شبکه به کار می آید، اجرا کنید دستورات زیر در هنگام بالا آمدن دستگاه این کار را انجام می دهند.

تهیه آخرین نسخه کرنل لینوکس :

:: قبل از هر چیز به این نکته توجه داشته باشید که احتمالاً به زودی به دلایل امنیتی، اضافه کردن سخت افزارهای جدید به سیستم، افزایش کارایی و یا شاید مشکلات موجود در کرنلها نیاز به کامپایل کردن کرنل خواهید داشت.

برای به دست آوردن نسخه های نهایی کرنل لینوکس سایتهای بسیاری وجود دارند ولی بهترین آنهاhttp://www.kernel.org می باشد. در این سایت شما شاهد قدیمیترین و جدیدترین نسخه های کرنل می باشد به همراه نمایش روزانه تغییرات صورت گرفته در کرنلها. اگر از با سرعت پایینی به اینترنت متصل هستید و یا قادر به استفاده از  FTP Server به دلیل حجم بالای کاربران نیستید، میتوانید از سایتهای مشابه که به نام Mirror مشهورند و در سایت www.kernel.org آنها را مشاهده می کنید استفاده کنید.

تمایز بین Stable Kernels و Developmental Kernels :

        کرنل های موجود به دو صورت می باشند، یک نوع از آنها کرنلهای Stable است که بدون خطا و ازکار افتادن ناگهانی (Crash) و یا اشکال مهم تست شده اند. همچنین در سیستم های بسیاری این کار صورت گرفته تا بتوان آنرا از نظر کاربران، Stable نامید. اغلب درایورها نیز در لینوکس های مختلفی تست شده اند و بدون هیچ مشکلی به کار خود ادامه داده اند تا بتوانند Stable به حساب بیایند.

            نوع دیگر از کرنل ها به Developmental مشهورند. این دسته پایداری کمتری دارند و احتمال از کار افتادن یا خطای بزرگ در آنها بسیار بیشتر است. این دسته معمولاً با تغییراتی در کرنل های Stable به دست می آیند.

  • اسم گذاری کرنل ها نیز به صورت روبرو می باشد : <Major Version>.<Minor Version>.<patch>. اولین بخش شامل شماره نگارش کرنل!! می باشد. در حال حاضر کرنل لینوکس ها با نگارش ۲ موجود می باشند. شماره دوم یا شماره وسط نشاندهنده نوع کرنل از جهت Stable یا Developmental می باشد. اگر عدد دوم زوج بود نشاندهندۀ Stable بودن کرنل و عدد فرد نشاندهندۀ Developmental بودن آن می باشد. آخرین قسمت نیز نشاندهندۀ شمارۀ Patch یا Release آن می باشد. به مثال زیر توجه کنید :

با تایپ کردن دستور “uname –a” شما میتوانید در سیستم عامل Red Hat Linux شماره نگارش و سه شناسه ای که در بالا ذکر شد را مشاهده فرمایید. میتوانید برای دیدن تنها نگارش لینوکس از دستور “uname –r” نیز استفاده نمایید.

۲٫۶٫۹-۱٫۶۶۷smp

  1. Kernel Major Number is 2
  2. Kernel is Stable : 6 is Even
  3. Patch ID is 667smp

کارهایی که پیش از کامپایل و نصب باید انجام دهیم :

زمانیکه کرنل را در کامپیوتر خود کپی می کنید یک فایل با نام README در دایرکتوری ای که کرنل در آنجا کپی شده است قرار می گیرد که مراحل کامپایل را دقیقاً توضیح داده است.

  1. پیش از همه Kernel Source Code ای را که در اختیار دارید در شاخه /usr/src قرار دهید. اگر بخواهید می توانید آنرا در شاخه دیگری قرار دهید ولی به زودی متوجه خواهید شد که بهترین مکان برای قرار دادن همان شاخه می باشد. این کارتنها توسط شناسه کاربری root امکانپذیر است.
  1. دایرکتوری جاری را به دایرکتوری کرنلی که میخواهید آنرا کامپایل کنید (در اینجا /usr/src/linux-2.6.9 ) تغییر دهید.
  1. اگر برای بار چندمی است که کرنلی را می خواهید کامپایل کنید، ابتدا باید فایلهای ایجاد شدۀ قبلی که نیازی به آنها نیست را با دستور «make mrproper» پاک کنید. برای بار اول لازم نیست این کار را انجام دهید.
  1. اگر فایلی با پسوند .conf در این دایرکتوری دیدید آنرا در یک دایرکتوری مطمئن کپی کنید. این فایل تنظیمات (Configuration) کرنل قبلی رانشان میدهد. اگر این فایل وجود ندارد با دستور «make oldconfig«آن را بسازید.

تنظیمات پیش از کامپایل درفایل .conf  :

            در جدول زیر لیست دستوراتی که برای تغییر دادن در فایل .conf به کار میروند را می بینید.

Table 2   Scripts For Modifying The .config File

Command

Description

make config

ایجاد یک محیط Text به صورت سوال کردن خط به خط برای تنظیمات کرنل. این روش بسیار وقت گیر است و زمانی به کار می رود که لازم است تنظیمات بسیار دقیقی برای کرنل جدید انجام دهیم.

make menuconfig

منوی تنظیمات در محیط Text

make gconfig

منوی تنظیمات در محیط X-Windows

هر کدام از این دستورات به شما این امکان را می دهند که امکاناتی را که نیاز دارید در کرنل خود داشته باشید به صورت درختواره ببینید و هر قسمت را به یکی از سه صورت ذیل تنظیم نمایید.

Table 3.Kernel Option Choices

Kernel Option Choice

Description

M

در این حالت خاصیتی که برای کرنل خود نیاز دارید به صورت Module در می آید. یعنی هر زمان که نیاز داشتید می توانید آنرا Load و Unload کنید. بدین ترتیب این خاصیت از حالت دائمی درون کرنل خارج می شود.

Y

در این حالت شما از کامپایلر میخواهید که زمان کامپایل کردن کرنل، خاصیت مورد نظر را به صورت دائمی و جزئی از کرنل قرار دهد. بدین صورت کرنل شما حجم بیشتری را اشغال می کند و احتمالاً سرعت دستگاه کمی پائین می آید. این کار باعث میشود که کرنل شما برای مقاصد بیشتری به کار بیاید ولی با حجم بیشتر. اگر شما تعداد زیادی از خواص کرنل را به این صورت اضافه کنید ( و به صورت M تنظیم نکنید) احتمال دارد که عمل کامپایل کردن به دلیل حجم بالای کرنل متوقف شود.

N

از کامپایل می خواهید که این خاصیت را به کرنل اضافه نکند.

:: برای کسب اطلاعات بیشتر در مورد هر کدام از خواص کرنل که در ساختن فایل .conf اهمیت دارد به مرجع شماره ۲ مراجعه فرمائید.

مراحل کامپایل کردن:

  1. بعد از مراحل بالا در کرنلهای ۲٫۴ و قبل از آن باید دستور “make dep” را اجرا میکردید تا فایلهای مورد نیاز برای کامپایل شدن آماده شوند ولی در کرنلهای ۲٫۶  و بعد از آن به این کار نیازی نیست.
  2. در مرحله بعد فایل Makefile را باز کنید و جلوی متغیر “EXTRAVERSION =” پسوندی که میخواهید به کرنل علاوه بر شماره نگارش آن اضافه شود را مشخص کنید. مثلاً اگر نگارش کرنل ۲٫۶٫۹ باشد و شما جلوی متغیر کلمه –myKernel را قید کنید، در نهایت کرنل فایلی با نام vmlinuz-2.6.9-myKernel تولید خواهد شد.
    1. فراموش نکنید که برای هر کرنل یک نام جدید انتخاب کنید.
  1. در اینجا قسمت طولانی و اصلی کامپایل شروع میشود. با اجرا کردن دستور «make bzImage» دستگاه شروع به کامپایل کردن کرنل می کند و یک فایل فشرده به عنوان کرنل به همراه فایل مورد نیاز دیگری با پسوند .img می کند.
  1. با تایپ کردن دستور «make modules» کامپایل کردن Module ها آغاز می شود. این فایلها در همان دایرکتوری /usr/src قرار می گیرند ولی در مرحلۀ می بینید که به دایرکتوری /lib/modules/ انتقال می یابند تا کرنل جدید بتواند آنها را پیدا و اجرا کند.
  2. با اجرا کردن دستور «make modules_install» شاهد آن هستید که Module ها در دایرکتوری مربوطه کپی می شوند. جدا کردن قسمتهای ۳ و ۴ این امکان را به شما می دهد که یکبار صحت کامپایل شدن Module ها را دقیق کنترل کنید قبل از اینکه آنها در دایرکتوری مربوطه کپی شوند.
  3. حالا باید کرنل و فایل .img ایجاد شده را در دایرکتوری /boot ، جایی که همۀ کرنلهای موجود باید درآن قرار بگیرند کپی کنید. این کار با اجرا کردن دستور «make install» امکان پذیر است.
    1. محتویات دایرکتوری /boot :

به روز رسانی GRUB Boot Loader :

            پس از کامپایل کردن کرنل جدید در این قسمت باید برای دستگاه خود مشخص کنید که از این پس از کرنل جدید به عنوان هسته اصلی سیستم عامل خود استفاده کند. برای این کار باید فایل /etc/grub.conf را به روز کنید. زمانی که شما دستور «make install» را اجرا میکنید، این کار به صورت خودکار انجام می شود. در فایل grub.conf دستوراتی شبیه دستورات زیر می بینید :

پارامتر default مشخص می کند که کدام کرنل به صورت پیش فرض بر روی سیستم اجرا شود. در اینجا عدد  ۱ ذکر شده یعنی کرنلی که در قسمت دوم مشخص شده. اگر این پارامتر به عدد ۰ تغییر دهید، کرنل شما کرنل پیشفرض سیستم قرار میگیرد.

محمد سخایی

منابع :

۱)      http://www.kernel.org

2)      http://www.linuxhomenetworking.com/linux-hn/kernel.htm

3)      http://www.faqs.org/docs/kernel/index.html

4)      http://snow.nl/dist/htmlc/ch01.html

5)      http://www.tldp.org/HOWTO/IBM7248-HOWTO/kernel.html

6)      http://newbiedoc.sourceforge.net/system/kernel-pkg.html#INTRO-KERNEL-PKG

7)  http://hamedvaezi.ir


[1] Ref : RED HAT Linux, Administrator’s Guide – Kerry Cox – PRIMA TECH