اطلاعیه

Collapse
No announcement yet.

برسی یک سیستم 386

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    #16
    پاسخ : برسی یک سیستم 386


    1. مقدمه ای در مورد وقفه ها
    2. نوشتن یک بوت لودر ساده با اسمبلی
    3. اسمبل کردن بوت لودر با NASM


    وقفه ها : از اونجایی که داشتن اطلاعات کاملی از وقفه ها برای نوشتن یک سیستم عامل ضروری و اجباریه. و من نمی تونم یه آموزش کامل از این موضوع رو اینجا بزارم، توصیه می کنم اگه اطلاعاتتون تو این زمینه کم هستش مطالعاتتون رو تو این زمینه بیشتر کنید. ولی یه توضیح مختصر درباره وقفه ها برای کسایی که هیچ اطلاعی ندارند میتونه مفید باشه.
    وقفه ها در واقع یه سری از توابع نوشته شده از قبل و آماده هستند که توی حافظه ROM در BIOS قرار دارند. و برنامه نویس میتونه برای انجام خیلی از کارها از اونا استفاده کنه. در واقع بعد از روشن شدن کامپیوتر این توابع از ROM خونده شده و به RAM منتقل میشه. وقفه ها رو با استفاده از اعداد هگزادسیمال نامگذاری می کنند. که میتونه عددی بین 0 H تا 100H باشه. همچنین به محلی از حافظه که اطلاعت وقفه ها در اون ذخیره میشه "جدول بردار وقفه" یا IVT گفته میشه. یکی از این وقفه ها وقفه شماره 19H هستش که بعد از لود شدن وقفه ها به حافظه به عنوان اولین کار اجرا میشه. وظیفه این وقفه همون چیزیه که تو پست قبلی گفتیم یعنی پیدا کردن و لود و اجرای بوت لودر از سکتور راه انداز دیسک. در ضمن به صورت قراردادی همیشه برنامه بوت لودر بعد از لود شدن در آدرس 7C00H قرار میگیره که بعداً دونستن این نکته به دردمون می خوره. به عنوان توضیح پایانی در مورد وقفه ها باید بگم که وقفه ها معمولاً در برنامه نویسی سطح پایین مورد استفاده قرار می گیرند و یکی از وظیفه های سیستم عامل فراهم کردن توابعی هست که برنامه نوسانی که تو اون سیستم عامل به یه زبون سطح بالا برنامه می نویسند رو از استفاده کردن از وقفه ها بی نیاز کنه. اگه با ویژوال بیسیک برنامه نویسی کرده باشید حتماً میدونید که اونجا اسمی از وقفه ها به میون نیومده ولی وقتی با اسمبلی کار می کنید به وفور باید از وقفه ها استفاده کنید.
    نوشتن یک بوت لودر ساده با اسمبلی:
    بالاخره به مرحله کدنویسی که میدونم منتظرش بودبد رسیدیم. هچند که این تازه اول راهه و این کد در برابر کدهایی که در آینده قراره بنویسیم تقریباً هیچه ولی باز از هیچی بهتره. این کد کاری که انجام میده در واقع اینه که هیچ کاری انجام نمیده. یک فایل متنی تو Notepad باز کنید و کد زیر رو توش تایپ کنید.
    کد:
    Org 0x7c00
     bits 16
     cli
     hlt
     times 510 - ($-$$) db 0
     dw 0xAA55

    حالا باید کمی در باره این خطوط توضیح بدم. خط اول از راهنمای org استفاده کرده و به اسمبلر می گوید که این کد بعد از لود شدن در آدرس 0x7c00 قرار خواهد گرفت. به یاد دارید که در مورد این موضوع قبلاً توضیح دادیم که همیشه برنامه بوت لودر بعد از لود شدن تو همین آدرس قرار میگیره پس لازمه که این کد رو حتماً اول تمام بوت لودر هایی که مینویسیم بزاریم.
    خط دوم به اسمبلر میگه که این برنامه رو به صورت 16 بیتی ترجمه کنه. یعنی اینکه بوت لودر ما یک بوت لودر 16 بیتی هستش. شاید بپرسید مگه قرار نیست که ما یک سیستم عامل 32 بیتی بسازم پس چرا تو حالت 16 بیتی داریم کد مینویسیم. در جواب شما باید بگم که تمام بوت لودر هایی که در تمام دنیا نوشته میشوند اول باید تو مود 16 بیتی باشند و بعد میتونند با اجرای دستوراتی وارد مود 32 بیتی بشوند. یعنی CPU به صورت قراردادی همیشه فرض میکنه که برنامه بوت لودر یک برنامه 16 بیتیه و با حالت 16 بیتی که اصطلاحاً بهش حالت واقعی هم میگن شروع به کار میکنه. فرمان های cli و hlt هم همون طور که برنامه نویسای اسمبلی میدونن به ترتیب وقفه ها رو غیر فعال و Cpu رو متوقف می کنند. که در واقع میشه گفت طبق توضیحات بالا هیچ کار مفیدی نمی کنند.
    حتماً یادتون هست که برنامه بوت لودر حتماً باید 512 بایت باشه نه بیشتر نه کمتر ولی این چند خط کد ما 10- 15 بایت بیشتر نمیشه ( البته بعد از ترجمه ). در اسمبلر NASM علامت $ شماره آدرس دستور جاری و $$ شماره آدرس اولین دستور را مشخص میکنند ( باز هم بعد از ترجمه ). از آنجایی که اندازه فایل ترجمه شده باید 512 بایت باشد باید مقداری اطلاعات بی معنی به پایتن فایل ترجمه شده اضافه کنیم تا این مشکل رفع بشه. دستور times که در بالا نوشته شده از بعد از دستور hlt تا بایت 510 رو با مقدار 0 پرمیکنه.
    به یاد داشته باشید برای اینکه برنامه شما به عنوان نقطه شروع سیستم یا همون بوت لودر توسط BIOS شناسایی و لود بشه یک شرط دیگه هم وجود داره که تا اینجا بهش اشاره نکرده بدیم. فایل بوت لودر باید دارای امضای مخصوصی باشه تا BIOS بتونه اون رو شناسایی کنه. اون شرط اینه که بایت 511 برابر با 0xAA و بایت 512 برابر با 0x55 باشه. به همین دلیل با دستور times فقط تا بایت 510 رو پر کردیم و دو بایت آخر رو برای امضای بوت لود نگه داشتیم. حالا دیگه توضیحات کامل شده و نوبت مرحله بعدی میرسه.
    اسمبل کردن بوت لودر با NASM:
    برنامه ای که تو بخش قبلی نوشتید رو توی فایلی به اسم boot.asm ذخیره کنید و توی همون مسیری که برنامه NASM قرار داره قرار بدید. بعد از طریق Command Window به مسیر مربوطه وارد شده و فرمان زیر را اجرا کنید.

    کد:
    nasm -f bin boot.asm -o boot.bin


    این فرمان دارای دو سوییچ است و به ترتیت سویچ –f bin به اسمبلر میگه که فرمت خروجی باید یک فایل باینری باشه و –o هم برای مشخص کردن نام فایل خروجی استفاده میشه. بعد از اجرای این دستور شما باید یک فایل با نام boot.bin دقیقاً با سایز 512 بایت داشته باشید.
    [glow=red,2,300]تاپیک های ایجاد شده[/glow]

    دیدگاه


      #17
      پاسخ : برسی یک سیستم 386

      ابزارهای لازم برای طراحی سیستم عامل:
      [hr]
      1. برنامه شبیه سازBochs: شما باید بعد از انجام هر تغییر روی سیسم عاملتون اون رو تست برای این کار شما میتونید سیستم عامل را روی سیستمتون نصب کنید و عملکردش رو ببینید ولی از اونجایی که این کار مستلزم اینه که سیستم عامل قبلیتون که معمولاً ویندوز هستش رو پاک کنید که این کار خیلی زمانبر و خسته کننده خواهد بود. برای جلوگیری از این کار میتونید از ابزارهای شبیه ساز استفاده کنید که یک ماشین مجازی رو در اختیارتون میزاره و میتونید دقیقاً عملکردی که سیستم عامل شما بعد از نصب خواهد داشت رو توی محیط ویندوز بدون از دست دادن وقتتون در عرض چند ثانیه ببینید برای این کار ما از نرم افزار Bochs استفاده میکنیم که هم خیلی ساده و هم کم حجم هستش. نر ام افزار های مشابه دیگه ای مثل VMware، Virtualbox، QEMU، Virtual Machine PC و ... استفاده کنید ولی پیشنهاد من برای شروع همون Bochs هست. این برنامه رو می تونید از اینجا دانلود کنید
      2. اسمبلر NASM : این برنامه برای اسمبل کردن یا ترجمه کردن برنامه های اسمبلی به زبان ماشین استفاده میشه، هرچند اسمبلر های زیادی وجود داره ولی بعضی از اونها مثل MASM و TASM برای طراحی سیستم عامل کارآمد نیستند و بهترین مورد همین برنامه NASM هستش. این برنامه رو می تونید از اینجا دانلود کنید.
      3. : MSVC++برای نوشتن هسته سیستم عامل به زبان C به یک کامپایلز C احتیاج داریم که میتونید از ورژن 2005 یا 2008 این نرم افزار استفاده کنید.
      4. : PartCopy برای این که بتونیم برنامه بوت لودر رو در سکتور راهنداز دیسک ( بعداً درباره او توضیح می دم) کپی کنیم به این برنامه کوچک احتیاج داریم که البته برای این مورد هم گزینه های مختفی وجود داره ولی من این رو به خاطر سادگی و حجم کمش پیشنهاد می کنم. این برنامه رو می تونید از اینجا دانلود کنید.
      5. VFD : حتماً تا حالا برنامه هایی مثل CloneCD و UltraISO و ... که یک درایو مجازی برای CD یا DVD می سازند رو دیدید. این برنامه همین کار رو برای فلاپی انجام میده. از اونجایی که ما سیستم عامل جدید رو قراره روی فلاپی اجرا کنیم ( بعدها روی هارد دیسک هم انجام میدیم) باید یک درایو فلاپی داشته باشیم و از اونجایی که بیشتر کامپیوتر های امروزی درایو فلاپی ندارند و این عتیقه رو باید تو موزه ها دنبالش بگردیم از این نرم افزار برای نصب یک درایور فلاپی مجازی روی سیستم استفاده می کنیم. البته اگه شما اون عتیقه رو تو سیستمتون دارید بازم پیشنهاد می کنم از همین برنامه استفاده کنید و از فلاپی واقعی استفاده نکنید چون سرعت فلاپی واقعی خیلی پایینه و به در کار ما نمی خوره که هر چند دقیقه ممکنه بخواهیم اطلاعات روی فلاپی رو تغییر بدیم و دوباره سیستم عامل رو از اون لود کنیم. این نرم افزار رو از اینجا دانلود کنید.
      خب. تمام چیزهایی که لازم داشتیم همین ها بود. حالا اگه مشتاقید که ادامه راه رو برید و می خواهید یه سیستم عامل برای خودتون طراحی کنید. قبل از خوندن مطالب بعدی تمامی این ابزار رو باید آماده کنید. توصیه می کنم تمامی چیزهایی که اینجا یاد میگیرید حتماً همون موقع خودتون رو کامپیوتر اجرا کنید تا مطمئن بشید که موضوع رو کاملاً متوجه شدید .
      [glow=red,2,300]تاپیک های ایجاد شده[/glow]

      دیدگاه


        #18
        پاسخ : برسی یک سیستم 386

        من متاسفانه نتونستم MSVC++ را پیدا کنم. آیا این امکان وجود داره که با ویژوال استودیو هسته ی سیستم عامل رو بنویسیم؟

        دیدگاه


          #19
          پاسخ : برسی یک سیستم 386

          با هر کامپایلر ++C میشه اینکار کرد
          از DEV C و CodeBlocks هم میتونین استفاده کنین

          تو متن بالا گفته شده که فقط برای لود کردن هسته سیستم عامل باید از اسمبلی استفاده بشه
          بعدش شما میتونین هر برنامه ای که با هر زبانی نوشته شده باشه فراخوانی کنین
          فقط این نکته هم باید اضافه بشه که برنامه های شما باید کاملا مستقل از سیستم عامل باشه
          و حتی شما مجاز به استفاده از وقفه های شماره 21 که مربوط به داس میشه نیز نیستین
          [glow=red,2,300]تاپیک های ایجاد شده[/glow]

          دیدگاه


            #20
            پاسخ : برسی یک سیستم 386

            خب بالاخره تونستم اولین سیستم عامل خودم که هیچ کاری انجام نمیده بنویسم :mrgreen:


            کد برنامه میزارم و یه سری توضیح برای اینکه بتونید خودتون اون اسمبل کنید.
            توضیحات خود کد باشه برای بعدا که برگشتم :redface:
            اول از همه این کدها باید با پسوند ASM ذخیره کنید.




            کد:
            ;*********************************************
            ;	Boot.asm 
            ;	Operating Systems Development Tutorial
            ;*********************************************
            bits	16		
            org		0x7c00	
            start:     jmp loader
            
            
            ;*********************************************
            ;	OEM Parameter block
            ;*********************************************
            bpbOEM					db "My_OS"	
            	
            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  "
            
            
            msg			db	"Welcome to My Operating System!", 0
            
            
            Print:
            			lodsb				
            			or		al, al		
            			jz		PrintDone	
            			mov		ah,	0eh	
            			int		10h
            			jmp		Print		
            PrintDone:
            			ret			
            
            
            ;*********************************************
            ;	Bootloader Entry Point
            ;*********************************************
            loader:
            
            
            	xor		ax, ax		
            	mov		ds, ax		
            	mov		es, ax	
            	
            	
            	mov 	ax, 3
            	int 	10h
            	
              mov		ax, 0600h
              mov   bx, 0f00h
              mov   cx, 0
              mov   dx, 194fh
              int   10h
             
            	mov 	ah, 02h
            	mov		bh, 0
            	mov 	dx, 0A14h 
            	int 	10h 
            
            
            	mov		si, msg						 
            	call	Print						 
             
            	mov 	ah, 02h
            	mov		bh, 0
            	mov 	dx, 1950h 
            	int 	10h 
            	
            	xor		ax, ax						 
            	int		0x12				 
            
            
            	cli							 
            	hlt						 
            	
            times 510 - ($-$$) db 0					 
            dw 0xAA55



            گام بعدی استفاده از دستورات زیر در خط فرمان ویندوز هست




            nasm -f bin Boot.asm -o Boot.bin
            PARTCOPY Boot.bin 0 200 -f0 0

            دقت کنید یه در مسیر جاری باید هر سه فایل ASM شما و NASM و PARTCOPY قرار داشته باشند.
            اگه فلاپی درایو و یه فلاپی سالم دارید همین الان از این دستورها استفاده کنین در غیر این صورت باید برنامه VFD یه درایو مجازی بسازید
            بعدش میتونین با هر برنامه ماشین مجازی سیستم عامل از روی فلاپی بوت کنین
            همون طوری که تو پست های قبلی گفتم میتونین از برنامه ساده bochs استفاده کنین.
            اگر مشکلی داشتید همینجا مطرح کنین. تو پست بعدی حتما در باره کار با این برنامه ها بیشتر توضیح میدم :nerd:
            [glow=red,2,300]تاپیک های ایجاد شده[/glow]

            دیدگاه


              #21
              پاسخ : برسی یک سیستم 386

              آموزش های شما بسیار خوبند. لطفا ادامه بدید.

              دیدگاه


                #22
                پاسخ : برسی یک سیستم 386

                با تشکر از پلاسمای عزیز :applause:


                قبل از هر چیزی درباره کار با برنامه هایی که تو پست های قبلی اشاره شد توضیح میدم
                اول از همه به برنامه NASM برای اسمبل کردن فایل ها نیاز داریم. کار با این برنامه تحت محیط داس هست.
                خوب اول از همه من یه پوشه تو درایو C می سازم و اسم اون OS قرار میدم. بعد فایل یه فایل متنی باز میکنم و برنامه بالا داخلش کپی و اون با اسم boot.asm در این پوشه ذخیره میکنم.
                حالا فایل NASM به همون پوشه انتقال میدم
                بعد پنجره RUN باز و عبارت CMD تاپت میکنم تا خط فرمان ویندوز اجرا بشه.
                برای اسمبل کردن کافیه فرمت زیر استفاده کنین.
                کد:
                nasm -f bin Boot.asm -o Boot.bin

                در این فرمان پارامتر f bin/ باعث میشه بجای فایل exe یه فایل باینری ساخته بشه. دقت کنین وقتی شما هنوز سیستم عامل ندارید پس کامپیوتر قادر به تشخیص فرمت داخلی برنامه شما نیست بنابراین برنامه شما حتما باید با فرمت باینری ساخته بشه.
                پارامتر o- نیز خروجی مشخص میکنه که در اینجا ما boot.bin به عنوان نام فایل خروجی انتخاب کردیم.
                اگه همه چی درست باشه شما الان باید یه فایل به اسم boot.bin داشته باشید. :agree:


                اگر فلاپی ندارید میتونین از برنامه VFD استفاده کنین و یه درایو مجازی بسازید. برای اینکار برنامه اجرا و در سربرگ Driver ابتدا Install و سپس Start بزنید. بعد به سربرگ Drive 0 برید و ابتدا با کلیک روی Change نام درایو :A انتخاب کنید و بعدش باید Open/Create کلیک و Creat بزنید تا درایو مجازی برای شما ساخته بشه.


                حالا باید فایل boot.bin در رکورد بوت دیسک کپی کنیم. چون سیستم عامل ویندوز اجازه دسترسی به این بخش به ما نمیده پس باید از یه برنامه کمکی استفاده کنیم. برنامه PARTCOPY در پوشه OS کپی میکنیم و با استفاده از فرمان زیر عملیات کپی انجام میدیم.

                کد:
                PARTCOPY Boot.bin 0 200 -f0 0

                برای استفاده از این دستور شما باید پارامترهای زیر وارد کنید.
                میسر فایل مبدا (همون فایلی که نوشیم اگه تو مسیر جاری باشه فقط اسم اون مینویسیم)
                آدرس شروع (معمولا 0)
                اندازه فایل (در اینجا 512 هست که باید به فرمت هگز بنویسیم. پس میشه 200)
                آدرس مقصد (f- برای فلاپی و h- برای هارد و عدد جلوی اون شماره درایو یا پارتیشن هست که از 0 شروع میشه. در اینجا درایو A انتخاب شده)


                بعد از این مراحل شما یه دیسک قابل بوت دارید. اگه فلاپی واقعی دارید همین الان سیستم ریستارت و از روی فلاپی بوت کنید تا نتیجه کار ببینین در غیر این صورت میتونین یه ماشین مجازی نصب کنین.
                شما میتونین از هر برنامه مجازی سازی استفاده کنین. من آموزش برنامه Bochs میزارم که یه برنامه خیلی کم حجم و ساده هست
                برنامه از پست بالا دانلود و اجرا کنین. در قسمت Edite Option باید عبارت Disk & Boot انتخاب و سپس Edit بزنین. قسمت های مختلف باید طبق اطلاعات زیر پر کنید.

                کد:
                Type of Florry drive: 3.5" 1.44M
                First flopy image/device: a:
                typr of floppy media: 1.44M

                و حتما تیک Inserted هم بزنید و ok کنید.
                شما میتونین تنظیمات save کنید تا بعدا بتونین به راحتی با Load کردن از این تنظیمات استفاده کنین.
                اگه همه چیز درست باشه میتونین با کلیک روی Start ماشین مجازی روشن و برنامه تست کنین
                اگه سوالی بود در خدمتیم
                [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                دیدگاه


                  #23
                  پاسخ : برسی یک سیستم 386

                  ممنون دوست عزیز. من زبان اسمبلی بلد نیستم امّا به یاد گیری آن علاقه مندم.شما چه مرجعی رو برای شروع پیشنهاد میکنید؟

                  دیدگاه


                    #24
                    پاسخ : برسی یک سیستم 386


                    حالا بیاید کدهای قبلی آنالیز کنیم و ببینیم چه کاری انجام میده


                    کد:
                     
                    bits	16		
                    org		0x7c00	
                    start:     jmp loader

                    خط اول میگه که برنامه 16 بیتی هست
                    خط دوم آدرس شروع برنامه تعیین میکنه (چرا 0x7c00 ؟)
                    خط سوم هم باعص میشه برنامه به نقطه شروع پرش کنه





                    کد:
                    ;*********************************************
                    ;	OEM Parameter block
                    ;*********************************************
                    bpbOEM					db "My_OS"	
                    	
                    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  "

                    با این قسمت فعلا کاری نداریم و بعدا درباره اون توضیحات کاملی میدم





                    کد:
                    msg			db	"Welcome to My Operating System!", 0

                    یه متغییر به اسم msg تعریف میکنیم و پیام خودمون بصورت رشته ای ذخیره میکنیم. دقت کنید که حتما بایت آخر باید 0 باشه تا پایان رشته اعلام کنیم.





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

                    این کدها یه ماکرو تشکیل میدن که تو برنامه اصلی با فراخوانی اون میتونیم یه متن روی صفحه نمایش نشون بدیم.
                    دستور Loadsb باعث میشه محتوی خانه ای از حافظه که ثبات SI به اون اشاره میکنه در AL کپی بشه. اگه AL صفر باشه دستور jz برنامه به خط آخر پرش میده در غیر این صورت به کمک تابع 0x0E وقفه 10 کارکتر موجود در AL چاپ میشه و دستور jmp باعث میشه این حلقه تکرار بشه. دستور ret هم باعث برگشت از روتین به محل اصلی برنامه میشه.




                    کد:
                     
                    loader:
                    
                    
                    
                    
                    	xor		ax, ax		
                    	mov		ds, ax		
                    	mov		es, ax

                    در اینجا سگمنت های مختلف مقدار دهی میکنیم




                    کد:
                     
                    	mov 	ax, 3
                    	int 	10h

                    با این وقفه موقعیت مکان نما میتونیم بخونیم (تو برنامه کار خاصی نمیکنه)





                    کد:
                     
                         mov   ax, 0600h
                         mov   bx, 0f00h
                         mov   cx, 0
                         mov   dx, 194fh
                         int    10h

                    این وقفه هم با شیفت دادن صفحه نمایش باعث پاک شدن صفحه میشه





                    کد:
                      
                    	mov 	   ah, 02h
                    	mov	   bh, 0
                    	mov 	   dx, 0A14h 
                    	int 	   10h

                    این تابع مکان نما به سطر 10 (0x0A) و ستون 20 (0x14) منتقل میکند.





                    کد:
                     
                    	mov	   si, msg						 
                    	call	   Print

                    در این قسمت ابتدا آدرس شروع رشته msg در ثبات Si کپی و سپس با فراخوانی تابع Print که در بالا نویشتیم عملیات چاپ رشته انجام میگیره.





                    کد:
                      
                    	mov 	   ah, 02h
                    	mov	   bh, 0
                    	mov    dx, 1950h 
                    	int 	   10h

                    با کمک این وقفه موقعیت مکان نما به خارج از صفحه انتقال میدیم تا مکان نما مخفی کنیم





                    کد:
                       	
                    	xor		ax, ax						 
                    	int		0x12

                    با کمک این وقفه میزان حافظه سیستم تعیین میشود (در حال حاظر مهم نیست ولی بعدا مورد نیاز خواهد بود)






                    کد:
                      
                    	cli							 
                    	hlt

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






                    کد:
                      
                        times   510 - ($-$$) db 0					 
                        dw     0xAA55

                    510 بایت باقی مانده این بلوک باید با 0 مقدار دهی کنیم و در نهایت کد 0xAA55 در انتهای کد به عنوان امضا قرار میدیم تا کد ما توسط سیستم به عنوان کد معتبر شناسایی بشه


                    اگه اسمبلی برنامه نویسی میکنید میتونین کد های خودتون در این برنامه بزارین تا برنامه شما بصورت مستقل و قابل بوت شدن اجرا بشه.
                    در ادامه نحوه بوت کردن سیستم و برنامه نویسی با زبان C شرح میدم :read:
                    [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                    دیدگاه


                      #25
                      پاسخ : پاسخ : برسی یک سیستم 386

                      نوشته اصلی توسط PLASMA
                      ممنون دوست عزیز. من زبان اسمبلی بلد نیستم امّا به یاد گیری آن علاقه مندم.شما چه مرجعی رو برای شروع پیشنهاد میکنید؟

                      اسمبلی زبانی شیرین ساده و نسبتا پیچیده هست
                      کتاب های زیادی وجود دارن مثل کتاب جعفر نژاد و سید رضی ولی بیشتر اونها بر اسال اسمبلر توربو اسمبلی هست
                      اسمبلر های مختلفی وجود دارن که شبیه به هم هستن و فقط در استفاده از ماکرو ها و کتابخانه ها متفاوت اند

                      [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                      دیدگاه


                        #26
                        پاسخ : برسی یک سیستم 386

                        تا جایی که من فهمیدم:
                        بوتلودر ما که وظیفه ی اون بارگذاری سیستم عامله در قسمت bootable فلاپی قرار میگیره و کرنل ما در قسمت معمولی.
                        بوتلودر هم کرنل رو از اونجا اجرامیکنه. درسته؟

                        دیدگاه


                          #27
                          پاسخ : برسی یک سیستم 386

                          نوشته اصلی توسط PLASMA
                          تا جایی که من فهمیدم:
                          بوتلودر ما که وظیفه ی اون بارگذاری سیستم عامله در قسمت bootable فلاپی قرار میگیره و کرنل ما در قسمت معمولی.
                          بوتلودر هم کرنل رو از اونجا اجرامیکنه. درسته؟
                          بله
                          برنامه بوت لودر باید در رکورد بوت دیسک قرار بگیره که حجم اون 512 بایت هست
                          شما با کمک اون میتونین مکان قرار گرفتن فایل های کرنل پیدا و اونها اجرا کنین
                          [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                          دیدگاه


                            #28
                            پاسخ : برسی یک سیستم 386

                            [s]ممنون.برای بوت این برنامه از روی سی دی باید چه کار کرد؟
                            [/s]
                            جواب رو پیدا کردم.
                            کد:
                            ;*********************************************
                            ;	OEM Parameter block
                            ;*********************************************
                            bpbOEM					db "My_OS"	
                            	
                            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  "
                            اگه اشتباه نکنم به این میگن بلوک oem درسته؟

                            دیدگاه


                              #29
                              پاسخ : برسی یک سیستم 386

                              نوشته اصلی توسط PLASMA
                              [s]ممنون.برای بوت این برنامه از روی سی دی باید چه کار کرد؟
                              [/s]
                              جواب رو پیدا کردم.
                              کد:
                              ;*********************************************
                              ;	OEM Parameter block
                              ;*********************************************
                              bpbOEM					db "My_OS"	
                              	
                              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  "
                              اگه اشتباه نکنم به این میگن بلوک oem درسته؟
                              بله. درسته
                              این بلوک فاقد قسمت اجراییه و فقط کارش معرفی دیسک و سیستم فایل هست
                              [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                              دیدگاه


                                #30
                                پاسخ : برسی یک سیستم 386

                                بلاک OEMو سیستم فایل
                                [hr]
                                خب، تا اینجای کار ما تونستیم یه برنامه بوت لودر بنویسیم که بتونه سیستم رو لود کنه و یه پیام روی مانیتور چاپ کنه. همونطور که چندبار گفتیم برنامه بوت لودر باید دقیقاً 512 بایت حجم داشته باشه و برای اینکه بتونیم هسته سیستم عاملی که بیشتر از 512 بایت حجم داره که تقریباً 100 درصد سیستم عامل ها رو شامل میشه باید این کار رو تو دو مرحله انجام بدیم.
                                1- اول با بوت لودر 512 بایتی سیستم رو راه اندازی کنیم
                                2- تنظیمات لازم برای ورود به مود 32 بیتی ( مود حفاظت شده ) رو توی این برنامه انجام بدیم و بعد هسته سیستم عامل رو توسط همین بوت لودر بارگذاری کنیم و کنترل سیستم رو به کرنل بسپاریم.
                                بعضی وقت ها ( در سیستم عامل های بزرگ همیشه ) تنظیمات لازم برای آماده سازی سیستم و لود کردن کرنل خیلی زیاده و نمیشه با یه برنامه 512 بایتی این کار رو انجام داد. توی اینجور مواقع باید از بوت لودر 2 مرحله ای استفاده کنیم. یعنی این که بوت لودر 512 بایتی ما بعد از اجرا شدن یه برنامه فرعی دیگه رو اجرا کنه که این برنامه میتونه هر حجمی داشته باشه و تنظیمات لازم توی این برنامه انجام بشه و بعد این برنامه کرنل رو اجرا کنه. البته برای سیستم عامل های 16 بیتی نیازی به این مرحله نیست و بوت لودر 512 بایتی میتونه مستقیماً کرنل رو لود کنه و تنظیمات بعدی توی خود کرنل انجام بشه.
                                به این جور بوت لودر ها ، بوت لودر چند مرحله ای یا MultiStage Bootloader گفته میشه. حالا شاید سوال پیش بیاد که منظور از تنظیمات لازم چیه. یکی از چیزهایی که لازمه در موردش بشتر بدونید تا تنظیمات مربوطه رو انجام بدید همون بلاک OEM هستش که تو پست قبلی یه کم بهش اشاره کردیم و تو این پست میخواهیم بیشتر در موردش توضیح بدیم.
                                وقفه شماره 13 H: این وقفه برای انجام اعمالی بر روی دیسک استفاده میشه و دارای توابع مختلفی هست که چند تاش برای ما خیلی مهمه.
                                تابع 0 H : تابع شماره 0H از این وقفه برای ریست کردن هد دسیک استفاده میشه. وقتی که ما میخواهیم اطلاعاتی رو از فلاپی بخونیم هد فلاپی درایو ممکنه تو هر جایی باشه ولی برای اینکه بتونیم مکان اطلاعات مورد نظر روی دیسک رو درست شناسایی کنیم لازمه قبل از هر عمل خوندن روی فلاپی، هدش رو به سکتور شماره 0 منتقل کنیم. برای فراخوانی این تابع باید ثبات AH با مقدار صفر و DL با شماره درایو مورد نظر تنظیم بشه. در صورتی که این تابع کارش رو با موفقیت انجام بده مقدار 0 در فلگ CF قرار میگیره و در صورت عدم موفیت مقدار این ثبات 1 میشه. برای اینکه مطمئن بشیم که هد به سکتور صفر منتقل شده، حتماً باید بعد از اجرای تابع مقدار CF رو تست کنیم. تکه برنامه زیر این کار رو انجام میده.
                                کد:
                                 .Reset:
                                 mov ah, 0
                                 mov dl, 0
                                 int 0x13
                                 jc .Reset
                                سطر آخر این برنامه در صورت 1 بودن CF به اول برنامه پرش میکنه و دوباره تابع رو اجرا میکنه تا وقتی که مطمئن بشه حتماً هد به سکتور 0 منتقل شده.
                                تابع شماره 2H : این تابع از وقفه 13H برای خواندن از دیسک استفاده میشه. برای استفاده از این تابع باید مقادیر ثبات ها به شکل زیر تنظیم بشه.
                                AH شماره تابع که همون 0x02 هستش
                                AL تعداد سکتورهایی که قراره خونده بشه باید توی این ثبات قرار بگیره.
                                ES محل قرار گیری اطلاعات در حافظه بعد از خواندن از دیسک.
                                BX سگمنتی که قراره اطلاعات توش قرار بگیره باید تو این ثبات ذخیره بشه. از اونجایی که ما نمی خواهیم فعلاً وارد بحث سگمنت ها بشیم و این بحث ها برای مود 32 بیتی زیاد لازم نمیشه فعلاً این ثبات رو به 0 تنظیم میکنیم. یعنی اطلاعات باید تو سگمت 0 ذخیره بشه.
                                DH همونطور که میدونید هر فلاپی دو تا هد داره و این ثبات شماره هدی که باید خوندن رو انجام بده رو مشخص میکنه. در واقع ما باید از هد اول یا هد شماره 0 استفاده کنیم.
                                DL شماره درایو باید توی این ثبات قرار بگیره که برای فلاپی شماره درایو صفر میشه
                                CH شماره سیلندری که خوندن باید از اون انجام بشه توی این ثبات قرار میگیره.
                                CL این ثبات هم برای مشخص کردن شماره سکتوری که خوندن باید از اونجا شروع بشه به کار میره.
                                در مورد دو مورد آخر یه کمی توضیح بیشتر لازمه. هر دیسک ( چه فلاپی یا هارد یا CD ) از یک سری شیار تشکیل شده که اطلاعات روی اونها ذخیره میشه این شیارها (Tracks) به صورت دوایر متحدالمرکز روی دیسک قرار گرفته اند. همچنین هر دیسک ممکنه چند وجه داشته باشه مثل فلاپی که دو وجه و در نتیجه دو تا هد خوندن و نوشتن هم داره. بعضی از درایورهای هارد دیسک ممکنه چند تا دیسک داشته باشند که هر دیسک میتونه یک یا دو وجه داشته باشه در هر دو مورد به مجموعه شیارهایی که در دیسک ها و وجه های مختلف دارای شعاع یکسان هستند، یعنی روی هم قرار میگیرند یک سیلندر گفته میشه. در واقع وقتی ما شماره سیلندر رو برابر 2 و شماره هد رو برابر 1 قرار میدیم.یعنی شیار شماره دو از وجهی که هد شماره 1 قرار داره مد نظرمون هستش. بحث مفصل درباره این موضوع توی این پست نمی گنجه. توصیه می کنم اگه اطلاعات زیادی در این مورد ندارید حتماً در فرصت مناسب اطلاعاتتون در این زمینه رو بیشتر کنید. همچنین این رو هم بگم که هر شیار به تعدادی سکتور تقیسم میشه که اولین سکتور از اولین شیار از اولین وجه هر دیسکی همون سکتور راه انداز دیسک رو تشکیل میده.
                                در مورد فلاپی باید این توضیح رو بدم که هر فلاپی 3.5 اینچی و 1.44 مگابایتی در هر شیار دارای 18 سکتور و در کل حاوی 80 شیار هستش. بعد از اجرای این تابع مقدار فلگ CF مثل تابع قبلی تغییر میکنه. یعنی اگر تابع با موفقیت اجرا بشه مقدار 0 و در غیر این صورت مقدار 1 رو میگیره.
                                به تکه کد زیر توجه کنید. این برنامه ابتدا هد فلاپی رو ریست میکنه بعد یک سکتور از فلاپی رو میخونه و در آدرس 0x1000 از حافظه در سگمنت 0 قرار میده.
                                کد:
                                 .Reset:
                                 mov ah, 0
                                 mov dl, 0
                                 int 0x13
                                 jc .Reset
                                 mov ax, 0x1000
                                 mov es, ax
                                 xor bx, bx
                                 .Read:
                                 mov ah, 0x02
                                 mov al, 1
                                 mov ch, 1
                                 mov cl, 2
                                 mov dh, 0
                                 mov dl, 0
                                 int 0x13
                                 jc .Read
                                 jmp 0x1000:0x0


                                این برنامه یک سکتور از شیار شماره یک رو با شروع از سکتور شماره 2 می خونه و در حافظه قرار میده و بعد به اون قسمت از حافظه می پره و اون رو اجرا میکنه. دقت کنید که در این حالت CPU نمیتونه تشخیص بده که کد موجود در آدرس 0x1000 از حافظه قابلیت اجرایی داره یا نه و اگر این کد قابلیت اجرا شدن رو نداشته باشه سیستم ممکنه هنگ بکنه یا ریست بشه یا هر اتفاق دیگه ای ممکنه بیفته، پس بیشتر دقت کنید.
                                خب حالا اگه ما بخواهیم بجای خوندن یک سکتور از فلاپی و اجرا کردن اون یه فایل رو بخونیم و اجرا کنیم باید چه کار کنیم. چون تا اینجا همه چیز بر مبنای شماره شیار و سکتور انجام شده نه بر اساس اسم فایل، از اونجایی که یه فایل ممکنه تو هر سکتوری ذخیره شده باشه باید اول سکتور مورد نظر رو پیدا کنیم. بعد فایل رو از اون سکتور مثل مثال بالا بخونیم و اجرا کنیم. این فایل میتونه هسته سیستم عامل یا مرحله دوم برنامه بوت لودر ما باشه. در واقع بحث اصلی این پست درباره همین موضوعه و اون همون پارامترهای بلاک OEM هستش.
                                سیستم فایل FAT12
                                حتماً تا حالا در مورد سیستم های فایل مختلف و مزایا و معایب اونا چیزهایی شنیدید. معروفترین این سیستم های فایل شاید NTFS , FAT12 , FAT32 , FAT16 , ext2 , ext3 و ... باشند. سیستم فایل FAT12 مخصوص دیسک های فلاپی طراحی شده. این سیستم همونطور که از از اسمش پیداست از سیستم 12 بیتی برای آدرس دهی برای اطلاعات روی دیسک استفاده میکنه ، در نتیجه حداکثر واحد حافظه ای که میتونه بشناسه برابر با 2 به توان 12 یا 4086 واحد میشه. البته واحد حافظه روی دیسک ها با واحد حافظه روی RAM خیلی فرق داره. واحد حافظه روی دیسک کلاستر هستش که خود کلاستر از یک یا چند سکتور تشکیل میشه. تعداد سکتور ها در هر کلاستر میتونه متغیر باشه و در سیستم FAT12 این عدد بین 1 و 8 باید باشه. بنابراین اگه هر کلاستر از 8 سکتور تشکیل شده باشه، اندازه هر کلاستر 4 کیلوبایت میشه و در نتیجه با توجه به اینکه 4086 کلاستر میتونه تو این سیستم آدرس دهی بشه. پس حد اکثر ظرفیت یک دیسک با سیستم فایل FAT12 برابر با 16 مگابایت میشه که برای دیسک های فلاپی 1.44 مگابایتی کافیه. حتی اگه هر کلاستر رو برابر با 1 سکتور تعریف کنیم بازهم 2 مگابایت فضای قابل آدرس دهی داریم که برای یک فلاپی کفایت میکنه.
                                حالا یه بار دیگه نگاهی به بلاک پارامترهای OEM که تو پست قبلی بهش اشاره کرده بودیم میندازیم. حالا به اندازه کافی پیش زمینه برای درک این کدهای به ظاهر خیلی زشت رو داریم. پس کمی بیشتر واردشون میشم.
                                کد:
                                 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  "
                                دو خط اول همونطور که از اسمشون پیداست به ترتیب تعداد بایت ها در هر سکتور و تعداد سکتورها در هر کلاستر رو مشخص میکنند که نشون میده تعداد سکتورها در فلاپی ما 1 هستش که البته میشه تغییرش داد ولی توصیه میکنم این کار رو نکنید. خط سوم هم تعداد سکتورهای رزرو شده رو مشخص میکنه. منظور از سکتور رزرو شده، سکتوری هست که توی جدول FAT استفاده نمیشه و نمیشه در حالت عادی اطلاعاتش رو تغییر داد. مثلاً تو حالت عادی شما اگه وارد یک CD ویندوز که قابلیت Bootable داره بشید. تو محیط ویندوز نمی تونید فایلهای مربوط به سکتور بوت اون دیسک رو ببینید ، در مورد درایو C یا فلاپی هم که سکتور راه انداز دارند وضع به همین ترتیب هستش. در حالت عادی ویندوز یا بقیه سیستم عاملها این اجازه رو به کابر نمیدن که اطلاعات این سکتور رو تغییر بدن، ولی با برنامه های خاصی مثل partcopy میشه این کار رو انجام داد. به همین دلیله که وقتی شما تو پست قبلی بوت لودرتون رو به فلاپی منتقل کردید بعد از وارد شدن به فلاپی چیزی نمیدید. از اونجایی که ما فقط به یک سکتور برای راه اندازی احتیاج داشتیم مقدار این پارامتر رو برابر 1 قرار دادیم.
                                پارامتر بعدی تعداد جدول های FAT رو مشخص میکنه که برای فلاپی همیشه برابر 2 هست. دو پارامتر بعدی به ترتیب حداکثر دایرکتوری های موجود در ریشه درایو و تعداد کل سکتورهای درایو رو نشون میدن که برای فلاپی به ترتیب 224 و 2880 باید باشه. پارامتر بعدی، یعنی bpbMedia یک عدد هشت بیتیه که هر بیت معنی خاصی داره که توضیح میدم.
                                بیت 0 : اگه 0 باشه یعنی فلاپی یک وجهی و اگه 1 باشه یعنی دو وجهیه
                                بیت 1 : اگه 0 باشه یعنی هر جدول FAT توی 9 سکتور جا میگیره و اگه 1 باشه توی 8 سکتور
                                بیت 2 : تعداد شیارها رو نشون میده که اگه 0 باشه یعنی 80 شیار و اگه 1 باشه یعنی 40 شیار
                                بیت 3 : نشون دهنده نوع دیسک هست که اگه 0 باشه یعنی ثابته ( مثل هارد ) و اگه 1 باشه یعنی قابل جابه جاییه ( مثل فلاپی و CD )
                                بیت های 4 تا 7 : بلا استفاده هستند.
                                در اینجا ما از عدد 0xF0 = 11110000 استفاده کردیم که نشون دهنده یک دیسک جابحا شونده و تک وجهی با 80 شیار و 9 سکتور در هر FAT هست.
                                پارامتر بعدی هم همون 9 سکتور در هر FAT رو مشخص میکنه. دو پارامتر بعدی هم به ترتیب تعداد سکتورها در هر شیار و تعداد هدها در هر سیلندر رو مشخص میکنند که برابر با 18 و 2 هستند.
                                چهار پارامتر بعدی مهم نیستند و همین مقادیر رو که میبینید همیشه براشون استفاده کنید.
                                سه پارامتر بعدی هم به ترتیب شماره سریال دیسک، برچسپ یا Label دسیک و نوع سیستم فایل دیسک رو مشخص میکنند. توجه کنید که برچسب دیسک حتماً باید 11 کاراکتر و نوع سیستم فایل 8 کاراکتر باشند. به همین دلیل از جای خالی استفاده شده. خب حتمآ میپرسید حالا این چیزهایی که گفتیم چه ربطی به ماجرا داره.
                                در واقع ما برای دستیابی به فایل ها روی هر دیسکی به این پارامترها احتیاج داریم. به طور ذاتی یک درایور دیسک چه از نوع سخت، چه از نوع نرم هیچ اطلاعی از نوع فایل سیستم، سکتور راه انداز، نحوه راه اندازی سیستم ، چگونگی تشکیل فایل و... نداره. حتی یک درایور هیچ تعریفی از فایل براش نشده. درایور دیسک فقط میتونه یک سری اطلاعات رو به صورت دسته ای از بیت ها در محل های مشخصی از دیسک ذخیره کنه یا اونها رو بخونه. در واقع این برنامه نویس هست که به CPU میفهمونه منظورش از یک فایل یا دایرکتوری چیه و تمام این مفاهیم قبل از استفاده به اون شکلی که مثلاً توی ویندوز دیدید باید توسط سیستم عامل تعریف بشه. مهمترین چیزی که برای تعریف مفهوم فایل به درد ما میخوره همین پارامترهای بلاک OEM هستش.
                                [glow=red,2,300]تاپیک های ایجاد شده[/glow]

                                دیدگاه

                                لطفا صبر کنید...
                                X