در قسمت قبل توضیحات کلی در مورد بخشهای سختافزاری برد sinux f1 دادیم و از این به بعد میخواهیم وارد بحث نرمافزاری و شناساندن سختافزار به نرمافزار شویم که یکی از این راهکارها Buildroot است پس با سیسوگ همراه باشید.
بگذارید مقدمه را به این صورت شروع کنم، ما برای سیستمهای امبدد برای هر بردی باید یک ایمیج مخصوص به خودش را داشته باشیم یعنی نمیتوانیم ایمیج یک برد را برای برد دیگری استفاده کنیم (در اکثر موارد البته)، ممکن است این سؤال پیش بیاید که چگونه ما برای سیستمهای شخصی خودمان فقط یک ایمیج داریم که روی هر سیستمی با هر سختافزاری قابلنصب هست؟ واضحتر بگم، سی دی ویندوز ما میتواند برای نصب روی هر سیستمی با هر نوع cpu یا مقدار رم یا گرافیک نصب شود (در اینجا هم اکثر موارد).
شاید برای شما مفید باشد: آموزش امبدد لینوکس از 0 تا 100
اما چگونه ممکن است؟
جواب ما در bios است! در سیستمهای شخصی ما قطعهای به نام bios داریم که هر مادربردی این قطعه را دارد و امکان ندارد بایوس یک مادربرد را برای مادربرد دیگر استفاده کرد، چرا که بایوس اطلاعات سطح پایین سختافزار را مثل آدرس و میزان رم و میزان گرافیک را نگهداری میکند.
شاید با خودتون بگید که ما خودمون رم یا گرافیکهای مختلف را در مادربرد میزنیم پس بایوس مقدارش را از کجا میفهمه!؟ باید بگم که روی هر رم و کارت گرافیک یک چیپ هست که اطلاعات مثلاً ان رم را برای بایوس ارسال میکند و همه اطلاعات دیگر را در خودش دارد و هنگام روشن شدن سیستم این اطلاعات را برای سیستمعامل ارسال میکند تا بتواند خودش را راهاندازی کند.
اما در بردهای امبدد، ما چنین قطعهای نداریم! چرا؟! اصلاً چرا باید داشته باشیم؟؟! اسمش روش هست، سیستم امبدد، ما یک سیستم امبدد را برای یک کاربرد خاص استفاده میکنیم پس همه منابع و ارتباطات سختافزاری ما محدود، مشخص، و غیرقابل تغییر هستند، پس نیازی به چیزی مانند بایوس نداریم و اطلاعات سختافزاری ما (نام آن device tree است که در آینده به آن اشاره میکنیم) را هم در سیستمعامل قرار میدهیم و به همین دلیل آن ایمیج روی سختافزاری با منابع متفاوت قابلاجرا نیست (البته این فقط یک دلیل است و غیر از آن نوع پردازنده که خودش شامل چندین ویژگی میشود و دلایل دیگر هم هستند که توضیح آنها از هدف این مطلب دور است).
ابزار ها
این نکته را هم باید در نظر بگیرید که یک سیستمعامل نیاز به چندین نرمافزار دارد که تعداد آنها کم نیست، که نام آنها در لینوکس پکیج میباشد ، حالا در نظر بگیرید که دهها پکیج دارید که هرکدام از آنها ممکن است نیاز به چندین پکیج دیگر داشته باشند و هر کدام از آنها باید از جایی دانلود شوند، در کنار یکدیگر قابلاجرا باشند و تداخل نداشته باشند، کامپایل شوند و فایلهای خروجی آنها در پوشههای مشخص در فایلهای سیستم قرار بگیرند، اگر کمی بیشتر درباره این مراحل و مراحل دیگری که برای ساخت یک سیستمعامل کامل انجام شود فکر کنید شاید اصلاً از این کار منصرف شوید! به دلیل زمان زیادی که گرفته میشود و در بعضی موارد شاید غیرممکن باشد برای کاربر انسانی به همین دلیل ابزارهایی برای تسهیل این فرآیند آماده شده تا شما نگران آن نباشید!?
yocto و buildroot ازجمله این ابزارها هستند که البته یوکتو کاملتر هست و این کاملی بدون هزینه نیست، ازجمله آن میتوان به فضای زیادی که اشغال میکند اشاره کرد مثلاً در حالت عادی ممکن است برای ساخت ایمیج تنها برای یک برد حدود 100 گیگ فضا اشغال کند. اما buildroot سبکتر است و نسبت به یوکتو سادهتر میباشد. ما برای این برد از بیلد روت استفاده میکنیم.
لازم است برای درک بهتر buildroot چند مورد دیگر را هم بهصورت کوتاه و خلاصه توضیح دهیم:
1- toolchain
تولچین اولین چیزی است که برای امبدد لینوکس نیاز داریم و از آن برای کامپایل کدها استفاده میکنیم، و شامل ابزارهایی مثل کامپایلر، لینکر و کتابخانههای موردنیاز است.
یکی از مهمترین این کتابخانهها کتابخانه C است، همانطور که در شکل زیر میبینید c library رابط بین نرمافزارها و هسته سیستمعامل میباشد.
2- bootloader
بوت لودر دو وظیفه اصلی داره، اول راهاندازی اولیه سیستم و بعد از آن اجرای Kernel، همچنین device tree را برای کرنل آماده میکند. device tree همانطور که در بالا هم اشاره شد برای تعریف بخشهای سختافزار بهکار میرود هم ویژگیهای خود SOC و هم ویژگیها برد، مثلاً در آن بخش i2c را تعریف میکنیم و آدرس رجیستر های i2c رو مشخص کرده و میگوییم اگه دیتایی در i2c آمد به کدام درایور ارسال بشه و پینهای i2c کدام است (البته یکسری از مقداردهیها ارجاعی به بخش دیگر از device tree هستند).
3- kernel
وظیفه اصلی کرنل مدیریت منابع، ارتباط با سختافزار و آمادهسازی یک AP I برای برنامههای کاربر هست.
در شکل بالا یک نمای کلی از وظایف کرنل نشان داده شده. نرمافزارهایی که در بخش user space اجرا میشوند درخواستهایشان توسط c library به kernel space ارجاع داده میشود و از آنجا روی سختافزار اجرا میشود. خود Kernel دارای امکانات مختلفی هست که در زمان کامپایل، کانفیگ های آن مشخص میشود، بهطور مثال درایورهای مختلف میتواند در کرنل قرار داده شود که البته هرچه تعداد آنها بیشتر باشد، حجم کرنل بالاتر رفته و بهتبع زمان لود شدن آن بیشتر میشود.
4- root filesystem
ما همه بخشهای بالا را استفاده میکنیم تا درنهایت بتوانیم برنامه خودمان را اجرا کنیم، چیزی که در root file system قرار میگیرد. البته باید در نظر داشت که برای اجرای برنامه ما مسلماً باید بخشهای دیگری از سیستمعامل اجرا شده باشند، مثلاً درایور شبکه راهاندازی و به شبکه متصل شده باشند، یا صفحهنمایش ما راهاندازی شده و آماده نمایش اطلاعات باشد، خوب کرنل از کجا بداند چه برنامهای را اجرا کند؟! برای حل این مسئله ما برنامهای با نام init داریم که آدرس آن در فایل سیستم، هنگام لود کرنل توسط بوت لودر، به کرنل اعلام میشود.
برنامه init که خودش انواع مختلفی دارد، به ترتیب نرمافزارهایی که باید اجرا شوند را مشخص و اجرا میکند حتی میتوانید در فایل کانفیگ مشخص کنید که هر برنامه نیاز دارد، تا چه برنامههایی قبل از آن اجرا شوند یا اگر برنامهای بسته شد دوباره اجرا شود یا نه و … . همانطور که گفته شد یکسری از ابزارها خیلی نیاز هستند تا ما بتوانیم یک استفاده ساده از سیستم کنیم، مثلاً دستورات ls, cat, grep,mkdir, cd و غیره هر کدوم یک ابزار محسوب میشوند که ما در ترمینال آنها رو اجرا میکنیم، حالا برای راحتی کار و یک راهاندازی سبک، نرمافزاری آماده شده به نام busybox که در آن دستوراتی مثل مواردی که اشاره شد و خیلی بیشتر را تعبیه کردند با حجم بسیار کمتر، به قول خودشون 80 درصد ابزارهای کاربردی رو با 20 درصد کد پیادهسازی کردند.
حالا با اتمام مقدمهای طولانی به سراغ اصل مطلب میرویم!
buildroot چیست؟
تصویر بالا کل فرایندی که buildroot انجام میدهد را نشان داده، buildroot یکسری makefile و patch هست که فرایند تهیه یک محیط لینوکس را برای یک سیستم امبدد، ساده و خودکار میکند. درواقع یک تولچین، روت فایل سیستم، کرنل و uboot را برای برد ما آماده میکند و در آخر هم یک ایمیج که شامل همه این بخشها هست را به ما میدهد که فقط کافی است اون رو بریزیم روی sd و اجرا کنیم.
کامپایل buildroot
وقتشه که بریم سراغ اجرایی کردن دانسته هامون:
سیستمی که برای استفاده از buildroot نیاز داریم لازم نیست که مشخصههای خیلی بالایی داشته باشد اما دقت کنید که ما قرار است کامپایل کنیم و هرچه CPU قویتری داشته باشیم سریعتر کامپایل انجام میشود، به نظر من یک سیستم معمولی برای این کار هم مناسب است مثلاً با core i5، CPU یا core i7 نسل 4.
از بابت سیستمعامل هم، ترجیحاً استفاده از لینوکس بدون ماشین مجازی هست و بهتر است که لینوکس را روی سیستم بوت و استفاده کنید (اگه هم علاقه شدیدی به ویندوز دارید میتوانید از WSL 2 استفاده کنید و buildroot را با کمک آن استفاده کنید (دردسر هاش با خودتون?).
من هم خودم از توزیع Ubuntu نسخه 2018 استفاده میکنم و شما هم بهتره که همین کار را انجام دهید ، نکتهای که برای لینوکسیها ثابتشده است اینکه جدیدتر همیشه بهتر نیست (جدیدتر همیشه پر باگ تر است!) پس نسخه 2020 رو پیشنهاد نمیکنم.
حالا ترمینال را باز کرده و شروع میکنیم، اول از همه با دو دستور زیر پکیجهای مورد نیازمان را نصب میکنیم:
1 2 | sudo apt install wget unzip build-essential git bc swig libncurses-dev libpython3-dev libssl-dev sudo apt install python3-distutils |
حالا پروژه را دانلود کرده و وارد پوشه میشویم:
1 2 | git clone https://github.com/mahdi2001h/buildroot-sinux cd buildroot-sinux |
دقت کنید که لازم نیست هیچکدام از دستورات buildroot با sudo اجرا شود!
با دستور
1 | make sisoog_sinux_f1_defconfig |
کانفیگ های خود را اعمال میکنیم (منظور از کانفیگ ها نسخه کرنل و بوت لودر، پکیجهایی که باید نصب شوند و … است، کمی پایینتر در مورد آن صحبت شده).
حالا برای شروع فرآیند build دستور زیر را وارد میکنیم
1 | make |
این هم از خروجی دستور بالا در صورت درست بودن همه چیز:
دستور make مراحل زیر را انجام میدهد:
- دانلود سورس کد ها
- کانفیگ و بیلد تولچین (یا استفاده از تولچینی که خود ما میدهیم)
- کانفیگ و بیلد پکیج هایی که مشخص کردیم
- بیلد کرنل
- بیلد بوت لودر
- ساخت root file system
- ساخت ایمیج نهایی
خروجی بیلد ما در پوشه output
قرار میگیرد که خودش شامل چند زیرپوشه میباشد:
- images: همه ایمیج های خروجی ما اینجا هستند (مثل ایمیج کرنل و بوتلودر و فایل سیستم) در واقع فایل هایی هستند که باید روی برد خودمان بریزیم.
- build: همه کامپوننت هایی که بیلد شدند در این پوشه هستند
- host: ابزار هایی که برای بیلد استفاده شدند و
sysroot
تولچین در این پوشه هستند ، مثلا میتوانید در پوشه host/bin به کراس کامپایلر دسترسی پیدا کنید و از آن برای کامپایل برنامه های خود ، استفاده کنید. - و…
کانفیگ buildroot
حالا نگاهی به فایل کانفیگ buildroot که استفاده کردیم میاندازیم و بخشهای مهم را بررسی میکنیم.
(منظور فایلsisoog_sinux_f1_defconfig
است که در پوشه configs
قرار داره، البته که خود نامگذاریها و کامنت ها تا حدی گویای کاری است که انجام میدهند )
در بخش بوت لودر کانفیگ خودمان را توسط پارامتر BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
مشخص کردیم تا از کانفیگ دیفالت جلوگیری شود. درBR2_TARGET_UBOOT_CUSTOM_DTS_PATH
دو مقدار را مشخص کردیم که یکی dtsi هست که بیشتر شامل ارجاع به فایل های دیگر (i از include میاد) و اطلاعات soc هست و dts که شامل اطلاعات بر اساس برد خودمان و بخش هایی که استفاده کردیم است.
در بخش kernel
هم نسخه کرنل و پچ هایی که باید روی کرنل اعمال شود مشخص شده و کانفیگ و …
دربخش fielsystem
مشخص شده که فایل سیستم ما با چه فرمت هایی ساخته شود (مثلا هم با فرمت ext2 برای ریختن روی sd card و هم فرمت لازم برای ریختن روی nand flash). در آخر هم پارامتری با نام BR2_ROOTFS_POST_IMAGE_SCRIPT
داریم که اسکریپتی را اجرا میکند که وظیفه ی اسکریپت این است که فایل های کرنل و بوت لودر و فایل سیستم را در کنار هم قرار میدهد و یک ایمیج میسازد که آن ایمیج را میتوانیم روی sd یا nand flash بریزیم.
در قسمت Target Package
هم پکیج هایی که میخواهیم نصب شوند را مشخص میکنیم لازم هست که پکیج ها با نامی که در اینجا مشخص شده اند در package در پوشه اصلی بیلدروت وجود داشته باشند.
با این دستور هم میتوانید به صورت گرافیکی کانفیگ های buildroot را اعمال کنید.
1 | make menuconfig |
در قسمت بعد به سراغ ساخت ایمیج و اجرای آن روی سختافزار میرویم.
دانلود رایگان شماتیک و PCB برد توسعه SINUX F1
فایل های طراحی را میتوانید به صورت رایگان از گیت هاب من دریافت کنید!
در این بخش میتونید به همه قسمتهای سری آموزش کار با تراشه F1C100S دسترسی پیدا کنید:
خیلی ممنون
راهی برای دانلود جدای فایل ها هست؟
هربار تو پوشه جدید بخوام مجدد این مراحلو از اول برم٬ بعد از زدن دستور make باید کلش دوباره دانلود بشه و هربار چیزی حدود 10 گیگ دانلود میکنه
و تقریبا بالای دو ساعت طول میکشه این فرایند 😐
محتویات پوشه download رو از داخل buildroot کپی کنید که هر بار نخواید دانلودش کنید
بعدم چرا باید هر بار تو پوشه جدید این کارو انجام بدید ؟؟!
سلام
من مراحل رو یکی یکی جلو رفتم ولی در نهایت برای ساخت ایمیج ۲ تا خطا گرفت البته پوشه output به همراه چند فایل ساخته شد ولی کامل نیستند.
مرحله اول
sudo apt install wget unzip build-essential git bc swig libncurses-dev libpython3-dev libssl-dev
sudo apt install python3-distutils
مرحله دوم
make sisoog_sinux_f1_defconfig
در این مرحله مشکلی نبود.
مرحله سوم
make
با خطای زیر مواجه شدم
usr/bin/make -j1 O=/home/saeed/F1C100s/buildroot-sinux/output HOSTCC=”/usr/bin/gcc” HOSTCXX=”/usr/bin/g++” syncconfig
You seem to have the current working directory in your
PATH environment variable. This doesn’t work.
make[1]: *** [support/dependencies/dependencies.mk:27: dependencies] Error 1
make: *** [Makefile:84: _all] Error 2
از چه توزیع لینوکس و چه نسخه ای استفاده میکنید؟
اوبونتو 20.04
تو توضیحات نوشته بودید که شما از نسخه 18 استفاده کرده اید ولی من این نسخه رو از قبل داشتم
یعنی مشکل از نسخه لینوکس هست؟
میتونه از این باشه
من پیشنهادم این هست که از اوبونتو 18 استفاده کنید
اگه بازم تست کردید و نشد سوالتون رو توی انجمن بپرسید تا مراحل رو با هم چک کنیم
سلام
با تشکر از شما
وقتی دستور make را می زنیم ارور 404 رو برای یو ار ال https://buildroot.org/ می ده به نظرم دیگه این لینک موجود نیست چه باید بکنیم؟
سلام
خواهش میکنم
عذرخواهی بابت تاخیر
من بررسی کردم این رو ولی نتونستم اون فایلی رو که قبلا دانلود کرده بودم رو دوباره پیدا کنم و checksum متفاوتی میگرفتم ، چون این پکیج رو خودم اضافه کرده بودم ، اما شما میتونید فعلا از داخل این فایل board/sisoog/sinux/f1/sisoog_sinux_f1_defconfig
کانفیگ
BR2_PACKAGE_RTL8188EUS=y
رو غیر فعال بکنید تا بتونید از بقیه قابلیت ها استفاده کنید
تا من اولین فرصت این پکیج رو هم درستش کنم
درود
با تشکر فراوان از شما بابت انتشار این مطالب بسیار ارزشمند و مفید
سوالی که میخواستم بپرسم این هست وقتی ما برای این امبدد سیستم ها ایمج های سفارشی میسازیم که سیستم عامل رو روی برد ما اجرا کنه چطور در ساخت یک محصول از کپی کردن این ایمج میتونیم محافظت کنیم و جلوی کپی برداری برد رو بگیریم و یا کلا از کپی شدن برنامه خودمون محافظت کنیم؟!؟
با تشکر
سلام
خواهش میکنم???
حقیقتا چون معمولا به سیستم های امبدد دسترسی فیزیکی هست یه جورایی میتونیم فقط سخت تر کنیم دسترسی به اطلاعاتمون رو (البته به اندازه کافی،ولی میگم سخت تر چون بستگی داره اطلاعات ما چقدر مهم باشه و طرف مقابل ما چقدر براش ارزش قائل باشه و کی باشه ، یه شخص باشه ، یه شرکت باشه یا یه مجموعه بزرگ تر! ).
نحوه حفاظت هم خودش چندتا مطلب میشه براش نوشت که شاید در آینده این کار رو انجام بدیم.
اما در حال حاضر میتونید این لینک ها رو بررسی کنید
https://embeddedbits.org/introduction-embedded-linux-security-part-1/
https://embeddedbits.org/introduction-embedded-linux-security-part-2/
سلام
ممنون از مطلب خوبتون
در قسمتی که دستور make sisoog_sinux_f1_defconfig رو وارد میکنم پیام زیر نمایش داده میشه و هیچی ساخته نمیشه.به نظرتون مشکل از کجاست؟
Nothing to be done for ‘sisoog_sinux_f1_defconfig’
سلام.
خواهش میکنم ?
دقت کنید که این دستور رو داخل خود پوشه buildroot-sinux باید اجرا کنید
همچنین اگر که در زمان انتشار مطلب پروژه رو از گیت گرفتید یه مشکل کوچیک داشت که برطرف شده و باید دوباره ریپازیتوری رو pull یا clone کنید.
اگر هم که الان که کامنت گذاشتید پروژه رو دانلود کردید احتمالا همین پوشه ای که گفتم رو داخلش نیستید
آره من اشتباه میکردم تو دایرکتوری configs اجرا میکردمش
ممنون مهدی عزیز!
خواهش میکنم ??
سلام
دمتون گرم. مطالبتون و نگارشتون عالیه.
در مورد یک چیپ دیگه از allwinner در روال فلش، مدام حرف از firmware میزنه. البته من هنوز عمیق نشدم وکار عملی باهاش رو شروع نکردم.
متوجه نمیشم منظورش از firmware چیه. کرنل بوت لودر سیستم فایل یا چی!
سلام
خواهش میکنم??
منظورتون از “در روال فلش“ متوجه نمیشم.
معمولا برای دستگاه های امبدد به همون ایمیج نهایی (که شامل بوت لودر و سیتم فایل و کرنل ) فریمور گفته میشه.
با سلام و تشکر از شما آقا مهدی و ریچ_دد
در مرحله اجرای دستور make configfile فایل پیکربندی sisoog_sinux_f1_defconfig که ls میگیرم اشاره به فایل /home/mahdi2001h/projects/buildroot-sinux/board/sisoog/sinux/f1/sisoog_sinux_f1_defconfig داره که به یک مسیر شخصی اشاره میکنه. من دستور زیر رو اجرا کردم نمیدونم کار درستی کردم یا که نه
ln -sf ../board/sisoog/sinux/f1/sisoog_sinux_f1_defconfig config/sisoog_sinux_f1_defconfig
و فعلا در حال Build هست …، فقط سوال اینکه سیستم از کجا میفهمه که از چه تولچینی باید استفاده کنه؟ آیا اون هم توی پیکربندی مشخص میشه؟
سلام خواهش میکنم??
بله شما کار درستی کردید?
مثل اینکه لینک درست نیست من توی گیتهاب اصلاحش میکنم ، ممنون که اطلاع دادید
منظورتون رو از چه تولچینی متوجه نمیشم
تولچین باید بر اساس نسخه کتابخونه c و معماری پردازنده باشه که ما این اطلاعات رو در همین فایل کانفیگی که بهش اشاره کردید بهش میدیم و خودش از سورس کامپایل میکنه برامون. اطلاعات بیشتر رو میتونید توی این لینک بررسی کنید:
https://buildroot.org/downloads/manual/manual.html#_cross_compilation_toolchain
توی قسمت هشتم و نهم آموزش “امبدد لینوکس” هم اشاره ای به این بحث تولچین شده
چقدر لذت بخش بود.. کلی یاد گرفتم.. تشکر کردن خیلی کمه برای این پروژه. واقعا عالی هستید.
ممنون از شما ، همین انرژی هاتون باعث میشه که ادامه بدیم ?.
نحوه ساخت این فایل هم توضیح میدید.sisoog_sinux_f1_defconfig
احتمالا منظور شما این هست که اگر برای برد خودمون خواستیم چنین فایلی بسازیم چیکار باید بکنیم ؛ روش مناسبش این هست که یک فایل کانفیگ مشابه که نزدیک هست به کارتون رو انتخاب کرده و یکسری پارامتر هایی که نیاز دارید رو فقط داخلش تغییر بدید ، به طور مثال من خودم از کانفیگ licheepi nano استفاده کردم ، برای اعمال تغییرات توی اون هم میتونید هم به صورت دستی و متنی تغییرش بدید و یا با کمک دستور make menuconfig به صورت گرافیکی تغییراتتون رو اعمال کنید و بعد ذخیرش کنید.
سلام. از کجا بفهمیم برای برد امبدد لینوکسی داریم طراحی میکنیم چه پردازنده ای رو انتخاب کنیم؟ ممنون میشم توضیح بدید یا قسمت بعدی آموزش در این خصوص هم صحبت کنید
سلام. سوال خوبی رو اشاره کردید. انشالله در چند قسمت بعد بهش اشاره میکنیم (احتمال زیاد البته ?)
اما شما فعلا میتونید این مطلب رو https://jaycarlson.net/embedded-linux/
یه بررسی بکنید که خیلی کمک کننده هست در رابطه با این موضوع.
بسیار عالی 🙂
ممنون از شما ??