Product SiteDocumentation Site

8.10. کامپایل یک کرنل

کرنل‌هایی که توسط دبیان ارائه می‌شوند بیشترین تعداد از ویژگی‌های ممکن را دارا هستند، به همراه بیشترین درایورهای پشتیبانی شده به منظور اینکه پاسحگوی طیف گسترده‌ای از پیکربندی‌های سخت‌افزاری باشند. این همان دلیلی است که برخی کاربران ترجیح می‌دهند تنها نیازهای مربوط به خود در نسخه کامپایل شده از کرنل داشته باشند. برای این انتخاب دو دلیل وجود دارد. نخست اینکه برای بهبود بخشیدن عملکرد سیستم، تنها بخشی از کد کرنل که مورد نیاز است کامپایل می‌شود و این کد حتی اگر استفاده نگردد باز حافظه مربوط به خود را اشغال می‌کند (که این حافظه هیچگاه به swap منتقل نمی‌شود چرا که دقیقا حافظه اصلی یا RAM سیستم است) که این کار می‌تواند به کند شدن عملکرد کلی سیستم منجر گردد. دوم اینکه یک کرنل کامپایل شده با نیازهای خاص احتمال بروز مشکلات امنیتی را کاهش داده چرا که تنها بخش مشخصی از کدهای کرنل کامپایل شده‌اند.
کامپایل‌مجدد کرنل تنها زمانی لازم است که بخواهید از قابلیت‌های جدید ارائه شده در patchها استفاده کنید (که در نسخه استاندارد کرنل قرار ندارند).

8.10.1. مقدمه و پیش‌نیاز

تعجبی ندارد که دبیان کرنل را به مانند سایر بسته‌های نرم‌افزاری مدیریت می‌کند، که با شیوه قدیمی کامپایل و نصب کرنل‌ها تفاوت دارد. از آنجا که کرنل در کنترل سیستم بسته‌بندی قرار دارد، به راحتی می‌تواند حذف یا روی دستگاه‌های دیگری نصب گردد. علاوه بر این، اسکریپت‌های موجود در این بسته‌ها عملیات مربوط به راه‌اندازی اولیه سیستم و تولید initrd را انجام می‌دهند.
سورس کد اصلی لینوکس شامل هر آنچه که برای ساخت یک بسته دبیان لازم است، می‌باشد. اما هنوز نیاز به نصب بسته build-essential را دارید تا اطمینان یابید جعبه‌ابزار شما برای ساخت بسته‌های دبیان کامل شده است. علاوه بر این، گام پیکربندی برای کرنل نیازمند بسته libncurses5-dev است. در نهایت، بسته fakeroot امکان ایجاد بسته دبیان بدون استفاده از مجوزهای سطح بالا را فراهم می‌کند.

8.10.2. دریافت منابع

Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the linux-source-version package. The apt search ^linux-source command lists the various kernel versions packaged by Debian. The latest version is available in the Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of قسمت 6.2.6, “کار با چندین توزیع مختلف” ). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches, which might (or might not) find their way into the upstream version of Linux. These modifications include backports of fixes/features/drivers from newer kernel versions, new features not yet (entirely) merged in the upstream Linux tree, and sometimes even Debian specific changes.
The remainder of this section focuses on the 4.9 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-4.9 package has been installed. It contains /usr/src/linux-source-4.9.tar.xz, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-4.9.tar.xz

8.10.3. پیکربندی کرنل

گام بعدی پیکربندی کرنل با توجه به نیاز خودتان است که عملیات دقیق آن به اهداف شما بستگی دارد.
زمانی که نسخه‌ای جدیدتر از کرنل را مجدد کامپایل می‌کنید (احتمالا به همراه یک patch اضافه)، پیکربندی تا آنجا که ممکن است به شیوه دبیان نزدیک خواهد بود. در این مورد، و بجای آنکه همه چیز را از ابتدا پیکربندی کنید، تنها کافی است از فایل /boot/config-version (نسخه‌ای که کرنل کنونی از آن استفاده می‌کند که با استفاده از دستور uname -r قابل خواندن است) در .config که در دایرکتوری شامل سورس کد کرنل می‌باشد، رونوشت بگیرید.
$ cp /boot/config-4.9.0-3-amd64 ~/kernel/linux-source-4.9/.config
اگر قصد تغییر در پیکربندی موجود را ندارید، می‌توانید در این مرحله توقف کرده و به قسمت قسمت 8.10.4, “کامپایل‌کردن و ساختن بسته” بروید. اگر می‌خواهید تغییرات را انجام دهید، از طرف دیگر، یا اینکه همه چیز را از اول پیکربندی کنید، باید زمان برای این ییکربندی سفارشی را مد نظر قرار دهید. رابط‌های انحصاری مختلفی در دایرکتوری سورس کد کرنل وجود دارند که می‌توان با استفاده از دستور make target فراخوانی کرد، که target یکی از مقادیر موجود در زیر است.
make menuconfig یک رابط متنی (که از بسته libncurses5-dev می‌آید) را کامپایل و اجرا می‌کند که اجازه پیمایش گزینه‌های پیکربندی مختلف را به صورت ساختار درختی می‌دهد. فشردن کلید Space مقدار گزینه انتخابی را تغییر می‌دهد و کلید Enter دکمه انتهای صفحه را فرا می‌خواهند؛ Select به زیر منو انتخابی باز می‌گردد؛ Exit صفحه جاری را بسته و به ساختار قبلی باز می‌گردد؛ Help نیز راهنمایی بیشتر درباره گزینه‌های موجود را نمایش می‌دهد. کلیدهای جهت‌نما نیز برای پیمایش در صفحه استفاده می‌شوند. برای خروج از برنامه پیکربندی، Select را از منوی اصلی انتخاب کنید. برنامه درخواست ذخیره‌سازی تغییرات شما را می‌دهد؛ در صورت راضی بودن از تغییرات آن‌ها را تایید کنید.
سایر رابط‌ها نیز عملکرد مشترکی دارند، اما به شیوه برنامه‌های گرافیکی مدرن کار می‌کنند؛ مانند make xconfig که از رابط گرافیکی Qt و make gconfig که از رابط گرافیکی +GTK بهره می‌برند. اولی به کتابخانه libqt4-dev و دومی به کتابخانه‌های libglade2-dev و libgtk2.0-dev نیاز دارند.
هنگام استفاده از این رابط‌ها برای پیکربندی، ایده خوبی است که از یک پیکربندی پیش‌فرض آغاز کنید. کرنل چنین پیکربندی‌هایی را در فایل arch/arch/configs/*_defconfig ارائه داده که می‌توانید آن‌ها را با استفاده از دستور make x86_64_defconfig (در مورد یک رایانه ۶۴ بیتی) یا make i386_defconfig (در مورد یک رایانه ۳۲ بیتی) انتخاب کنید.

8.10.4. کامپایل‌کردن و ساختن بسته

زمانی که پیکربندی کرنل آماده باشد، یک دستور ساده make deb-pkg تا ۵ بسته دبیان را تولید می‌کند: linux-image-version که شامل کرنل و ماژول‌های مربوطه است، linux-headers-version که شامل فایل‌های سرآیند برای ساخت ماژول‌های اضافی است، linux-firmware-image-version که شامل فایل‌های مورد نیاز برخی درایورها است (این بسته هنگامی که از منابع کرنل دبیان استفاده می‌کنید ممکن است وجود نداشته باشد)، linux-image-version-dbg که شامل گزینه‌های عیب‌یابی برای کرنل و ماژول‌های آن است و در نهایت linux-libc-dev که شامل فایل‌های سرآیند برخی برنامه‌های سمت کاربر مانند کتابخانه GNU glibc می‌باشد.
version توسط الحاق نسخه توسعه‌دهنده اصلی (که توسط متغیرهای VERSION، PATCHLEVEL، SUBLEVEL و EXTRAVERSION در فایل Makefile مشخص می‌شود) از LOCALVERSION پارامتر پیکربندی و LOCALVERSION متغیر محلی است. نسخه بسته از همان رشته تولید شده به همراه یک عدد که به صورت ترتیبی افزایش می‌یابد بهره می‌گیرد (که در فایل .version ذخیره می‌شود) مگر آنکه را با استفاده از متغیر محلی KDEB_PKGVERSION بی‌تاثیر سازید.
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot-dbg_4.9.30-1_amd64.deb
../linux-libc-dev_4.9.30-1_amd64.deb

8.10.5. کامپایل‌کردن ماژول‌های خارجی

برخی ماژول‌ها خارج از کرنل رسمی لینوکس مدیریت می‌شوند. برای استفاده از آن‌ها، باید همراه با نسخه مربوطه کرنل کامپایل گردند. تعدادی از ماژول‌ها به صورت جداگانه توسط دبیان و در بسته‌های مختص به خود مانند xtables-addons-source (ماژول‌های اضافی برای iptables) یا oss4-source (سیستم آزاد صوتی، برخی درایورهای مبتنی بر صدا) فراهم آمده‌اند.
تعداد این بسته‌های خارجی بسیار زیاد است و فرصت مطرح کردن آن‌ها را در این قسمت نداریم؛ دستور apt-cache search source$ می‌تواند فهرست مختصری از آن‌ها را به شما نمایش دهد. اگرچه، دارا بودن فهرست کاملی از این ماژول‌ها مادامی که ندانید به کدام یک نیاز دارید و کدام یک اضافی است، کاربرد خاصی ندارد. در این موارد، مستندات مربوط به دستگاه یا سخت‌افزاری که می‌خواهید از آن در لینوکس استفاده کنید به این نکات اشاره می‌کنند.
برای نمونه، بیایید نگاهی به بسته xtables-addons-source بیندازیم: پس از نصب، فایل .tar.bz2 از منابع ماژول در مسیر /usr/src/ قرار می‌گیرد. با اینکه می‌توانیم این فایل را از حالت فشرده خارج ساخته و ماژول مورد نظر را تولید کنیم، در عمل از ابزار DKMS به منظور خودکارسازی این فرآیند استفاده می‌کنیم. اکثر ماژول‌ها انطباق با مکانیزم DMKS را در نام بسته‌هایی که به -dkms ختم می‌شوند ارائه می‌دهند. در این مورد، نصب بسته xtables-addons-dkms تنها کار مورد نیاز به منظور کامپایل این ماژول برای کرنل فعلی نصب شده است که بسته linux-headers-* مختص به آن می‌باشد. برای نمونه، اگر از linux-image-amd64 استفاده می‌کنید، باید بسته linux-headers-amd64 را نصب داشته باشید.
$ sudo apt install xtables-addons-dkms

[...]
Setting up xtables-addons-dkms (2.12-0.1) ...
Loading new xtables-addons-2.12 DKMS files...
Building for 4.9.0-3-amd64
Building initial module for 4.9.0-3-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.9.0-3-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.12, 4.9.0-3-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/4.9.0-3-amd64/updates/dkms/xt_ACCOUNT.ko
license:        GPL
alias:          ipt_ACCOUNT
author:         Intra2net AG <opensource@intra2net.com>
description:    Xtables: per-IP accounting for large prefixes
[...]

8.10.6. اعمال یک وصله در کرنل

برخی ویژگی‌ها به دلیل مناسب نبودن با استانداردهای کرنل یا عدم تفاهم بین توسعه‌دهندگان آن، در نسخه استاندارد کرنل قرار ندارند. چنین ویژگی‌هایی در قالب وصله یا patch وجود دارند که به صورت آزادانه توسط کاربران می‌توانند به یک نسخه از کرنل اضافه گردند.
Debian sometimes provides some of these patches in linux-patch-* packages but they often don't make it into stable releases (sometimes for the very same reasons that they are not merged into the official upstream kernel). These packages install files in the /usr/src/kernel-patches/ directory.
برای اعمال یک یا چندی از این وصله‌ها، از دستور patch در دایرکتوری اشاره شده استفاده کنید سپس به کامپایل‌ مجدد کرنل طبق روش‌های بالا بپردازید.
$ cd ~/kernel/linux-source-4.9
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
نکته اینکه یک وصله مشخص به طور خاص با تمام نسخه‌های کرنل کار نمی‌کند؛ از این رو امکان ناموفق بودن عملیات همراه با دستور patch وجود دارد. یک پیام خطا هنگام بروز چنین مشکلی همراه با جزئیات آن نمایش داده می‌شود؛ در این مورد، به مستندات موجود در بسته دبیان مربوط به فایل وصله (در دایرکتوری /usr/share/doc/linux-patch-*/) مراجعه کنید. در اکثر موارد، نگهدارنده بسته اشاره می‌کند که وصله برای کدام یک از نسخه‌های کرنل کار می‌کند.