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

سلام دوستان و هموطنان عزیز، این هفتمین جلسه از آموزش سیستم عامل هست که در خدمتتون هستیم! پس با ما همراه باشید ...

خوب همونطور که جلسات قبل گفتم، ما اومدیم و گفتیم که آقای عباس مقدم یه چند جلسه از آموزش ساخت بوت لودر رو دادن و من هم از ایشون اجازه گرفتم که اونا رو توی سایت قرار بدم که دیگه لازم نباشه دوباره بنویسیم و ما خودمون رو برای بعد از بوت لودر و توسعه کرنل اماده کنیم foot-in-mouth بنابراین این جلسه هم آخرین مرحله از توسعه بوت لودر و ورود به کرنل هست که باز هم ( البته برای آخرین بار ) با آقای عباس مقدم همراه خواهیم شد!

پس شروع میکنیم!

توي اين پست ميخواهيم نحوه خوندن و اجرا كردن يك فايل از روي فلاپي توسط برنامه بوت لودر رو با استفاده از پارامترهاي بلاك OEM آموزش بديم. در اين جا ما يك بوت لودر دو مرحله اي ميسازيم كه مرحله دوم به صورت يك فايل جداگانه كه هر حجمي ميتونه داشته باشه روي فلاپي كپي ميشه. دقت كنيد كه نيازي به استفاده از BOOTICE توي اين مرحله وجود نداره و ميتونيم توسط دستور copy از طريق محيط ويندوز اين كار رو انجام بديم ( یعنی معمولی فایلمون رو کپی کنیم بریزیم توی فلاپی)

 

نكاتي در مورد سيستم هاي فايل

1- سيستم فايل چيزي به جز يك سري تعاريف نيست كه به ما كمك مي كنه تا مفهوم فايل رو با استفاده از دستورات سطح پايين و وقفه ها پياده سازي كنيم.

2- يك فايل چيزي جز يك سري اطلاعات به صورت مجموعه اي از بيت ها نيست. اين اطلاعات ميتونه شامل هرچيزي باشه ( مثلاً فايل متني يا صوتي ). اين ما هستيم كه تعيين ميكنيم اين بيت ها به چه صورت تفسير بشه. ما حتي ميتونيم يك فايل متني يا صوتي رو به صورت يك فايل اجرايي ، اجرا كنيم ولي نتيجه انجام اين كار قابل پيش بيني نخواهد بود.

3- ميدانيم كه هر سكتور برابر با 512 بايت است و فايل ها روي اين سكتور ها ذخيره ميشوند. اما حجم فايل ها هميشه برابر با 512 بايت يا مضرب صحيحي از اين عدد نيست. بنابراين بايد مابقي بايت هاي سكتوري كه به عنوان آخرين سكتور از يك فايل است را با اطلاعات خاصي علامت گذاري كنيم.

4- ممكن است تمام سكتور هاي حاوي اطلاعات يك فايل خاص پشت سر هم قرار نگرفته باشند. به اينگونه فايل ها، فايل هاي تكه تكه يا گسسته گفته ميشود. درنتيجه براي خواندن اينگونه فايل ها بايد تمام سكتورها را جداگانه خواند و در كنار هم قرار داد.

5- برخي از سيستم هاي فايل معروف عبارتند از FAT12 , FAT16 , FAT32 , NTFS , ext2 , ext3 و ... . اما برخي شركت ها ممكن است از سيستم فايل مربوط به خود استفاده كنند كه معمولاً كارايي اين نوع سيستم فايل پايينتر از سيستم فايل هاي استاندار است. مگر موارد خاصي مانند سيستم فايل اختصاصي گوگل GFS كه كارايي بسيار بالايي داره.

 

نكاتي در مورد سيستم فايل FAT12

سيستم فايل FAT12 قديمي ترين سيستم فايل استاندارد جهان ميباشد كه در سال 1977 توسط مايكروسافت معرفي شد و هنوز هم به عنوان يك سيستم فايل استاندارد مورد استفاده قرار ميگيرد. برخي از خصوصيات اين سيستم فايل عبارتند از :

1- اين سيستم از سلسله مراتب داركتوري پشتيباني نميكند. اين به اين معني است كه فقط يك داركتوري ريشه در اين نوع سيستم فايل وجود دارد.

2- آدرس دهي كلاسترها به صورت 12 بيتي صورت ميگيرد. اين به اين معني است كه حداكثر تعداد كلاسترها 4096 است ( یعنی 212 )

3- به دليل محدوديت فوق و با توجه با سكتورهاي رزرو شده، حداكثر تعدار فايل در اين سيستم 4077 فايل ميباشد.

اين ها محدوديت هاي بزرگي هستند.  در سيستم FAT16 امكان ذخيره بيش از 64000 فايل وجود دارد و ايجاد دايركتوري نيز پشتيباني ميشود. باين حال فعلاً جهت سادگي كار از FAT12 استفاده خواهيم كرد. هزچند ساختار كلي FAT12 و FAT16 بسيار شبيه به هم هست. ولي FAT32 ساختار كاملاً متفاوتي داره. در آينده از FAT16 وFAT32 براي توسعه سيستم عامل استفاده خواهيم كرد.

 

نحوه ذخيره اطلاعات در FAT12

 

سكتورهاي ذخيره سازي فايل ها

دايركتوري ريشه

جدول FAT دوم

جدول FAT اول

سكتورهاي رزرو شده

بوت سكتور 

 

اين جدول نشاندهنده ساختار كلي يك ديسك فرمت شده با سيستم فايل FAT12 هستش. همونطور كه ميبينيد سكتور راه انداز در اولين محل قرار گرفته. درك صحيح اين جدول جهت لود كردن فايل هاي روي ديسك بسيار مفيد خواهد بود. دقت كنيد كه دو جدول FAT وجود دارد كه بعد از سكتور هاي رزرو شده قرار گرفته اند. ( اگر سكتور رزرو شده اي وجود نداشته باشد بعد از سكتور راه انداز قرار ميگيرند ). اين دو جدول معمولاً يكسان هستند و از دومي براي انجام اعمال بازيابي از ديسك در صورت از دست رفتن ناخواسته اطلاعات استفاده ميشود. همچنين دونستن اين نكهته مهمه كه داركتوري ريشه هميشه بعد از اين دو جدول قرار ميگيره. با اين تفاسير ما با دونستن تعداد سكتورها در هرFAT و تعداد سكتورهاي رزرو شده و جمع كردن اونها با سكتور راه انداز ميتونيم اولين سكتور مربوط به دايركتوري ريشه رو به دست بياريم كه ميدونيم مقدار اين پارامترها در بلاك OEM تعريف شده. با جستجو در دايركتوري ريشه هم ميتونيم محل قرار گيري هر فايل روي ديسك رو پيدا كنيم.

جدول FAT در واقع آرايه اي از مقادير 12 بيتي را در خود ذخيره كرده كه هر انديس از اين آرايه معرف وضعيت كلاستر معادل اين انديس است. يعني مثلاً مقدار پنجم از اين جدول مشخص كننده پنجمين كلاستر بوده و با توجه به مقدار اين عدد 12 بيتي مشخص ميشود كه وضيعيت كلاستر مذكور چيست؟ اين وضعيت ميتونه يكي از حالات زير باشه:

0x00 : اين مقدار به معني آزاد بودن كلاستر است.
0x01 : اين مقدار نشان ميدهد كه اين كلاستر جزو سكتورهاي رزروشده هست.
0x002 تا 0xFEF :‌ نشان ميدهد كه اين كلاستر درحال استفاده توسط يك فايل ميباشد.
0xFF0 تا 0xFF6 : اين مقادير توسط سيستم رزرو شده.
0xFF7 : اين مقدار نشاندهنده يك كلاستر خراب و غير قبل استفاده است.
0xFF8 تا 0xFFF : اين مقادير نشاندهنده كلاستر پاياني يك فايل هستند.

در واقع جدول FAT آرايه اي از اين مقادير است. پس اگه اولين كلاستر يك فايل مثلاً X باشد با خوندن X امين مقدار از اين جدول ميتونيم اطلاعات خوبي راجع به فايل به دست بياريم. اگه اين مقدار بين 0xFF8 تا 0xFFF باشه يعني اين فايل فقط يك كلاستر داره و خوندن همين كلاستر به معني خوندن كل فايل هست و اگه عددي بين 0x002 تا0xFEFمثل Y باشه نشون ميده كه كلاستر شماره Y هم كلاستر بعدي فايل رو تشكيل ميده و ... . همچنين يادتون باشه كه توي بلاك OEM ما تعداد سكتور هاي يك كلاستر رو 1 تعريف كرديم. پس در اينجا مفهوم سكتور و كلاستر تقريباً يكسان است. پس حالا تنها مسئله باقي مونده اينه كه چطور اولين كلاستر يا سكتور يك فايل رو پيدا كنيم. در ادامه اين موضوع رو توضيح ميدم.

 

جدول دايركتوري ريشه

همونطور كه مشاهده كرديد جدول FAT مجموعه اي از مقادير 12 بيتي بود. جدول داركتوري ريشه هم ساختاري مشابه دارد با اين تفاوت كه اين جدول به صورت آرايه اي از مقادير 32 بايتي تشكيل ميشه و هر عضو 32 بايتي مشخصات يك فايل رو نگهداري ميكنه و هر بايت از اين 32 بايت معني بخصوصي داره. كاربرد هر بايت به صورته :

0 تا 7 : اين 8 بايت حاوي نام فايل هستند ( در صورتي كه نام فايل ها كمتر 8 كاراكتر باشه بايد بايت ها پاياني با space پر بشه )
8 تا 10 : اين 3 بايت براي ذخيره پسوند فايل استفاده ميشه ( در صورتي پسوند كمتر از 3 كاراكتر باشه بايد از space استفاده كنيم )

11 : براي ذخيره صفات فايل استفاده ميشه و هر بيت معني خاصي داره :

  • 0 : فقط خواندني

  • 1 : مخفي

  • 2 : سيستمي

  • 3 : برچسب

  • 4 : ساب دايركتوري

  • 5 : آرشيو

  • 6 : كاربرد سيستمي

  • 7 : بدون كاربرد

12 : بدون كاربرد
13 : زمان ساخت برحسي 10 ميلي ثانيه ( بين 0 تا 199 )
14 و 15 : يك عدد 16 بيتي براي نگهداري زمان ساخت فايل با فرمت زير :

  • 0 تا 4 : ثانيه تقسيم بر دو ( بين 0 تا 29 ). براي يافتن تانيه دقيق بايد از يايت 13 كمك بگيريم

  • 5 تا 10 : دقيقه ( بين 0 تا 59 )

  • 11 تا 15 : ساعت ( بين 0 تا 23 )

16 و 17 : يك عدد 16 بيتي ديگر براي نگهداري زمان ساخت فايل با فرمت زير :

  • 0 تا 4 : روز ( بين 1 تا 31 )

  • 5 تا 8 : ماه ( بين 1 تا 12 )

  • 9 تا 15 : سال ( 0 = 1980 و 127 = 2107 )

18 و 19 : آخرين تاريخ دسترسي به فايل با فرمت بالا
20 و 21 : EA index هستش و در سيستم هاي OS/2 و NT كاربرد داره و به كار ما نمياد.
22 و 23 : زمان آخرين اصلاحات روي فايل ( با فرمت 14 و 15 )
24 و 25 : ترايخ آخرين اصلاحات روي فايل ( با فرمت 16 و 17 )
26 و 27 : شماره اولين كلاستر فايل
28 تا 32 : اندازه فايل

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

توجه به اين نكته خيلي مهمه كه تعداد كاراكتر هاي تشكيل دهنده نام فايل و پسوند فايل حتماً بايد برابر با 8 و 3 باشه و در صورتي كه اسم و پسوند مورد نظر ما طولي كمتر از اين مقادير داسته باشه بايد با فاصله جاهاي خالي رو پر كنيم. همچنين 3 بايت مربوط به پسوند ميتونه كلاً با فضاي خالي پر بشه ولي اسم فايل بايد حتماً يك كاراكتر داشته باشه. بنابراين اگه فايل مرحله دوم بوت لودر اسمش مثلاً Stage2.SYS باشه ما بايد توي بوت لودر دنبال فايلي به اسم "Stage2  SYS" بگرديم. در اين مورد به "Stage2.SYS" اسم خارجي فايل و "Stage2  SYS" اسم داخلي فايل گفته ميشه.

 

جستجوي فايل و خواندن فايل در FAT12

خب فكر كنم ديگه بحث خيلي طولاني شده و شما كم كم داريد از كلمه FAT12 متنفر ميشد. پس ديگه بايد وارد مرحله بعدي بشيم.

توي پست قبلي در مورد بلاك OEM يا همون بلاك بارامترهاي باياس bpb كمي با هم صحبت كرديم. حالا با استفاده از اين پارامترها و مطالبي كه تا حالا تو اين پست مطرح شد مي خواهيم خوندن فايل از روي ديسك رو شروع كنيم براي سادگي رجوع به bpb ها يه بار ديگه اينجا ذكرشون ميكنيم.

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 "

در ابتدا بايد يه اسم مناسب براي فايل مورد نظر پيدا كنيم. از اونجايي كه هدف از خوندن اين فايل ، لود كردن كرنل يا همون هسته سيستم عامل و همچنين آماده سازي سيستم براي ورود به مود 32 بيتي هستش من اسم اين فايل رو KRNLDR.SYS انتخاب ميكنيم. يادتون باشه كه طول اين اسم حتماً 11 كاراكتر باشه پس توي برنامه از شكل داخلي اون يعني KRNLDR  SYS استفاده ميكنيم. همچنين اسم فايل منبع اين برنامه رو KRNLDR.ASM انتخاب مي كنيم.

خب، برنامه اي كه قراره ما به عنوان مرحله دوم بوت لودر بنوسيم فعلاً خيلي ساده هست. فعلاً هدف ما آموزش چگونگي لود كردن يك فايل از ديسك و اجرا كردن اونه. اين برنامه تنها كاري كه انجام ميده نمايش دادن يك پيغام ساده روي مانيتور و بعد متوفق كردن سيستم با فرمان hlt هستش. بعد ها با توضيحاتي كه در مورد مود 32 بيتي دادم ياد ميگيريد كه چطور از اين فايل براي آماده سازي سيستم براي ورود به مود 32 بيتي استفاده كنيد و همين برنامه رو تا حدي توسعه ميديم و بعدشم كه نوبت به مهمترين بخش طراحي سيستم عامل، يعني نوشتن كرنل توي مود 32 بيتي ميرسه. سورس برنامه KRNLDR.ASM رو اين زير ميتونيد ببينيد.

org    0x0
bits    16
jmp    main

;*************************************************;
; Prints a string
; DS=>SI: 0 terminated string
;************************************************;

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

;*************************************************;
; Second Stage Loader Entry Point
;************************************************;

main:
    cli
    push    cs
    pop    ds

    mov    si, Msg
    call    Print

    cli
    hlt

;*************************************************;
; Data Section
;************************************************;

Msg    db    "Preparing to load operating system...",13,10,0

حالا ميتونيد با فرمان هاي زير برنامه رو ترجمه و روي فلاپي كپي كنيد. دقت كنيد كه نيازي به استفاده از BOOTICE نيست و حتي از طريق Explorer ويندوز يا Send to هم ميتونيد اين كار رو انجام بديد.(یعنی معمولی کپی کنید! مثل وقتی که یه آهنگ رو تو فلشتون کپی مکیند که تو ماشین گوش بدید) در مورد كرنل هم كه بعد ها مينويسيم وضع به همين ترتيب خواهد بود.

nasm -f bin KRNLDR.ASM -o KRNLDR.SYS

 

لود كردن جدول دايركتوري ريشه

حالا وقت لود كردن KRNLDR.SYS از بوت لودر فرا رسيده. اولين چيزي كه ما به اون احتياج داريم دونستن اندازه دايركتوري ريشه است. براي به دست آوردن اين مقدار كافيست تعداد كل سلول هاي ( Entry ) دايركتوري ريشه ( 224 ) را در سايز هر سلول ( 32 ) ضرب كنيم. تكه كد زير ضمن انجام اين كار تعداد سكتورهاي مصرف شده توسط دايركتوري ريشه را نيز محاسبه ميكند.

mov    ax, 0x0020
mul    WORD [bpbRootEntries]
div    WORD [bpbBytesPerSector]

 

چيزي كه حالا به اون احتياج داريم دونستن محل سكتوري هستش كه دايركتوري ريشه از اونجا شروع ميشه. براي به دست آوردن اين مقدار هم كافيه تعداد سكتورها در هرFAT رو در 2 ضرب كرده و با تعداد سكتورهاي رزرو شده جمع كنيم. براي درك بهتر اين موضوع ميتونيد به جدول بالا دوباره نگاهي بندازيد. تكه كد زير اين كار رو براي ما انجام ميده.

mov    al, BYTE [bpbNumberOfFATs]
mul    WORD [bpbSectorsPerFAT]
add    ax, WORD [bpbReservedSectors]

تو اين كد هم مثل كد بالا نتيجه توي ثبات ax ذخيره ميشه. روتين كامل لود كننده دايركتوري ريشه ميتونه به اين صورت نوشته بشه.

 

LOAD_ROOT:

    xor    cx, cx
    xor    dx, dx
    mov    ax, 0x0020
    mul    WORD [bpbRootEntries]
    div    WORD [bpbBytesPerSector]
    xchg ax, cx

    mov    al, BYTE [bpbNumberOfFATs] ; number of FATs
    mul    WORD [bpbSectorsPerFAT] ; sectors used by FATs
    add    ax, WORD [bpbReservedSectors] ; adjust for bootsector
    mov    WORD [datasector], ax ; base of root directory
    add    WORD [datasector], cx

    mov bx, 0x0200
    call ReadSectors

اين روتين بعد از محاسبه سايز و محل قرارگيري دايركتوري ريشه و قرار دادن اونا به ترتيب در cx و ax با فراخواني روتينReadSectors دايركتوري ريشه رو به مكان 0x0200 يعني درست بعد از محل قرارگيري بوت لودر در حافظه لود ميكنه.

 

پيدا كردن فايل KRNLDR.SYS

ميدانيم كه مشخصات هر فايل در دايركتوري ريشه به صورت يك مقدار 32 بايتي ذخيره ميشه. همچنين 11 بايت اول از اين 32 بايت اسم هر فايل رو ذخيره ميكنه. پس براي پيدا كردن فايل KRNLDR.SYS كه ميدونيم شكل داخلي اون KRNLDR  SYS هستش بايد مقدار 11 بايت اول هر سلول رو با اين نام مقايسه كنيم و در صورت عدم برابري 11 بايت اول از 32 بايت بعدي را مقايسه كنيم تا زماني كه مورد برابر را پيدا كنيم ( حداكثر 224 بار ). تكه كد زير اين كار رو انجام ميده.

 

    mov    cx, WORD [bpbRootEntries]
    mov di, 0x0200

.LOOP:

    push    cx
    mov     cx, 0x000B
    mov    si, ImageName
    push    di

rep    cmpsb

    pop    di
    je    LOAD_FAT
    pop     cx
    add    di, 0x0020
    loop .LOOP
    jmp FAILURE

در اينجا منظور از ImageName همان اسم داخلي فايل مورد نظر يا KRNLDR هست. در صورتي كه فايل مورد نظر بعد از 224 با جستجو يافت نشود برنامه به سابروتينFAILURE پرش ميكند.

 

لود كردن جدول FAT

همونطور كه گفتيم بايت هاي 26 و 27 از هر سلول دايركتوري ريشه حاوي شماره اولين كلاستر فايل هستند پس با داشتن اين مقدار ميتونيم محل قرارگيري فايل بر روي ديسك رو پيدا كنيم. البته توي مثال ما فقط بايت 26 براي اين كار كفايت ميكنه ( دليلش رو خودتون پيدا كنيد kiss). منتها قبل از اينكه بتونيم فايل رو لود كنيم بايد خود جدول FAT رو لود كنيم تا از اين طريق بتونيم تمام كلاسترهاي مربوط به فايل مورد نظر رو پيدا كنيم. بادتون باشه كه تمام كلاسترهاي يك فايل ممكن روي ديسك پشت سر هم قرار نگرفته باشند. به تكه برنامه زير نگاه كنيد :

LOAD_FAT:

    mov    si, msgCRLF
    call    Print
    mov    dx, WORD [di + 0x001A]
    mov WORD [cluster], dx

    xor    ax, ax
    mov    al, BYTE [bpbNumberOfFATs]
    mul    WORD [bpbSectorsPerFAT]
    mov    cx, ax

    mov    ax, WORD [bpbReservedSectors]

    mov    bx, 0x0200
    call ReadSectors

قبل از هرچيز اين رو بگم كه تو اين پست و پست هاي بعدي هرجا توي كدها شناسه اي رو ديديد كه بدون اينكه تعريف شده باشه ازش استفاده شده. نگران نباشيد تو آخر پست هاي اينجوري فايل كامل برنامه براي دانلود گذاشته شده كه ميتونيد دانلود كنيد و ببينيد كه هركدام از شناسه ها كجا و به چه منظور تعريف شدند. همچنين اين فايل ها به غير از سورس اصلي برنامه شامل توضيحات راهنما هم هستند كه كمك زيادي به درك عملكرد برنامه مي كنند. در مورد كد بالا بايد بگم كه در اينجا در ابتدا اولين كلاستر از فايل مشخص و ذخيره ميشه و بعد جدول FAT با استفاده ازسابروتين ReadSectors لود ميشه. اين كد هم سكتور هاي خونده شده مربط به FAT رو توي آدرس 0x0200 قرار ميده چونكه ديگه نيازي به اطلاعات قبلي اين آدرس وجود نداره.

 

LBA و CHS

همونطور كه تو پست قبلي اشاره كرديم براي خوندن يك سكتور از ديسك به پارامترهايي مثل شماره هد، شماره سيلندر و شماره سكتور احتياج داريم كه به اين نوع آدرس دهي CHS يا ( Cylinder / Head / Sector ) گفته ميشه. اما مشكلي كه اينجا بهش برميخوريم ( ناراحت نشيد اين آخرين مشكلمونه ) اينه كه آدرس كلاستر ها در جدولFATبه صورت يك آرايه از مقادير متوالي تشكيل ميشه و هر كلاستر فقط با يك شماره 12 بيتي مشخص ميشه. به اين نوع آدرس دهي LBA يا ( Logical Block Addresing ) گفته ميشه. براي به دست آوردن شماره هد، سكتور و شيار از روي آدرس LBA ميتوان از سه رابطه زير استفاده كرد.

absolute sector = (logical sector / sectors per track) + 1
absolute head = (logical sector / sectors per track) MOD number of heads
absolute track = logical sector / (sectors per track * number of heads)

و براي به دست آوردن LBA از روي CHS از رابطه زير استفاده ميكنيم.

LBA = (cluster - 2 ) * sectors per cluster

اگه ناراحت نميشيد بايد بگم يه مشكله ديگه هنوز حل نشده و اون اينه كه وقتي ما هر سلول از جدول FAT رو ميخونيم اون رو بايد توي يك داده از نوع WORD ذخيره كنيم ولي اين داده فقط از 12 بيت تشكيل شده و در واقع 4 بيت اضافي مربوط به سلول بعدي هستند. براي اينكه بتونيم آدرس كلاستر رو از جدول FAT به درستي بخونيم بايد 12 بيت مفيد رو پيدا كنيم. به بياني ديگر هر كلاستر زوج 4 بيت از كلاستر بعدي و هر كلاستر فرد 4 بيت از كلاستر قبلي رو هم شامل ميشه. پس براي رفع اين مشكل از راه حل زير استفاده ميكنيم.

كلاسترهاي زوج رو با بيت ماسك 0000111111111111 بايد And ميكنيم و كلاسترهاي فرد رو 4 بيت به راست شيفت ميديم.

 كدهاي كامل مربوط به اين تبديلات و تبديلات LBA و CHS رو تو فايل zip ضميمه شده ميتونيد بعد از دانلود مشاهده كنيد. اين فايل رو ميتونيد از اينجا دانلود كنيد.

خب اگه تا حالا تمام مطالب مطرح شده رو مطالعه كرده باشيد حتماً متوجه شديد كه مطالب اين پست نسبت به پست هاي قبلي كمي پيچيده تر بوده. اگه اين طور نيست بايد بگم كه شما در سطح خوبي از برنامه نويسي با اسمبلي هستيد و از اين به بعد هم به مشكلي نخواهيد خورد. چونكه سطح برنامه هاي اين پست تقريباً جزو سخت ترين برنامه هايي هست كه ما تا حداقل 10 پست بعدي براتون آموزش ميديم ولي اگه مطالب براي شما سخت و نامفهوم بوده ناراحت نشيد چونكه با كمي مطالعه ميتونيد خودتون رو براي پست هاي بعدي آماده كنيد.

از اين جا به بعد كار ما توسعه دادن فايل KRNLDR.SYS براي آماده سازي جهت ورود به مود 32 بيتي و بعد از اون مرحله اصلي يعني نوشتن كرنل با زبان C هستش. براي اين كه بتونيد اين كارها رو انجام بديد بايد آشنايي خوبي با تفاوت هاي موجود بين مود 16 بيتي ( مود واقعي ) و مود 32 بيتي ( مود حفاظت شده )  داشته باشيد. پس پست بعدي به تشريح اين تفاوت ها اختصاص داره. تا پست بعدي مطالعاتتون رو بيشتر كنيد.

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

این آموزش هم از آقای عباس مقدم بود که خدا خیرشون بده خیلی خوب عالی توضیح داده بودن! foot-in-mouth اما صد حیف که دیگه ادامه ندادن embarassed و این پست آخر پست ایشون توی وبلاگشون بود.

امیدوارم بتونیم این راه پر پیچ و خم surprised رو ادامه بدیم.

فعلا 

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

 

قسمت قبل : جلسه ششم