در قسمت قبلی به بررسی کرنل و ساختار فایل های آن پرداختیم، حالا در این قسمت به سراغ پیکربندی کرنل لینوکس و درایور ها میپردازیم و آنها را کامپایل میکنیم.
آشنایی با پیکربندی (configuration) کرنل لینوکس
یکی از نقاط قوت لینوکس این هست که برای هر دیوایس و کاربردی میشه پیکربندیش کرد. از یه وسیله ساده مثل یه ترموستات الکترونیکی تا یه وسیله پیچده مثل موبایل اصلاً پیکربندی لینوکس، خودش یه کار مفصلی هست و یه تخصص محسوب میشه که مکانیستم پیکربندی کرنل لینوکس Linux Kernel Kconfig
نام داره و بیلدسیستمی که همراهش هست هم Kbuild
بهش میگن.
این سیستم Kconfig
و Kbuild
توی پروژههای دیگهای هم استفاده شدن مثل یوبوت فصل قبل یا کراستولانیجی دو فصل قبل یا بیزی باکس و بیلدروت که در آینده باشون آشنا میشیم.
تقریباً توی تمامی فولدرهای کرنل لینوکس فایل Kconfig
وجود داره.
این فایلها قواعد و سینتکس مشخصی دارن و با استفاده از اونها میتونید تنظیمات مختلف به کرنل بدین.
اگه اولین فایل رو بازکنید اولین خطی که بعد از کامنتها میبینید این هست:
mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"
که گویا اولین چیزی که باید مشخص بشه معماری پردازنده هست. اگه بریم توی فولدر arch و باز فایل کانفیگ رو بازکنیم اولین خط بعد از کامنتها این هست
source "arch/$(SRCARCH)/Kconfig"
فایلهای Kconfig
پر از منو هستن که با کلیدواژهی menu
شروع و با endmenu
تموم میشن.
مثلاً یکی از منوهای drivers/char/Kconfig
رو با هم ببینیم و بررسی کنیم:
menu "Character devices" [...] config DEVMEM bool "/dev/mem virtual device support" default y help Say Y here if you want to support the /dev/mem device. The /dev/mem device is used to access areas of physical memory. When in doubt, say "Y". [...] endmenu
برای پیکربندی DEVMEM
یه متغیر bool داریم که مقدار پیشفرضش y هست و در قسمت help
هم توضیحات لازم رو در خصوص این متغیر به ما داده.
برای پیکربندیهای مختلف این مدل متغیرها رو داریم.
برای اینکه نخوایم دونه دونه این فایلها رو بازکنیم و بررسی کنیم و مقداردهی کنیم و … ابزارهای کمکی هستن که میتونیم بهصورت گرافیکی این کارها رو انجام بدیم.
آشناترینش menuconfig
هست که قبلاً هم ازش استفاده کردیم.
برای اینکه وارد منوی پیکربندی کرنل لینوکس بشیم طبق اولینig
نیاز داریم فایل Kconf
معماری پردازنده رو تعیین کنیم.
در خصوص رسپبریپای معماری ما arm64
هست و برای لیچیپای معماری ما arm
هست.
cd ~/EmbeddedLinux/RPI3BP/kernel/linux-5.15.43/ make ARCH=arm64 menuconfig
خب الان همچین صفحهای باید جلوتون باز بشه:
الان اگه برید توی منوی Device Drivers
و بعد برید توی منوی Character devices
میتونید تنظیمات DEVMEM
رو ببینید.
توی این منوها * یعنی این ویژگی/ درایور در کرنل لینوکس باشد، M یعنی به صورت ماژولار باشد و خالی بودن به معنای نبودن در کرنل لینوکس هست.
ماژولار یعنی اینکه بیلد میشه اون درایور ولی فقط در زمان اجرا به کرنل لینوکس الحاق میشه و جزیی استاتیک از کرنل نیست.
در اینجا هم یه سری فایلهای defconfig
از قبل تعریف شده واسه بردها و پردازندههای مختلف هست که خیلی از بخشهای پیکربندی رو توی خودشون دارن و کار رو سادهتر میکنن.
برای هر معماری توی این فولدر میتونید ببینید این فایلها رو:
arch/$ARCH/configs
من پیشنهاد میکنم همیشه برای پیکربندی وقت بذارید تا بهترین پیکربندی رو داشته باشین. اینجوری هم زمان اجرای کرنل کمتر میشه و هم بهینهتر هست.
به عنوان تمرین، این دو منو و گزینههای انتخاب شده رو با هم مقایسه کنید تا متوجه بشید. این رو هم بگم که ما از پیکربندی پیشفرض دوم برای ادامه مسیر استفاده میکنیم.
#1) cd /EmbeddedLinux/RPI3BP/kernel/linux-5.15.43 make ARCH=arm64 defconfig make ARCH=arm64 menuconfig #2) cd ~/EmbeddedLinux/RPI3BP/kernel/linux make ARCH=arm64 bcmrpi3_defconfig make ARCH=arm64 menuconfig
ماژولهای کرنل لینوکس Linux Kernel
آخرین مطلبی که قبل از ساختن کرنل لینوکس لازم هست بدونید در مورد ماژولها هست. ماژولهای کرنل لینوکس توی سیستمهای دسکتاپ خیلی بهدردبخور و پرکاربرد هستن. چون یک کرنل لینوکس قرار هست روی سیستمهای خیلی زیادی با امکانات و وسایل جانبی خیلی متنوع اجرا بشه.
توی دنیای امبددلینوکس تقریباً همهچیز و کلیهی سختافزارها همان روز اول مشخص هستن پس عملاً نیاز خاصی نیست که از ماژولها استفاده کنیم و توصیه کریس هم این هست که استفاده نکنیم چون بعدش وابستگیهای زیادی میاره.
کریس میگه سه تا دلیل هست که میتونه استفاده از ماژولهای کرنل لینوکس رو منطقی کنه:
۱- مسائل مربوط به کپیرایت.
۲- کاهش زمان بوت شدن کرنل لینوکس با لود نکردن درایورهای غیرضروری.
۳- زمانی که درایورهای زیادی هست و استاتیک بودن اونها نیازمند حافظه زیادی هست، مثلاً شما یه پورت USB دارین که سختافزارهای زیادی رو پشتیبانی می کنه.
قبل از ساختن کرنل لینوکس چندتا سؤال و جواب داشته باشیم:
کدام فرمت کرنل لینوکس Linux Kernel رو انتخاب کنیم؟
وقتیکه کرنل لینوکس رو میسازیم چند تا خروجی داریم که یکیش همون فایل کرنل لینوکس هست.
این فایل میتونه فرمتهای مختلفی داشته باشه، اول باید ببینیم ما کدوم فرمت رو میخواهیم.
اگر بوت لودر ما یوبوت باشه: یوبوت درگذشته فرمت uImage
رو قبول میکرد ولی الان zImage
رو هم قبول میکنه و با دستور bootz
میشه اجراش کرد.
کامپیوترهای X86: باید از فرمت bzImage
استفاده کرد.
بقیه بوتلودرها: معمولاً همون zImage
رو استفاده میکنن.
به جز کرنل لینوکس Linux Kernel چه چیزی رو باید بیلد کنیم؟
بهجز کرنل لینوکس دیوایس تری هم حتماً باید ساخته بشه.
ماژولها رو هم میتونیم بسازیم یا نه بستگی داره که از اونها در آینده میخوایم استفاده کنیم یا نه.
چه فایلهایی ساخته میشن و به چه کاری میان؟
Vmlinux
که در حقیقت فایل ELF
کرنل لینوکس هست و System.map
همیشه ساخته میشن بعدش از روی vmlinux
فایل باینری کرنل لینوکس که اسمش Image
هست، ساخته میشه و از روی اون فرمتهای مختلف کرنل لینوکس مثل zImage
و uImage
ممکنه ساخته بشن.
بریم که کرنل لینوکس رو بسازیم
بعد از پیکربندی کرنل لینوکس بهراحتی و با انتخاب معماری و کراس کامپایل میشه کرنل لینوکس روساخت:
یادتون نرفته که ما یه فایل داریم با این محتویات
#!/bin/sh export GCC=/home/at00/EmbeddedLinux/RPI3BP/build-tools/at00toolchain/bin/aarch64-linux-gnu-gcc export PATH=$PATH:/home/at00/EmbeddedLinux/RPI3BP/build-tools/at00toolchain/bin/
حالا این دو خط رو هم بش اضافه میکنیم:
export ARCH=arm64 export CROSS_COMPILE=/home/at00/EmbeddedLinux/RPI3BP/build-tools/at00toolchain/bin/aarch64-linux-gnu-
اول بریم سرجای درست
cd ~/EmbeddedLinux/RPI3BP/kernel/linux
مرحله بعدش طبق راهنمایی خود بنیان باید این رو هم پشت سر بذاریم:
KERNEL=kernel8
و در نهایت بریم بزنیم ساخته بشه
make -j$(nproc) Image modules dtbs
میتونید ماژول رو به تنهایی بزنید برای بیلد شدن ماژولها و یا dtbs
رو برای دیوایس تری و یا به جای Image
از zImage
یا uImage
استفاده کنید.
تمیز کردن سورس کدها
ممکنه یه وقتایی خرابکاری کنیم یا اصلاً بنا به هر دلیل دیگه بخوایم همهچیز برگرده به زمانی که سورس رو دانلود کردیم میتونیم از این سه تا دستور استفاده کنیم:
make clean make mrproper make distclean
کریس اینا رو در موردشون میگه:
یه سری هم به نظرات این پایین بندازید، نظرات رو به خونید و اگر شما همنظری دارید، لطفاً با ما به اشتراک بگذارید!
همه آموزش های امبدد لینوکس
منبع: سیسوگ