آشنایی با هسته لینوکس - قسمت دوم ( مقدمات کاربردی)(3063 مجموع کلمات موجود در متن) (18108 بار مطالعه شده است) در
قسمت گذشته به بررسی موضوعاتی چون تاریخچه
یونیکس و لینوکس,آشنایی
با پروژه لینوکس,
درامدی
بر سیستم های عامل و هسته ها,
مقایسه
ای بین هسته لینوکس و هسته دیگر یونیکس
ها و نسخه های هسته لینوکس پرداختیم.
در
این قسمت به بررسی مقدمات کاربردی از هسته
لینوکس خواهیم پرداخت.
در
ابتدا با نحوه دریافت و وصله کردن هسته
لینوکس اشنا خواهیم شد.
سپس
مروری بر دایرکتوری های کد هسته خواهیم
داشت.
در
بخش سوم با نحوه پیکربندی,
کامپایل
و نصب هسته اشنا خواهیم شد.
پیکربندی
بارگذار بوت (Boot
Loader) عنوان
بخش چهارم خواهد بود و در بخش اخر این
مقاله تحت عنوان ”موجودی از یک طبیعت
دیگر” به بررسی نکاتی بسیار مهم درباره
هسته لینوکس خواهیم پرداخت.
دریافت
کد هسته لینوکس
کد
منبع کنونی هسته لینوکس همیشه به دو صورت
کد کامل فشرده شده و وصله افزایشی (نسبت
به انتشار قبلی)
در
سایت رسمی هسته لینوکس یعنی
http://www.kernel.org
قابل
دسترسی است.
اگر
دلیل معینی برای استفاده از هسته های
قدیمی ندارید سعی کنید که همیشه از اخرین
نسخه پایدار هسته لینوکس استفاده کنید.
کد
کامل هسته به دو صورت فشرده gzip
و
bzip2
توزیع
می شود.
فرمت
bzip2
به
دلیل اینکه نسبت به gzip
مقدار
بیشتری فشرده می کند فرمت پیش فرض و ترجیح
داده شده در فشرده سازی هسته است.
کد
کامل فشرده شده هسته در فرمت bzip2
در
قالبی چون linux-x.y.z.tar.bz2
نام
گذاری می شود و x.y.z
در
حقیقت نسخه انتشار هسته لینوکس را نشان
می دهد.
مانند:
2.6.20 در
linux-2.6.20.tar.bz2 پس
از دریافت کد منبع هسته از مخازن kernel.org
در
صورت فشرده سازی در فرمت bzip2
با
استفاده از دستور اول و در صورت فشرده
سازی در فرمت gzip
با
استفاده از دستور دوم ان را از حالت فشرده
خارج سازید.
saied@linux:~$tar xjf
linux-x.y.z.tar.bz2 saied@linux:~$tar xzf linux-x.y.z.tar.gz
خروجی
این دستورات کد منبع هسته را از حالت فشرده
خارج می سازد و در دایرکتوری جاری تحت
دایرکتوری به نام linux-x.y.z
ذخیره
می سازد.
سوال:
کد
منبع هسته را در کجا نصب کنم؟ کد
منبع هسته را می توان در هر دایرکتوری که
کاربر جاری مجوز نوشتن دارد از حالت فشرده
خارج نمود.
معمولا
دایرکتوری ای که برای این کار مورد استفاده
قرار می گیرد usr/src/
می
باشد.
معمولا
لینکی به نام linux
که
به linux-x.y.z
اشاره
می کند نیز در این دایرکتوری ساخته می
شود.
root@linux:/home/saied#cd
/usr/src/ root@linux:/usr/src# tar xjf
/home/saied/linux-2.6.20.7.tar.bz2 root@linux:/usr/src# ln -s
linux-2.6.20.7 linux
سوال:
وصله
(patch)
چیست
و چگونه اعمال می شود؟ وصله
ها در حقیقت تفاوت یک کد منبع نسبت به کد
منبع دیگر می باشند.
توسعه
دهندگان هسته معمولا از وصله ها برای
اعمال تغییراتشان نسبت به کد منبع اصلی
هسته استفاده می کنند.
نحوه
ایجاد وصله ها با استفاده از دستور diff
می
باشدکه تفاوت های دو کد را در یک فایل جدید
با پسوند patch
یا
diff
ذخیره
می کند.
نحوه
اعمال وصله ها نیز با استفاده از دستور
patch
می
باشد. برای
اعمال وصله حتما بایستی بدانیم که وصله
را در کدام سطح از دایرکتوری هسته اعمال
کنیم.
این
اطلاعات را بایستی توسعه دهنده وصله در
اختیار قرار دهد. صورت
معمول دستور patch
به
صورت patch
-pnum < patchfile می
باشد و num
همان
شماره سطح اعمال وصله می باشد.
به
عنوان مثال وصله های افزایشی هسته لینوکس
که در بردارنده تغییرات جدید هسته نسبت
به اخرین انتشار است را می توان به صورت
زیر اعمال نمود:
root@linux:/usr/src# cd
linux-2.6.20.6
root@linux:/usr/src/linux-2.6.20.6# patch -p1 <
/home/saied/patch-2.6.20.7
مروری
بر دایرکتوری های کد هسته کد
منبع هسته شامل دایرکتوری هایی می باشد
که بیشتر انها شامل تعداد زیادی زیر
دایرکتوری هستند.
دایرکتوری
هایی که در ریشه کد منبع هسته قرار دارند
به طور مختصر در جدول ۱ لیست شده اند.
-
دایرکتوری
|
توضیحی
مختصر
|
arch
|
کدهای
وابسته به معماری سخت افزاری
|
crypto
|
کدهای
رابط رمزنگاری
|
Documentation
|
مستندات
کد منبع هسته
|
drivers
|
کدهای
راه اندازهای دستگاه ها
|
fs
|
VFS
و
فایل سیستم های مجزا
|
include
|
فایل
های سرایند هسته
|
init
|
کدهای
بوت و مقداردهی اولیه هسته
|
ipc
|
کدهای
مربوط به ارتباط بین پروسه ها
|
kernel
|
زیر
سیستم های اصلی مانند زمان بند
|
lib
|
روتین
های کمکی و اضافه
|
mm
|
زیر
سیستم مدیریت حافظه و حافظه مجازی
|
net
|
زیر
سیستم شبکه
|
scripts
|
اسکریپت
های کامپایل و ساخت هسته
|
security
|
ماجول
امنیت لینوکس
|
sound
|
زیر
سیستم صدا
|
usr
|
کدهای
فضای کاربر
|
جدول
۱-
دایرکتوری
های ریشه کد منبع هسته لینوکس
تعدادی
فایل نیز در ریشه کد منبع هسته قرار دارند.
فایل
COPYING
مجوز
هسته لینوکس (GNU
GPL v2) , فایل
CREDITS
لیستی
از توسعه دهندگان هسته که کدهای زیادی در
هسته دارند,
MAINTAINERS لیستی
از افرادی که زیر سیستم ها و راه اندازهای
دستگاه ها در هسته را نگهداری می کنند و
در نهایت Makefile
نیز
فایل ورودی make
پایه
هسته را نشان می دهد.
پیکربندی,
کامپایل
و نصب هسته
کامپایل
و ساخت هسته فرایندی بسیار اسان است.
در
حقیقت این کار بسیار ساده تر از کامپایل
و نصب دیگر اجزای در سطح سیستم مانند
کتابخانه استاندارد زبان C
گنو
(glibc)
است.
سری
هسته 2.6
سیستم
پیکربندی و ساخت جدیدی نسبت به هسته 2.4
معرفی
کرده است که کار کامپایل و ساخت هسته را
بسیار اسان می کند. به
دلیل اینکه کد منبع هسته لینوکس در اختیار
است شما می توانید قبل از کامپایل,
ان
را سفارشی و پیکربندی نمایید.
می
توانید پشتیبانی از امکانات و راه اندازهایی
را که می خواهید در ان فعال نمایید و
امکانات و راه اندازهایی را که به انها
نیازی ندارید غیر فعال کنید.
پیکربندی
هسته مرحله ای ضروری در ساخت هسته
است. پیکربندی
هسته با گزینه های پیکربندی که با پیشوند
CONFIG
شروع
می شوند کنترل می گردد به صورت CONFIG_FEATURE
. مانند
امکان چندپردازندگی متقارن (SMP)
که
با گزینه پیکربندی CONFIG_SMP
کنترل
می شود.
اگر
این گزینه تنظیم شود پشتیبانی از SMP
فعال
می گردد در غیر این صورت هسته ساخته شده
از SMP
پشتیبانی
نخواهد کرد. گزینه
های پیکربندی برای تعیین اینکه کدام فایل
ها کامپایل شوند و دستکاری کد در دستورهای
پیش پردازنده به کار می روند.
گزینه
های پیکربندی که پروسه ساخت هسته را کنترل
می کنند متغیرهای دوحالته (Boolean)
یا
سه حالته (tristate)
هستند.
یک
متغیر دو حالته فقط دو حالت yes
و
no
را
می تواند اختیار کند.
امکاناتی
از هسته مانند CONFIG_PREEMPT
متغیرهایی
دو حالته هستند یعنی در صورت انتخاب y
کامپایل
می شوند و در صورت n
کامپایل
نمی شوند.
یک
گزینه سه حالته یکی از سه حالت yes
و
no
و
module
را
می تواند اختیار کند.
حالت
module
هنگامی
که برای یک گزینه تنظیم می گردد باعث
کامپایل ان به صورت یک ماجول هسته که می
تواند به صورت دینامیک در هسته وارد شود
می گردد.
گزینه
های راه اندازها معمولا متغیرهای سه حالته
هستند.
گزینه
های پیکربندی همچنین می توانند رشته ای
از کاراکترها یا اعداد صحیح باشند.
این
گزینه ها نمی توانند رویه کامپایل و ساخت
هسته را کنترل نمایند در عوض به عنوان
مقادیری برای پیش پردازنده به کار می
روند.
به
عنوان مثال,
یک
گزینه پیکربندی می تواند اندازه یک ارایه
استاتیک را تعیین نماید.
هسته
های توزیع شده در توزیع های لینوکس به
عنوان بخشی از توزیع از پیش کامپایل شده
اند.
برخی
از این هسته های از پیش کامپایل شده امکانات
بسیار وسیعی را فراهم می کنند و از گستره
وسیعی از سخت افزارها پشتیبانی به عمل می
اورند.
شما
به عنوان یک هکر هسته بایستی بتوانید هسته
خودتان را کامپایل نمایید و با انتخاب
ماجول های لازم برای کامپایل و حذف ماجول
های غیر لازم اشنا شوید.
روش
سنتی کامپایل هسته لینوکس
خوشبختانه
هسته لینوکس ابزارهای متنوعی برای تسهیل
پیکربندی دارد.
ساده
ترین ابزار یک برنامه محیط متنی است که
برای اجرای ان به دایرکتوری کد هسته رفته
و دستور زیر را اجرا نمایید:
root@linux:/usr/src/linux#make
config
این
ابزار برای هر گزینه پیکربندی از شما سوال
می کند و شما به ان پاسخ می دهید.
به
دلیل دشواری و وقت گیر بودن این ابزار,
ابزار
دیگری مبتنی بر کتابخانه ncurses
وجود
دارد که در محیط متنی اجرا می گردد و شما
با استفاده از دستور زیر می توانید ان را
اجرا نمایید:
root@linux:/usr/src/linux#make
menuconfig
شکل
۱ نمایی از اجرای این دستور را نمایش می
دهد.
با
حرکت در منوها می توانید گزینه های پیکربندی
را تنظیم نمایید.
شکل
۱-
برنامه
پیکربندی هسته لینوکس در محیط متنی
در
محیط گرافیکی نیز دو برنامه مبتنی بر
کتابخانه های Qt
و
+Gtk
وجود
دارد.
برای
اجرای برنامه مبتنی بر Qt
دستور
make
xconfig و
برای اجرای برنامه مبتنی بر +Gtk
دستور
make
gconfig را
اجرا نمایید. شکل
۲ و ۳ نمایی از اجرای این دو محیط را نمایش
می دهد.
شکل
۲-
برنامه
گرافیکی پیکربندی هسته لینوکس مبتنی بر
کتابخانه Qt
شکل۳-
برنامه
گرافیکی پیکربندی هسته لینوکس مبتنی بر
کتابخانه +Gtk
با
استفاده از این برنامه ها با حرکت در منوها
و گروه ها می توانید هسته خود را پیکربندی
نمایید.
پس
از اتمام پیکربندی ان را ذخیره نمایید.
گزینه
های پیکربندی شما در فایلی به نام config.
در
دایرکتوری ریشه کد هسته ذخیره می گردد.
اگر
کامپایلر gcc
و
دیگر ابزارهای لازم برای کامپایل کدهای
منبع بر روی سیستمتان نصب باشد در این
قسمت می توانید شروع به کامپایل هسته
نمایید. ابتدا
از کامپایل ایمیج هسته (vmlinuz)
شروع
می کنیم.
بسته
به اینکه می خواهید از چه نوع فشرده سازی
در ساخت این فایل استفاده کنید می توانید
از ورودی های zImage
یا
bzImage
برای
دستور make
استفاده
نمایید.
رویه
فشرده سازی معمول bzImage
است.
با
استفاده از دستور زیر فایل bzImage
در
دایرکتوری arch/<architecture>/boot
ساخته
می شود:
root@linux:/usr/src/linux#
make bzImage
مرحله
بعد کامپایل ماجول های هسته است.
با
استفاده از ورودی modules
به
دستور make
می
توانید ماجول هایی را که در مرحله پیکربندی
انتخاب کردید را مورد کامپایل قرار دهید:
root@linux:/usr/src/linux#make
modules
شکل
۴-
نمایی
از پروسه کامپایل هسته را نمایش می دهد
با
استفاده از ورودی jn-
می
توانید به make
دستور
دهید که n
رویه
اجرایی همزمان اختیار نماید.
مانند:
make bzImage -j3 که
۳ رویه اجرایی همزمان در کامپایل bzImage
ایجاد
می کند.
نصب
هسته
با
استفاده از دو دستور زیر می توانید هسته
کامپایل شده خود را نصب نمایید.
دستور
اول فایل ایمیج هسته را در دایرکتوری
boot/
کپی
می نماید(x.y.z
همان
نسخه هسته است)
و
دستور دوم ماجول های هسته را در دایرکتوری
lib/modules/
نصب
می نماید:
root@linux:/usr/src/linux#cp
arch/<architecture>/boot/bzImage
/boot/vmlinuz-2.6.20.7 root@linux:/usr/src/linux#make
modules_install
پیکربندی
بارگذار بوت (boot
loader)
در
این بخش ما فقط پیکربندی grub
را
که در بیشتر توزیع های امروزی از ان استفاده
می شود را به طور مختصر بررسی می نماییم.
برای
بوت کردن سیستم با استفاده از هسته ای که
کامپایل نموده اید بایستی فایل
boot/grub/menu.lst/
(که
در بعضی توزیع ها با نام های دیگر مانند
grub.conf
وجود
دارد)
ویرایش
نمایید.
برایآشنایی
کامل با بارگذارهای بوت لینوکس مانند
grub
و
lilo
به
مستندات این دو بارگذار بوت مراجعه
کنید. برای
بوت سیستم با هسته جدید بایستی یک entry
جدید
در این فایل ایجاد نمایید.
ساختار
هر entry
در
این فایل از قسمت های زیر تشکیل شده است:
title custom-name
که
برای شما در هنگام بوت نام custom-name
را
در منوی بوت گراب نمایش می دهد.
root (hdx,y)
شما
در این دستور بایستی مقادیر x
و
y
را
تغییر دهید.
x شماره
دیسک و y
شماره
پارتیشن ای از دیسک است که فایل های ایمیج
هسته و initrd
در
ان قرار دارند.
kernel
/boot/vmlinuz-2.6.20.7 root=/dev/<root_device> <kernel_options>
این
دستور گراب فایل ایمیج هسته یا همان
vmlinuz
را
در حافظه بارگذاری می نماید.
ورودی
های این دستور مسیر به فایل ایمیج هسته,
نام
فایل دستگاه پارتیشن ریشه /
و
در نهایت دیگر گزینه های ورودی هسته هستند.
<root_device> مانند
hda5
, hdb3 , sda1 , sdb7 و
...
و
<kernel_options>
که
لیستی از ورودی های هسته می باشند مانند:
vga=792 , ramdisk_size=5000 , quiet و
...
initrd /boot/initrd.<gz
, img>-2.6.20.7
این
دستور فایل فشرده شده initrd
که
در حقیقت نوعی مکمل زمان بوت برای vmlinuz
است
در حافظه لود می نماید.
نحوه
ساخت فایل initrd
در
توزیع های مختلف متفاوت است.
برایآشنایی
با نحوه ساخت این فایل به صفحات مستندات
دستوراتی مانند mkinitrd
یا
mkinitramfs
در
توزیع خود مراجعه کنید.
و در
نهایت بوت سیستم.
گراب
با اجرای این دستورات به شرط صحت ورودی
ها و ارگومان ها خواهد توانست سیستم شما
را با استفاده از هسته لینوکسی که خود شما
کامپایل نموده اید بوت نماید.
کامپایل
هسته در سیستم های مبتنی بر دبیان
در
سیستم های دبیان دستورات مفیدی برای
کامپایل هسته و ساختن بسته deb
ان
وجود دارد.
یکی
از مفیدترین این دستورات دستور make-kpkg
می
باشد.
برایآشنایی
بیشتر با نحوه کار این دستور در سیستم های
مبتنی بر دبیان دستور man
make-kpkg را
اجرا نمایید. پس
از پیکربندی هسته به همان روالی که در
قسمت قبل بیان شد و ایجاد فایل config.
در
دایرکتوری ریشه کد هسته با استفاده از یک
دستور make-kpkg
می
توانید به سادگی هسته را کامپایل و بسته
های deb
مربوط
را ایجاد نمایید:
root@linux:/usr/src/linux#export
CONCURRENCY_LEVEL=3 root@linux:/usr/src/linux#make-kpkg
--rootcmd fakeroot --revision 1 --append_to_version -mykernel
--initrd --bzimage kernel_image kernel_headers
این
دستور باعث ایجاد دو بسته linux-image
و
linux-headers
خواهد
شد.
با
استفاده از دستور dpkg
می
توانید این دو بسته را نصب نمایید:
root@linux:/usr/src#dpkg
-i linux-image-2.6.20.7-mykernel_1_i386.deb root@linux:/usr/src#dpkg
-i linux-headers-2.6.20.7-mykernel_1_i386.deb
dpkg به
طور خودکار grub
را
پیکربندی می نماید.
موجودی
از یک طبیعت دیگر
هسته
تفاوت های متعددی نسبت به برنامه های
معمولی که در فضای کاربر اجرا می شوند
دارد.
این
بدان معنی نیست که فرایند توسعه دشوارتر
و پیچیده تری نسبت به برنامه های معمولی
دارد بلکه چالش های منحصر بفردی در توسعه
هسته وجود دارد. این
تفاوت ها هسته را به عنوان موجودی از یک
طبیعت دیگر مطرح می نماید.
اگرچه
برخی از تفاوت ها بدیهی هستند (مانند
اینکه هسته در سیستم توانایی انجام هر
کاری را دارد)
اما
برخی دیگر خیلی واضح نیستند.
مهم
ترین این تفاوت ها عبارتند از: ۱-
هسته
به کتابخانه استاندارد زبان C
دسترسی
ندارد. ۲-
کد
هسته بر اساس استاندارد GNU
C می
باشد. ۳-
هسته
مانند برنامه های معمولی فضای کاربر فاقد
حفاظت حافظه می باشد. ۴-
هسته
به سادگی نمی تواند از اعداد مبنای ممیز
شناور استفاده کند. ۵-
هسته
پشته ای کوچک با اندازه ثابت دارد. ۶-
به
دلیل اینکه درون هسته وقفه های غیرهمزمان
وجود دارند,
هسته
انحصارگرا (preemptive)
است,
از
SMP
پشتیبانی
می کند,
همگام
سازی و همزمانی موضوعاتی بسیار مهم و
اساسی در هسته هستند. ۷-
قابلیت
حمل هسته بسیار مهم است.
توسعه
دهندگان هسته به موارد بالا بایستی بسیار
توجه داشته باشند.
در
ادامه به طور مختصر به بررسی هر کدام از
موارد بالا می پردازیم:
libc وجود
ندارد
برخلاف
یک برنامه فضای کاربر,
هسته
با کتابخانه استاندارد زبان C
لینک
نمی شود.(البته
هسته با هیچ کتابخانه ای لینک نمی شود).
برای
این موضوع دلایل متعددی وجود دارد شامل
قضیه مرغ و تخم مرغ اما دلیل اصلی سرعت و
اندازه است.
کل
کتابخانه استاندارد زبان C
یا
حتی بخشی از ان نسبت به هسته بسیار حجیم
و غیر بهینه هسته هستند.
تعداد
زیادی از توابع libc
درون
هسته پیاده سازی شده اند.
به
عنوان مثال توابع معمول کار با رشته ها
در lib/string.c
پیاده
سازی شده اند.
برای
استفاده از انها <linux/string.h>
را
در کد خود ضمیمه نمایید. یکی
از محبوب ترین توابع libc
تابع
()printf
است.
هسته
به این تابع دسترسی ندارد اما تابع دیگری
به نام ()printk
را
در اختیار شما قرار می دهد.
این
تابع رشته ای فرمت شده از کاراکترها را
در بافر ثبت وقایع هسته کپی می کند که
معمولا این بافر توسط برنامه syslog
خوانده
و ذخیره می شود.
نحوه
استفاده از این تابع دقیقا مشابه ()printf
است
با این تفاوت که ()printk
می
تواند ماکرویی تحت عنوان اولویت نمایش
رشته را نیز دریافت دارد.
اگر
این اولویت از اولویت پیش فرض ترمینال
جاری کمتر بود رشته ورودی در ()printk
به
جای ذخیره در فایل مربوط به ثبت وقایع
هسته بر روی صفحه نمایش ظاهر می شود.
printk(KERN_ERR “this
is an error!\n”);
GNU C
هسته
لینوکس مانند دیگر هسته های یونیکس با
استفاده از زبان C
پیاده
سازی شده است.
در
عین حال هسته لینوکس کاملا بر اساس
استاندارد ANSI
C توسعه
نیافته است.
در
عوض,
توسعه
دهندگان هسته هر جا که امکان استفاده از
قابلیت های اضافی که در gcc
(مجموعه
کامپایلرهای گنو – GNU
Compiler Collection که
شامل یک کامپایلر زبان C
است
که برای کامپایل هسته و هرانچه که در یک
سیستم لینوکسی به زبان C
توسعه
یافته است به کار می رود)
وجود
دارد مهیا بوده از ان استفاده کرده اند.
توسعه
دهندگان هسته هر دو استاندارد ISO
C99 و
GNU
C Extentions را
به کار برده اند.
این
تغییرات هسته لینوکس را به gcc
گره
زده است اگرچه اخیرا کامپایلرهای دیگری
مانند کامپایلر زبان C
اینتل
از بیشتر امکانات gcc
به
طرز مناسبی پشتیبانی می کند که باعث شده
هسته توسط این کامپایلر نیز کامپایل گردد.
استاندارد
ISO
C99 که
هسته از ان بهره می برد نکته ویژه ای ندارد,
به
دلیل اینکه C99
بازنگری
رسمی زبان C
می
باشد تغییرات کمی نسبت به استاندارد ANSI
دارد.
بیشترین
تغییرات غیراشنا که ممکن است در کد هسته
لینوکس مشاهده نمایید توسط امکانات موجود
در GNU
C فراهم
امده است.
بعضی
از این امکانات عبارتند از: توابع
inline,
اسمبلی
inline,
پیش
بینی شاخه بر اساس شرط و ...
. این
موارد از سطح این مقاله خارج است و به
خواننده واگذار می گردد.
حفاظت
حافظه وجود ندارد
هنگامی
که یک برنامه فضای کاربر سعی در دسترسی
به یک حافظه غیرمجاز می کند هسته می تواند
خطایی ایجاد کند,
سیگنال
SIGSEGV
به
ان پروسه بفرستد و انرا بکشد.
حال
اگر خود هسته به یک حافظه غیرمجاز دسترسی
پیدا کند نتیجه ان نسبت به حالت قبل کنترل
کمتری خواهد داشت.
(چه
کسی خطای هسته را خواهد گرفت؟) نتیجه
نقض دسترسی مجاز به حافظه در هسته موجب
ایجاد اتفاقی در هسته خواهد شد که اصطلاحا
oops
نامیده
می شود که یک خطای بنیادی در هسته است.
اتفاقاتی
در هسته مانند ارجاع یک اشاره گر NULL
می
تواند شرایط وخیمی در هسته و در سیستم
ایجاد کند.
علاوه
بر ان حافظه هسته قابل صفحه بندی یا اصطلاحا
pageable
نیست.
بنابراین
هر بایتی که شما در هسته مصرف می کنید یک
بایت از حافظه فیزیکی کسر می شود.
بنابراین
هرهنگام که برای هسته امکان جدیدی را
توسعه می دهید بسیار مراقب این نکته باشید.
به
سادگی نمی توان از اعداد مبنای ممیز شناور
استفاده کرد
هنگامی
که یک برنامه فضای کاربر از دستورات ممیز
شناور استفاده می کند هسته تبدیلات بین
نوع داده ای integer
به
حالت floating
point را
مدیریت می کند.
کاری
که هسته برای استفاده از دستورات ممیز
شناور بایستی انجام دهد در هر معماری نسبت
به معماری دیگر متفاوت است اما هسته معمولا
کلکی می زند و کاری در پاسخ انجام می
دهد. برخلاف
فضای کاربر,
هسته
امکان پشتیبانی یکپارچه از مبنای ممیز
شناور را ندارد زیرا نمی تواند به خود کلک
بزند.
استفاده
از ممیز شناور در خود هسته نیازمند ذخیره
و بازیابی ثبات های ممیز شناور است.
به
طور مختصر:
این
کار رانکنید و از دستورات ممیز شناور در
هسته استفاده نکنید.
پشته
کوچک و ثابت
برنامه
های فضای کاربر می توانند هزاران هزار
متغیر را در پشته به خود تخصیص دهند شامل
ساختارهای داده بسیار بزرگ و ارایه هایی
با عناصر زیاد.
این
کار در فضای کاربر مجاز است به دلیل اینکه
پشته در فضای کاربر بزرگ است و می تواند
به صورت دینامیکی بزرگ یا کوچک شود. اما
بر خلاف مورد بالا پشته هسته نه بزرگ است
و نه دینامیک و کوچک و با اندازه ثابت می
باشد.
اندازه
دقیق پشته در هر معماری نسبت به معماری
دیگر متفاوت است. در
معماری x86
اندازه
پشته در زمان کامپایل قابل پیکربندی به
مقادیر 4k
یا
8k
است.
از
لحاظ تاریخی پشته هسته دو صفحه از حافظه
است که در معماری ۳۲ بیتی 8k
و
در معماری ۶۴ بیتی 16k
خواهد
بود.
همگام
سازی و همزمانی
هسته
مستعد پذیرش شرایط رقابت بر سر منابع
مشترک است.
برخلاف
یک برنامه تک رشته ای فضای کاربر,
تعدادی
از خواص هسته این اجازه را می دهد که دسترسی
همزمان به منابع مشترک صورت پذیرد و برای
مقابله با نتایج منفی بایستی همگام سازی
و مقابله با رقابت صورت پذیرد.
به
طور خاص:
۱-
لینوکس
یک سیستم عامل چند کاره (multitasking)
و
انحصارگرا (preemptive)
است.
پروسه
ها بر اساس تصمیم زمان بند سیستم عامل
زمان بندی می شوند.
هسته
بایستی بین این کارها همگام سازی انجام
دهد.
۲-
هسته
لینوکس از چندپردازندگی (multiprocessing)
پشتیبانی
می کند.
بنابراین
بدون یک حفاظت صحیح,
اجرای
کد هسته بر روی دو یا چند پردازنده به طور
همزمان می تواند باعث دسترسی همزمان به
بعضی منابع مشترک گردد.
۳-
وقفه
ها به طور غیرهمزمان نسبت به اجرای کد
جاری اتفاق می افتند.
بنابراین
بدون یک حفاظت صحیح یک وقفه می تواند در
بین دسترسی به یک منبع مشترک اتفاق بیفتد
و تابعی که به وقفه پاسخ می دهد می تواند
به همان منبع دسترسی پیدا کند و کار را
خراب نماید.
۴-
هسته
لینوکس یک هسته انحصارگرا (preemptive)
است.
بنابراین
بدون حفاظت,
کد
هسته می تواند در حین اجرا قطع شود و کد
دیگری از هسته به همان منبع مشترک دسترسی
یابد.
راه
حل های متداول برای مساله شرایط رقابت
شامل استفاده از spinlock
ها
و semaphore
ها
می شود.
در
اینده به این مقوله به طور مفصل تری خواهیم
پرداخت.
قابلیت
حمل بسیار مهم است
اگرچه
برنامه های فضای کاربر لزوما با هدف قابلیت
حمل نوشته نمی شوند ولی لینوکس یک سیستم
عامل قابل حمل (portable)
است.
این
بدان معنی است که کد زبان C
ای
که به معماری سخت افزاری وابسته نیست
بایستی بر روی گستره وسیعی از معماری ها
به درستی کامپایل و اجرا گردد و ان بخش از
کد وابسته به معماری سخت افزاری بایستی
به درستی در دایرکتوری مجزا در کد هسته
لینوکس تفکیک شوند.
در
اینده به این مقوله به طور مفصل تری خواهیم
پرداخت.
در
اینجا قسمت دوم از مجموعه مقالاتآشنایی
با هسته لینوکس تحت عنوان مقدمات کاربردی
به پایان می رسد.
در
قسمت اینده به بحث مدیریت پروسه ها خواهیم
پرداخت و مباحثی چون مشخصه پروسه ها,
ساختارهای
داده مربوط به پروسه ها در هسته,
ایجاد
و خاتمه پروسه ها و پیاده سازی رشته ها
(threads)
در
هسته لینوکس را از نظر خواهیم گذراند.
نویسنده:
سعید
تقوی
s.taghavi@ece.ut.ac.ir
منابع
مطالعاتی
:
1- The Linux kernel Source Code
(http://kernel.org )
2- The Linux Kernel Documentations
(inside the source tree).
3- D.P. Bovet,“Understanding the
Linux Kernel”, 2nd ed, O'Reilly, 2002.
4- R.Love,“Linux Kernel
Development”, 2nd ed, Sams, 2005.
5- J.Corbert and others,“Linux
Device Drivers”, 3rd ed, O'Reilly, 2005.
6- A.Silberchatz and
others,“Operating System Concepts”, 7th ed, John Wiley, 2006.
7-
http://www.tldp.org/LDP/lkmpg/2.6/html
PDF Version
|