آموزش نوشتن سیستم عامل قسمت چهارم

سلام!
خوب از اسم این پست که دیگه میدونید قصدم چیه!
آره آموزش چهارم سیستم عامل نویسی
ولی!:
ولی چی؟
به صورت متنی!
چرا؟
چون هم درد سرش کمتره, همم اینجوری راحتتر دستوراتو میفهمید, همم فضای کمتری اشغال میشه!
نگران نباشید!, من تک تک, خط به خط ترجمه میکنمشون
تو این آموزش خوشگل یه بوت لودر برا گراب مینویسیم, و یه هسته کوچولو
خوب گراب چیه؟
یه بوت لودر اوپن سورس
که میتونه سیستم عاملارو از رو CD, hard disk, floppy و حتی از رو یه شبکه بوت کنه!
خوب یه سوال:
چه جوری این گراب کار میکنه؟
این آقای گراب, یه لطفی میفرمایند سیستمو از حالت 16 بیت درش میارن, میبرنش تو حالت 32 بیت و بعدش هسته سیستم عامل شما رو که الآن باید به روش خواصی به حالت multi boot درش کنیم (multiboot header) بهش بدیم, بعدش شناخته میشه
خوب این multiboot چیه؟
multiboot در حقیقت یه روش بوته که اگه فرض سیستم عامل شما بوت نشدن, میره یکی دیگه و دیگه که به ترتیب بهش شناخته شده رو بوت میکنه!
خوب فرض که ما بوت لودرو نوشتیم!
حالا بعدش تو این آموزش چی کار میکنیم؟
مثل بچه آدم, میریم یه پیغام hello Operating System Development world رو نشون میدیم
خوب سرت درد گرفت؟
حالا مونده!
تو آموزشای بعدی گریه میکنی!
خوب بریم بوت لودرمونو بنویسیم!

یه فایل به اسم boot.s درست کنید و این دستورات اسمبلی رو توش بنویسید

[bits 32] ;this code run's on 32 bit protected mode
global boot ;boot function to load are kernel!
extern main ;our main function to load from the bootloader (we work it on C programming language)
;do not edit these!
section .boot
align 0x4 ;boot alignment!
MODULEALIGN equ 1<<0 ;the boot alignment module!
MEMINFO equ 1<<1 ;we say grub to show the memory output!
FLAGS equ MODULEALIGN|MEMINFO ;this is the flags that represent's our alignment and memory output!
MAGIC equ 0x1BADB002 ;the boot magic
CHECKSUM equ -(MAGIC+FLAGS) ;the boot checksome: must not be edited or removed
boothdr:
dd MAGIC
dd FLAGS
dd CHECKSUM
;you can modify here!
boot:
push ebx ;this code push's the multiboot in the EBX register
call main ;call our main function
jmp $ ;halt's the system

تا اینجا OK?
اما خط به خط توضیح میدم!
وای خدا!
; یعنی توضیح
باید اینو دیگه فهمیده باشید!
[bits 32]
این کد میگه که کد تو 32 بیت protected mode اجرا میشه!
protected mode چیه؟
ببینید تو 16 بیت ما چیزی به اسم protected mode یا pMode نداریم!
خیل خوب حالا چیه؟
از اسمش معلومه دیگه!
به خاطر اینکه تموم حافظه سیستم دست برنامه ها نمیفته
یا بهتره بگم یه سری قسمتای سیستم محافظت شدست
حالا برای اینکه بهتر بگم, تو سیستم عاملنویسی, ما 4 تا دسترسی داریم
0 بیشترین دسترسی (kernel mode), 1 و 2 بیشتر برا سرورا و 3 usermode که کمترین دسترسی به کامپیوتر باشه و ویندوز و لینوکس و بیشتر سیستم عاملای دیگه رو این حالت یعنی usermode اجرا میشن
واسه همینه که بهش میگن pMode که رو سی پی یوای 32 بیتی وجود داره
اما خط بعدی
global boot
این خط میگه که یه تابع به اسم boot تعریف کن که کدشو تو همین فایل مینویسیم و سیستم عاملمونو باهاش بوت میکنیم (البته با گراب!)
خط بعدی!
extern main
این کد میگه که یه تابع دیگه به اسم main بساز که تو این فایل نیست و میشه ازش اینجا استفاده کرد
خط بعدی
section .boot
اینم توش چیزایی که گراب بهشون احتیاج داره رو میزاریم!
align 0x4
MODULEALIGN equ 1<<0
MEMINFO equ 1<<1
FLAGS equ MODULEALIGN|MEMINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC+FLAGS)
اینام متغیرایین که گراب بهشون احتیاج داره
دستورات بعدی
boothdr:
این خطم multiboot header رو تعریف میکنیم که گراب از اینجا بوت هسته رو بخونه و به مقادیر متغیرای بالا دسترسی داشته باشه
dd MAGIC
dd FLAGS
dd CHECKSUM
اینجام متغیرا رو تعریف میکنیم
خط بعدی
boot:
اینجام که خودتون میدونید بوت لودر شروع میکنه به کار کردن
خط بعدی
push ebx
این خط زیاد مهم نیست (میتونید ننویسیدش!) ولی پیشنهادش میکنم
خوب این کد میگه که مقدار هدر مولتی بوتو بریز تو رجیستر ebx
خط بعدی
call main
میفرمایند که تابع اصلی هسته رو اجرا کن!
خط بعدی
jmp $
این کدم میتونید ننویسیدش!
فقط سیستمو میبره رو یه حلقه تموم نشدنی

اما یه فایل به اسم linker.ld بسازید
و اینا رو توش بنویسید!

ENTRY(Boot)

/* sections that we have to modify in order to load grub */
SECTIONS
{
/* Begin putting sections at 1 MB, a conventional place for kernels to be loaded at by the bootloader. */
. = 1M;

/* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.boot)
*(.text)
}

/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}

/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}

/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
}

خط به خط ترجمه میکنم اینم
/* میگه که یه توضیح شروع شده و */ میگه که توضیح تموم شده
اما دستور اول
ENTRY(Boot)
میگه سیستم عامل باید از تابع boot که تو boot.s نوشتیم بوت شه
خط بعدی!
SECTIONS
اینجام چیزایی رو تعریف میکنیم مثل .text که دستورات سیستم عامل باشن, .rodata که متغیرای سیستم عامل باشن و بقیشون!
خط بعدی
{
اینم یه آکولاده که میگه بقیه سکشنا میتونن ردیف بشن
خط بعدی
=1m;
بهش زیاد گیر ندید که گیج میشید!
فقط باید بهتون بگم که هسته سیستم عاملو رو یه مگابایت لود میکنه
یه سکشنو شرح میدم, بقیشو خودتون میفهمید
.text BLOCK(4K) : ALIGN(4K)
{
*(.boot)
*(.text)
}
اولیش میگه که 4 کیلوبایت برا دستوراتمون در نظر بگیر
بعد از آکولادم اول بوت لودرمونو میزاریم که باید حتما این کارو بکنیم, بعدش دستورات سیستم عاملو
یه جورایی میچینیمشون کنار هم دیگه
خط آخر!
}
اینم میگه که دیگه سکشنا بسته شدن!
اما یه فایل به اسم main.c بسازید و اینارو توش بنویسید:

void main()
{
*((uint)0xB8000)="Hello Operating System Development World!";
}

اینم ترجمه میکنم برید حال کنید!
void main()
میگه که تابع main که تو boot.s تعریف کردیم اینجا تعریف شه
خط بعدی!
{
اینجام محتویات تابعو مینویسیم
خط بعدی!
این خط مقدار Hello Operating System Development World رو به مقدار 0xB8000 میده که مقدار کارت گرافیک باشه!
خط آخر!
}
اینجام تابع تموم میشه
اما کامپایل
یه فایل به اسم build.sh بسازید
اینارو توش بزنید
اینارو توضیح نمیدم چون اینارو تک تک میتونید تو خط فرمان لینوکس و یا cygwin بنویسید
اما محتویاتش!

nasm -f elf boot.s -o boot.o
gcc -c main.c -o main.o -ffreestanding -fno-exceptions -fno-rtti -Wall -Wextra -nodefaultlibs -nostdlib
gcc main.o boot.o -O kernel -T linker.ld -fno-exceptions -fno-rtti -nodefaultlibs -nostdlib -lgcc
mkdir iso
cd iso
mkdir boot
cd boot
mkdir grub
cd ../../
mv kernel iso/boot/kernel
grub-mkrescue --output=myos.iso iso

خوب برید تو iso تو boot تو grub و یه فایل به اسم grub.cfg درست کنید و اینارو توش کپی کنید!


menuentry "my operating system" {
kernel /boot/kernel
}

بعدش بیاید تو پوشه اصلی سیستم عامل و فایل build.sh رو اجرا کنید

sh build.sh

حالا یه فایل به اسم myos.iso آماده خدمته!
حالشو ببرید!
هر سوالی بود در خدمتم!
فعلا!

درباره امیر رضا رمضانی

من امیر رضا رمضانی متولد سال 1370 در بچگی با اثر برخورد ضربه شدید به سرم هشتاد درصد دیدمو از دست دادم در 12 سالگی شروع به یاد گیری زبان برنامه نویسی C++ کردم در 16 سالگی Assembly را یاد گرفتم، در 17 سالگی دست به نوشتن گیم انجین Allegro game creator زدم و در 18 سالگی دست به نوشتن سیستم عامل AmirOS زدم البته این سیستم عامل هنوز در دست تکمیل است ولی به لطف خدا نوشته میشود
این نوشته در آموزش, آموزش های رایگان ارسال و , , برچسب شده است. افزودن پیوند یکتا به علاقه‌مندی‌ها.

6 Responses to آموزش نوشتن سیستم عامل قسمت چهارم

  1. 1
    منصور says:

    سلام چقدر میگیری واسم یه لینکر درست کنی ؟
    میخوام لینکر درستورات سی را بخونه

  2. 2
    محمد says:

    با سلام
    به چه برنامه ای فایل build.sh را اجرا و کامپایل کنیم(با چه برنامه ای)؟

  3. 3
    محمد says:

    با سلام
    با چه برنامه ای فایل build.sh را اجرا و کامپایل کنیم(با چه برنامه ای)؟

  4. 4
    mi_ameri says:

    سلام
    ممنون خیلی خوب توضیح دادید . استفاده کردم
    می شه لطفا فایل قسمت سوم آموزش رو اصلاح کنید ؟! دیگه نمی شه از رو سایت برش داشت … اگه کمک کنید ممنون می شم
    یا اگرم کس دیگه ای فایل رو داره لطف کنه به دست بنده برسونه
    m.ameripour110@gmail

  5. 5
    mohammad says:

    سلام
    ممنون خیلی خوب توضیح دادید . استفاده کردم
    می شه لطفا فایل قسمت سوم آموزش رو اصلاح کنید ؟! دیگه نمی شه از رو سایت برش داشت … اگه کمک کنید ممنون می شم
    یا اگرم کس دیگه ای فایل رو داره لطف کنه به دست بنده برسونه
    m.ameripour110@gmail

  6. 6

    سلام خیلی ممنون امیر
    اینها رو گفتی ولی من یه چیزی رو نفهمیدم.
    اگه این کدها رو بنویسیم چطوری بدون بینایی بفهمیم که آیا اجرا شده یا نشده؟
    اگه سیستم رو بوت کنیم راهی برای خوندن پیغام هاش نداریم.

دیدگاهتان را بنویسید