به نام خدا
سلام
بالاخره بعد از چند وقت تونستم وقت کنم و به کار های مورد علاقه ام بپردازم
یکی از کار های مورد علاقه من کامپایل لینوکس برای برد خودم هست.
کلا اینکه برنامه های Bare-Metal بنویسم
یعنی برنامه ای به زبان سطح پایین که به صورت مستقیم روی سخت افزار اجرا بشه بدون هیچ سیستم عاملی
خب اولین چیزی که بهش نیاز داریم اینه که چطوری باید یه برنامه رو برای آرم کامپایل کنیم
در حال حاضر کامپایل برنامه های زبان سی برای سیستم عامل هایی مثل لینوکس و ویندوز به سادگی تایپ gcc a.c هست (البته اگه شما هم مثل من اسم فایل ها رو a میزارید :))
اما این قضیه برای کامپایل یه برنامه برای یه معماری متفاوت و بدون سیستم عامل فرق میکنه
ما میتونیم از دو کامپایلر برای این کار استفاده کنیم که من دوست دارم هر دو رو یاد بدم
اولیش کامپایلر رایگان GCC هست که اسمش gcc-arm-none-eabi هست که شما هم میتونید مثل من روی ویندوز هم نصبش کنید
کار با این ابزار زیاد سخت نیست
مثلا دستور زیر برای کامپایل فایل a.c استفاده میشه:
arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -c a.c -o a.o
همچنین برای لینک کردن سه فایل a.out , b.out , c.out و ساخت فایل d.elf میتونید از دستور زیر کمک بگیرید:
arm-none-eabi-ld a.o b.o c.o -T memmap -o d.elf
و در آخر ساخت فایل bin :
arm-none-eabi-objcopy d.elf -O binary d.bin
اما چیزی که من بخاطرش این مطلب رو نوشتم استفاده از کامپایل رسمی arm هست که خود شرکتش ارایه اش میکنه (البته لاینسنس داره که نمیدونم لایسنس اش پولی هست یا نه)
برای اینکه بتونید لاینسنش رو دور بزنید میتونید برنامه Keil رو نصب کنید و اون رو کرک کنید اون با خودش کامپایلرش رو هم نصب میکنه که میتونید ازش استفاده کنید. (فقط حواستون باشه که مشکلش اینه که نمیتونید باهاش برای پردازنده های ۶۴ بیتی کامپایل کنید)
لینک های زیر مفید هستن
https://developer.arm.com/tools-and-software/embedded/arm-compiler/downloads/version-6
https://developer.arm.com/tools-and-software/embedded/arm-compiler/documentation
https://developer.arm.com/docs/100748/latest
خب طبق چیزایی که از خود داکیومنتش یاد گرفتم برای کامپایل برنامه زیر باید چیکار کنیم؟
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
خب اولین چیزی که ما باید بهش توجه کنیم اینه که ما میخواهیم این کد رو برای یه پردازنده ۳۲ بیتی کامپایل کنیم یا برای پردازنده ۶۴ بینی؟
دومین چیزی که باید بهش توجه کنیم اینه که ما میخواهیم اینو برای چه معماری یا برای چه پردازنده ای کامپایل کنیم؟
طبق چیزی که خود داکیومنتش گفته شما میتونید مشخص کنید که این کد رو میخواید برای چه معماری (march) یا برای چه سی پی یو یی (mcpu) کامپایل کنید
خب فرقش چیه؟
سی پی یو میشه چیزایی مثل cortex-a7 cortex-a53 cortex-a72 و...
و معماری میشه ARMv7-A , ARMv8-A یا ARMv7-M که برای میکرو کنترلر هاست
خب پردازنده ای مثل کورتکس آ۷ معماری اش ARMv7-A هست حالا ما باید برای کامپایل برنامه به کامپلر یکی از اینا رو بدیم
فرق چیه؟
اگه ما پردازنده رو بدیم برنامه خروجی کاملا برای اون سی پی یو بهینه میشه اما اگه معماری رو بدیم برنامه برای سی پی یو خاصی بهینه نمیشه و خوبیش اینه که روی همه سی پی یو ها با اون معماری قابل اجراست.
خب سه مرحله کامپایل اینجا چجوری انجام میشه؟
برای کامپایل فایل a.c از کد زیر استفاده میکنیم:
armclang -c a.c --target=arm-arm-none-eabi -mcpu=cortex-a7 -o a.o
و برای کامپایل فایل اسمبلی b.s از دستور زیر استفاده میکنیم.
armclang -c b.s --target=arm-arm-none-eabi -mcpu=cortex-a7 -o b.o
و برای لینک کردنش:
armlink a.o b.o -o c.axf
که به ما فایل c.axf رو خروجی میده و برای ساخت فایل باینری از این باید از دستور زیر استفاده کنیم:
fromelf --bin --output=outfile.bin ali.axf
امیدوارم مفید بوده باشه
موفق باشید
یا علی مدد.
سلام.
کاکو کارت عالیه