به نام خداوند بخشنده و مهربان!

سلام خدمت دوستان و هموطنان گرامي!

امروز گفتم بيام پست بعدي مربوط به آموزش سيستم عامل رو قرار بدم! بنابراين بريم سراغ آموزش ... foot-in-mouth

خوب ببينيد مثل پست قبلي که مطلب آموزشي ام کپي بود اينبار هم تصميم گرفتم به دليل توضيح کامل جناب آقاي عباس مقدم آموزش ايشون رو قرار بدم که توي وبلاگشون گذاشتن. با اينکار مطالب اصلي رو ياد ميگيريم و مطالب بعدي که توسعه کرنل هست رو بايد خودمون ادامه بديم sealed

پس مطالب زير يکي از پست هاي ايشون توي وبلاگشونه! که کپي کردم. (البته بهشون ايميل زدم و ازشون اجازه گرفتم) همچنين بگم چون مطالب ايشون کمي از لحاظ برنامه هاي استفاده شده فرق داره منم خودم کمي مطالبش رو تغيير دادم تا با مطالب و کارهاي ما جور در بيايد.

خب تا اينجاي كار ما يك بوت لودر ساده نوشتيم و همچنين نحوه استفاده از برنامه هاي گفته شده رو هم آموزش داديم. حالا قصد داريم تو اين پست همون برنامه رو يك كمي ( البته خيلي كم ) توسعه بديم تا يك پيام رو توي صفحه نمايش بده. (همينشم خيلي باحاله ها ... kiss) همونطور كه ميدونيد وقتي كامپيوتر رو روشن ميكنيم اول تو مود واقعي يا مود 16 بيتي بالا مياد پس ما ميتونيم از تمام وقفه هاي بابوس استفاده كنيم. ( تو مود 32 بيتي وضعيت كمي فرق داره ). پس براي نمايش متن مورد نظر ميتونيم از وقفه هاي مربوط به صفحه نمايش استفاده كنيم. اما قبل از وارد شدن به اين مبحث ميخوام به مقدمه كوچك براي تكميل پست قبلي بنويسم.

اگه پست قبلي رو با من جلو اومده باشيد حتماً متوجه شديد با اينكه فلاپی مجازی سالمه و قابليت راه اندازي و بوت هم داره وقتي روش دابل كليك ميكنيد و ميخواهيد واردش بشيد با پيام Not Formatted مواجه ميشيد. و شما مجبور به فرمت كردن اون هستيد تا بتونيد يه فايل ديگه ( مثلاً همون كرنل يا هسته سيستم عامل ) توش كپي كنيد. در واقع فلاپی شما سالمه اما سيستم فايل مشخصي نداره و ويندوز نميتونه باهاش ارتباط برقرار كنه براي اينكه بتونيم يه سيستم فايل معتبر براي فلاپي تعريف كنيم بايد از پارامترهاي بلاك OEM استفاده كنيم. توضيح كامل در مورد اين بلاك رو تو پست هاي بعدي براتون مينويسم اما فعلاً براي اين كه از مشكلي كه گفتم راحت بشيم بايد يك سري كد به فايل بوت لودري كه نوشتيم اضافه كنيم كه توضيحاتش بمونه براي پست هاي بعدي چونكه هدف ما تو اين پست چيز ديگه اي هست و البته اگر اين كدها رو اضافه نكنيد بازهم مثال اين بخش رو ميتونيد انجام بديد ولي توصيه ميكنم از همين حالا اين كدها رو به برنامه اضافه كنيد. در واقع كد نهايي بعد از اضافه كردن اين كدها به اين شكل ميشه :

bits 16
org 0x7c00
start: jmp loader

;*************************************************;
; OEM Parameter block
;*************************************************;
TIMES 0Bh-$+start DB 0
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 1
bpbNumberOfFATs: DB 2
bpbRootEntries: DW 224
bpbTotalSectors: DW 2880
bpbMedia: DB 0xF0
bpbSectorsPerFAT: DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber: DB 0
bsUnused: DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "FAT12 "
;*************************************************;
; Bootloader Entry Point
;*************************************************;

loader:
cli
hlt
times 510 - ($-$$) db 0
dw 0xAA55


براي نمايش متني بر رو صفحه نمايش بايد از وقفه 0x10 استفاده كنيم. تابع شماره 0x0E از اين وقفه اين كار را براي ما انجام ميده. اين تابع در هر بار فراخواني ميتواند يك كاراكتر را بر روي صفحه نمايش چاپ كند. براي اين كار ثبات هاي پردازنده به اين صورت تنظيم ميشوند.

AH : اين ثبات با مقدار 0x0E تنظيم ميشود
AL : كاراكتر مورد نظر در اين ثبات قرار ميگيرد
BH : شماره صفحه كه معمولاً 0 است
BL : رنگ كاراكتر است كه فقط در مود گرافيكي استفاده ميشود

به عنوان مثال تكه كد زير كاراكتر 'A' را در صفحه نمايش چاپ ميكند.

xor bx, bx
mov ah, 0x0e
mov al, 'A'
int 0x10


توجه كنيد كه خط اول از اين كد براي 0 كردن مقدار bx نوشته شده، اين روش از دستور mov bx,0 سريع تر اجرا ميشه. براي اينكه بتونيم يك رشته توي خروجي چاپ كنيم بايد از يك حلقه به صورت يك زير برنامه استفاده مي كنيم. در اين برنامه مقدار 0 نشان دهنده پايان رشته است. بوت لودري كه در زير ميبينيد كار چاپ رشته رو برامون انجام ميده. حتماً كد مورد نظر رو خودتون تايپ كنيد تا بهتر ياد بگيريد. ( البته بخش OEM رو ميتونيد كپي كنيد innocent).

bits 16
org 0x7c00
start: jmp loader

;*************************************************;
; OEM Parameter block
;*************************************************;
TIMES 0Bh-$+start DB 0
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 1
bpbNumberOfFATs: DB 2
bpbRootEntries: DW 224
bpbTotalSectors: DW 2880
bpbMedia: DB 0xF0
bpbSectorsPerFAT: DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber: DB 0
bsUnused: DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "FAT12 "
;*************************************************;
; Bootloader Entry Point
;*************************************************;

msg db "Welcome to My Operating System!", 0

Print:
lodsb
or al, al
jz PrintDone
mov ah, 0eh
int 10h
jmp Print
PrintDone:
ret

loader:
xor ax, ax
mov ds, ax
mov es, ax
mov si, msg
call Print

cli
hlt
times 510 - ($-$$) db 0
dw 0xAA55


در مورد اين كد شايد فقط دستور lodsb كمي مبهم باشه كه بايد بگم اين دستور محتويات آدرسي از حافظه رو كه ثبات si بهش اشاره ميكنه رو توي al قرار ميده و دستور بعدي هم در صورتي كه مقدار اين خانه 0 باشه پايان رشته را تشخيص ميده و به آخر زيربرنامه پرش ميكنه. دقت كنيد كه بخش OEM قابليت اجرايي نداره و برنامه بلافاصله پس از اجرا از روي آن پريده و به بخش loader ميرود و اين بخش براي مقاصدي كه گفتم بايد اضافه بشه. خب مثل پست قبلي برنامه این برنامه رو هم اسمبل کنید و روی فلاپی بریزید و در نهایت با Qemu اجراش کنید. باید شکل زیر رو ببینید (برای بزرگ نمایی روی تصویر کلیک کنید)

 

اگه شبيه ساز پيغام رو نشون داد يعني اين كه شما تونستيد يه بوت لودر بنويسيد كه سرش به تنش مي ارزه. تو پست هاي بعدي بازم درباره تكميل بوت لودر مطالبي رو بهتون آموزش ميدم.

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

همطونور که اول آموزش گفتم این آموزش از آقای عباس مقدم بود که توی وبلاگشون گذاشته بودن و من هم با اجازه از ایشون توی پستم استفاده کردم!

انشالله در جلسات آینده بیشتر این سیستم عامل رو توسعه میدیم!

اگه قصد کمک و همکاری داشتید در خدمتتونم!

فعلا tongue-out

یا علی مدد...!

 

  قسمت قبل : جلسه چهارم                                                         قسمت بعد : جلسه ششم