به نام خدا 

سلام

بالاخره بعد از چند وقت تونستم وقت کنم و به کار های مورد علاقه ام بپردازم

یکی از کار های مورد علاقه من کامپایل لینوکس برای برد خودم هست.

کلا اینکه برنامه های 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

امیدوارم مفید بوده باشه

موفق باشید

یا علی مدد.