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

سلام عرض میکنم خدمت شما دوستان عزیز و هموطنان گرامی! امیدوارم حالتون خوب باشه!

بعد از چند وقتی دوباره تصمیم گرفتم قسمت بعدی آموزش ساخت سیستم عامل رو براتون آماده کنم! امیدوارم به دردتون بخوره و ما رو دعا کنید!

خوب در جلسه قبل جدول توصیفگر سراسری یا GDT رو خدمتتون تدریس کردیم! و نگاهی به قالب اون انداختیم. یک مثال زدیم و اون مثال رو تجزیه و تحلیل کردیم. گفتیم جدول توصیفگر سراسری شامل سه واصف (توصیفگر) هست. واصف NULL یا پوچ، واصف کد و واصف دیتا. همچنین گفتیم علاوه بر جدول توصیفگر سراسری GDT یه چیز دیگه هم به نام جدول توصیفگر وقفه یا IDT داریم که در مود 32 بیتی برای وقفه ها و استثنا ها استفاده میشه! و در نهایت در جلسه قبل وارد مود 32 بیتی شدیم!

در این قسمت میخوایم خط A20 رو فعال کنیم!

خط A20 یک گیت (دروازه) فیزیکی هست که به یکی از پایه های یکی از سخت افزار ها وصل هست (میتونید سرچ کنید یا از توی همین سایت منبع از روش بخونید) که وقتی ما اونو فعال کنیم باعث میشه که دیگه آدرس دهی ما به 20 خط یا همون 1 مگابایت محدود نباشه و آدرس دهی ما 32 بیتی بشه! بنابراین ما برای دسترسی به چهار گیگ فضا نیاز به فعال کردن A20 داریم! و قصد داریم در این جلسه این کار رو انجام بدیم!

ببینید ما یه موضوعی داریم به نام برنامه نویسی مستقیم سخت افزار که یه چیز تقریبا مهمی هست. من این سایت منبع رو پیشنهاد میکنم یه نگاهی بندازید! (کلیک کنید)

ما حالا نیاز داریم با سخت افزار به طور مستقیم ارتباط برقرار کنیم و از طریق دو دستور خاص IN و OUT اینکار رو انجام میدیم!

راستش یه میکروکنترلری وجود داره به نام Intel 8042 که به کیبورد ما وصل هست و کیبورد رو کنترل میکنه یعنی مثلا کلیدی رو که زدیم رو سیگنالش رو میگیره و به CPU میگه چه کلیدی زده شده! اون خط A20 ما با این میکروکنترلر در ارتباط هست. یعنی ما برای اینکه خط A20 رو فعال کنیم باید با 8042 ارتباط برقرار کنیم!

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

 

Default x86 Port Address Assignments
Address Range First QWORD Second QWORD Third QWORD Fourth QWORD
0x000-0x00F DMA Controller Channels 0-3
0x010-0x01F System Use
0x020-0x02F Interrupt Controller 1 System Use
0x030-0x03F System Use
0x040-0x04F System Timers System Use
0x050-0x05F System Use
0x060-0x06F Keyboard/PS2 Moude (Port 0x60)
Speaker (0x61)
Keyboard/PS2 Mouse (0x64) System Use
0x070-0x07F RTC/CMOS/NMI (0x70, 0x71) DMA Controller Channels 0-3
0x080-0x08F DMA Page Register 0-2 (0x81 - 0x83) DMA Page Register 3 (0x87) DMA Page Register 4-6 (0x89-0x8B) DMA Page Register 7 (0x8F)
0x090-0x09F System Use
0x0A0-0x0AF Interrupt Controller 2 (0xA0-0xA1) System Use
0x0B0-0x0BF System Use
0x0C0-0x0CF DMA Controller Channels 4-7 (0x0C0-0x0DF), bytes 1-16
0x0D0-0x0DF DMA Controller Channels 4-7 (0x0C0-0x0DF), bytes 16-32
0x0E0-0x0EF System Use
0x0F0-0x0FF Floating Point Unit (FPU/NPU/Mah Copprocessor)
0x100-0x10F System Use
0x110-0x11F System Use
0x120-0x12F System Use
0x130-0x13F SCSI Host Adapter (0x130-0x14F), bytes 1-16
0x140-0x14F SCSI Host Adapter (0x130-0x14F), bytes 17-32 SCSI Host Adapter (0x140-0x15F), bytes 1-16
0x150-0x15F SCSI Host Adapter (0x140-0x15F), bytes 17-32
0x160-0x16F System Use Quaternary IDE Controller, master slave
0x170-0x17F Secondary IDE Controller, Master drive System Use
0x180-0x18F System Use
0x190-0x19F System Use
0x1A0-0x1AF System Use
0x1B0-0x1BF System Use
0x1C0-0x1CF System Use
0x1D0-0x1DF System Use
0x1E0-0x1EF System Use Tertiary IDE Controller, master slave
0x1F0-0x1FF Primary IDE Controller, master slave System Use
0x200-0x20F Joystick Port System Use
0x210-0x21F System Use
0x220-0x22F
Sound Card
Non-NE2000 Network Card System Use
0x230-0x23F SCSI Host Adapter (0x220-0x23F), bytes 17-32)
0x240-0x24F  
Sound Card
Non-NE2000 Network Card System Use
NE2000 Network Card (0x240-0x25F) Bytes 1-16
0x250-0x25F NE2000 Network Card (0x240-0x25F) Bytes 17-32
0x260-0x26F  
Sound Card
Non-NE2000 Network Card System Use
NE2000 Network Card (0x240-0x27F) Bytes 1-16
0x270-0x27F  
System Use Plug and Play System Devices LPT2 - Second Parallel Port
System Use LPT3 - Third Parallel Port (Monochrome Systems)
NE2000 Network Card (0x260-0x27F) Bytes 17-32
0x280-0x28F  
Sound Card
Non NE2000 Network Card System Use
NE2000 Network Card (0x280-0x29F) Bytes 1-16
0x290-0x29F NE2000 Network Card (0x280-0x29F) Bytes 17-32
0x2A0-0x2AF  
Non NE2000 Network Card System Use
NE2000 Network Card (0x280-0x29F) Bytes 1-16
0x2B0-0x2BF NE2000 Network Card (0x280-0x29F) Bytes 17-32
0x2C0-0x2CF System Use
0x2D0-0x2DF System Use
0x2E0-0x2EF System Use COM4 - Fourth Serial Port
0x2F0-0x2FF System Use COM2 - Second Serial Port
0x300-0x30F  
Sound Card / MIDI Port System Use
Non NE2000 Network Card System Use
NE2000 Network Card (0x300-0x31F) Bytes 1-16
0x310-0x31F NE2000 Network Card (0x300-0x32F) Bytes 17-32
0x320-0x32F  
Sound Card / MIDI Port (0x330, 0x331) System Use
NE2000 Network Card (0x300-0x31F) Bytes 17-32
SCSI Host Adapter (0x330-0x34F) Bytes 1-16
0x330-0x33F  
Sound Card / MIDI Port System Use
Non NE2000 Network Card System Use
NE2000 Network Card (0x300-0x31F) Bytes 1-16
0x340-0x34F  
SCSI Host Adapter (0x330-0x34F) Bytes 17-32
SCSI Host Adapter (0x340-0x35F) Bytes 1-16
Non NE2000 Network Card System Use
NE2000 Network Card (0x340-0x35F) Bytes 1-16
0x350-0x35F  
SCSI Host Adapter (0x340-0x35F) Bytes 17-32
NE2000 Network Card (0x300-0x31F) Bytes 1-16
0x360-0x36F  
Tape Accelerator Card (0x360) System Use Quaternary IDE Controller (Slave Drive)(0x36E-0x36F)
Non NE2000 Network Card System Use
NE2000 Network Card (0x300-0x31F) Bytes 1-16
0x370-0x37F  
Tape Accelerator Card (0x370) Secondary IDE Controller (Slave Drive) LPT1 - First Parallel Port (Color systems)
System Use LPT2 - Second Parallel Port (Monochrome Systems)
NE2000 Network Card (0x360-0x37F) Bytes 1-16
0x380-0x38F System Use Sound Card (FM Synthesizer) System Use
0x390-0x39F System Use
0x3A0-0x3AF System Use
0x3B0-0x3BF VGA/Monochrome Video LPT1 - First Parallel Port (Monochrome Systems)
0x3C0-0x3CF VGA/CGA Video
0x3D0-0x3DF VGA/CGA Video
0x3E0-0x3EF  
Tape Accelerator Card (0x370) System Use COM3 - Third Serial Port
System Use Tertiary IDE Controller (Slave Drive)(0x3EE-0x3EF)
0x3F0-0x3FF  
Floppy Disk Controller COM1 - First Serial Port
Tape Accelerator Card (0x3F0) Primary IDE Controller (Slave Drive)(0x3F6-0x3F7) System Use
 

This table is not complete, and hopefully has no errors in it. I will add to this table as time goes on, and more devices are developed.

ب

خوب اگه دقت کنید میبینید که برای کیبورد توی جدول بالا آدرس 0X60 رو نوشته. حالا ما میتونیم با دستور مخصوص IN و OUT با کیبورد ارتباط برقرار کنیم

یه مثال میزنم!

in al, 0x60		; get byte from 8042 microcontroller input register

کد بالا مقداری رو از میکروکنترلر 8042 میگیره و در al قرار میده!

 

» فعال کردن A20

راه های فعال کردن A20 خیلی زیاده و ممکنه همه شون روی یه کامپیوتر جواب نده. منظورم اینه که ممکنه یه راه برای فعال کردن A20 وجود داشته باشه که روی کامپیوتر من کار کنه ولی روی کامپیوتر شما کار نکنه!

ولی به هرحال ما چندتا راهش رو براتون میگیم!

راه اول: از طریق System Control Port A

این راه آسون ترین و ساده ترین راه ممکن هست. ما میتونیم توی بعضی از کامپیوتر ها از طریق کنترلر ورودی و خروجی 0x92 خط A20 رو فعال کنیم! چند بیت پایین میتونیم استفاده کنیم!

  • Bit 0 - Setting to 1 causes a fast reset (Used to switch back to real mode)
  • Bit 1 - 0: disable A20; 1: enable A20
  • Bit 2 - Manufacturer defined
  • Bit 3 - power on password bytes (CMOS bytes 0x38-0x3f or 0x36-0x3f). 0: accessible, 1: inaccessible
  • Bits 4-5 - Manufacturer defined
  • Bits 6-7 - 00: HDD activity LED off; any other value is "on"

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

mov	al, 2	; set bit 2 (enable a20)
out	0x92, al

کار های دیگه هم ما میتونیم با این پورت انجام بدیم. مثل، مثال زیر 

mov	al, 1	; set bit 1 (fast reset)
out	0x92, al

این روش روی بعضی از ماشین های مجازی سازی مثل Bochs (پیشنهاد میکنم این برنامه رو هم دانلود و نصب کنید و از این به بعد از اون استفاده کنید) به خوبی جواب میده!

 

روش دوم: از طریق BIOS

این روش از طریق bios خط A20 رو فعال میکنه که میتونید برید توی مطلب اصلی از اینجا بخونید!

 

روش سوم : کنترلر کیبورد

در این روش باید با میکروکنترلر 8043 که بالا درباره اش حرف زدیم، ارتباط برقرار کنیم! بنابراین باید قبلش با برنامه نویسی سخت افزار کمی آشنا بشیم!

نقشه پورت

ببینید باید ما با نقشه ی این کنترلر آشنا باشیم تا بتونیم با اون ارتباط برقرار کنیم. نقشه اون به شکل زیره

 

 

Port Mapping
Port Read/Write Descripton
0x60 Read Read Input Buffer
0x60 Write Write Output Buffer
0x64 Read Read Status Register
0x64 Write Send Command to controller

 

همونطور که میبینید از پورت 0X60 استفاده شده.ما میتونیم با نوشتن در پورت 0X64 یه دستور رو برای این میکروکنترلر ارسال کنیم و اگه این دستور یه پارامتر هم داشته باشه میتونیم اونو از طریق پورت 0X60 بفرستیم. بعد میتونیم پیامی که میکروکنترلر برامون میفرسته رو از طریق پورت 0X60 بخونیم!

راستش سرعت این میکروکنترلر خیلی از سرعت CPU ما پایین تر هست بنابراین دیرتر به درخواست ما پاسخ میده. برای اینکه ما درست بتونیم کار کنیم باید منتظر بمونیم تا ببینیم کی پاسخ میده! برای اینکار باید به وضعیت میکروکنترلر نگاه کنیم ببینیم آیا پاسخ داد؟ وقتی پاسخ داد بریم اونو بخونیم! حالا از کجا وضعیت میکروکنترلر رو پیدا کنیم؟

به جدول زیر یه نگاهی بندازید! ما میتویم این جدول رو با خوندن از پورت 0X64 بدست بیاریم

  • Bit 0: Output Buffer Status
    • 0: Output buffer empty, dont read yet
    • 1: Output buffer full, please read me :)
  • Bit 1: Input Buffer Status
    • 0: Input buffer empty, can be written
    • 1: Input buffer full, dont write yet
  • Bit 2: System flag
    • 0: Set after power on reset
    • 1: Set after successfull completion of the keyboard controllers self-test (Basic Assurance Test, BAT)
  • Bit 3: Command Data
    • 0: Last write to input buffer was data (via port 0x60)
    • 1: Last write to input buffer was a command (via port 0x64)
  • Bit 4: Keyboard Locked
    • 0: Locked
    • 1: Not locked
  • Bit 5: Auxiliary Output buffer full
    • PS/2 Systems:
      • 0: Determins if read from port 0x60 is valid If valid, 0=Keyboard data
      • 1: Mouse data, only if you can read from port 0x60
    • AT Systems:
      • 0: OK flag
      • 1: Timeout on transmission from keyboard controller to keyboard. This may indicate no keyboard is present.
  • Bit 6: Timeout
    • 0: OK flag
    • 1: Timeout
    • PS/2:
      • General Timeout
    • AT:
      • Timeout on transmission from keyboard to keyboard controller. Possibly parity error (In which case both bits 6 and 7 are set)
  • Bit 7: Parity error
    • 0: OK flag, no error
    • 1: Parity error with last byte

خوب چیز های مهم زیاد داره که من اونا رو بزرگ نوشتم!

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

wait_input:
        in      al,0x64		; read status register
        test    al,2		; test bit 2 (Input buffer status)
        jnz     wait_input	; jump if its not 0 (not empty) to continue waiting

 

ارسال دستور به میکروکنترلر 8043

خوب حالا وقت اون رسیده تا به میکروکنترلر مون یه دستور بفرستیم که A20 رو فعال کن! اگه برگردید و به جدول بالا دوباره نگاه کنید میبینید برای ارسال دستور باید از پورت 0X64 استفاده کنیم!

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

 

Keyboard Controller Commands
Keyboard Command Descripton
0x20 Read Keyboard Controller Command Byte
0x60 Write Keyboard Controller Command Byte
0xAA Self Test
0xAB Interface Test
0xAD Disable Keyboard
0xAE Enable Keyboard
0xC0 Read Input Port
0xD0 Read Output Port
0xD1 Write Output Port
0xDD Enable A20 Address Line
0xDF Disable A20 Address Line
0xE0 Read Test Inputs
0xFE System Reset
Mouse Command Descripton
0xA7 Disable Mouse Port
0xA8 Enable Mouse Port
0xA9 Test Mouse Port
0xD4 Write to mouse

 

اگه به جدول بالا دقت کنید بایت 0XDD و 0XDF برای فعال کردن و غیر فعال کردن خط A20 استفاده میشه!

بنابراین با کد زیر میتونیم به این بایت دسترسی پیدا کنیم!

; Method 3.1: Enables A20 through keyboard controller
mov al, 0xdd	; command 0xdd: enable a20
out 0x64, al	; send command to controller

یه راه دیگه هم از طریق همین جدول بالا وجود داره که میتونیم اون راه هم انجام بدیم!

برای راه دوم باید از دوبایت 0XD0 و 0XD1 در جدول بالا استفاده کنیم برای آشنایی با این مورد هم میتونید به سایت منبع اصلی سر بزنید و قسمت Method 3.2: Enabling A20 through Output Port رو مطالعه کنید! (اینجا کلیک کنید)

خوب کد همه موارد بالا به صورت کامل میتونید از لینک زیر دریافت کنید!

دانلود کنید!

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

خوب این قسمت هم به پایان رسید. امیدوارم مفید واقع شده باشه! s15

فعلا!

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