codefans

          導(dǎo)航

          <2008年10月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          程序設(shè)計(jì)鏈接

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          [開發(fā)教程][原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)算機(jī)

          預(yù)備知識(shí):
            匯編語(yǔ)言、能讀懂NASM語(yǔ)法、了解BIOS 中斷INT0x10, INT 0x16,虛擬機(jī)的使用

          涉及工具:
            NASM,一個(gè)文本編輯器(我用的是ConText + NASM語(yǔ)法高亮)

          前言:
            第一次寫教程,不知道能拿多少分。

            “怎樣開始寫自己的操作系統(tǒng)”可能是不少有“非分想法”的愛(ài)好者來(lái)說(shuō)是一個(gè)難題,在我的大學(xué)課程《計(jì)算機(jī)操作系統(tǒng)教程》以教程的形式充分說(shuō)明了操作系統(tǒng)的原理,這本書會(huì)告訴你各個(gè)環(huán)節(jié)的原語(yǔ);所謂“原理”就指理論上的東西,實(shí)際上我們并不知道操作系統(tǒng)是如何工作的。為了不至于讓有這個(gè)非分想法的朋友不至于放棄,這篇日志就帶你走進(jìn)操作系統(tǒng)開發(fā)的殿堂。

          一、操作系統(tǒng)是如何啟動(dòng)的?

            首先讓我們來(lái)看看計(jì)算機(jī)的啟動(dòng)過(guò)程,這里我摘抄了一些東西:

            “首先讓我們來(lái)了解一些基本概念。第一個(gè)是大家非常熟悉的BIOS(基本輸入輸出系統(tǒng)),BIOS是直接與硬件打交道的底層代碼,它為操作系統(tǒng)提供了控制硬件設(shè)備的基本功能。BIOS包括有系統(tǒng)BIOS(即常說(shuō)的主板BIOS)、顯卡BIOS和其它設(shè)備(例如IDE控制器、SCSI卡或網(wǎng)卡等)的BIOS,其中系統(tǒng)BIOS是本文要討論的主角,因?yàn)橛?jì)算機(jī)的啟動(dòng)過(guò)程正是在它的控制下進(jìn)行的。BIOS一般被存放在ROM(只讀存儲(chǔ)芯片)之中,即使在關(guān)機(jī)或掉電以后,這些代碼也不會(huì)消失。

            “第二個(gè)基本概念是內(nèi)存的地址,我們的機(jī)器中一般安裝有32MB、64MB或128MB內(nèi)存,這些內(nèi)存的每一個(gè)字節(jié)都被賦予了一個(gè)地址,以便CPU訪問(wèn)內(nèi)存。32MB的地址范圍用十六進(jìn)制數(shù)表示就是0~1FFFFFFH,其中0~FFFFFH的低端1MB內(nèi)存非常特殊,因?yàn)樽畛醯?086處理器能夠訪問(wèn)的內(nèi)存最大只有1MB,這1MB的低端640KB被稱為基本內(nèi)存,而A0000H~BFFFFH要保留給顯示卡的顯存使用,C0000H~FFFFFH則被保留給BIOS使用,其中系統(tǒng)BIOS一般占用了最后的64KB或更多一點(diǎn)的空間,顯卡BIOS一般在C0000H~C7FFFH處,IDE控制器的BIOS在C8000H~CBFFFH處。”

            (以上引自:http://article.pchome.net/2003/09/25/13022.htm

          二、進(jìn)一步了解引導(dǎo)的關(guān)鍵所在

            計(jì)算機(jī)啟動(dòng)的第一個(gè)過(guò)程由BIOS完成,它做了什么工作是不我們不必理會(huì)的,我們也管不了那它;關(guān)鍵在于:BIOS完成設(shè)備檢查、初始化、更新之后,根據(jù)預(yù)先設(shè)定的引導(dǎo)設(shè)備順序檢查可以引導(dǎo)的設(shè)備,比如我們?cè)O(shè)置啟動(dòng)順序?yàn)?:Floppy(軟驅(qū))2:HDD1(硬盤1) 3:CD-ROM(光驅(qū)),那么,BIOS會(huì)從軟驅(qū)開始查找是否可以啟動(dòng),如果軟驅(qū)失敗,則會(huì)去找HDD1,......
            那么,BIOS如何知道軟盤或硬盤能不能引導(dǎo)呢?這個(gè)把戲的關(guān)鍵在于:每個(gè)可引導(dǎo)設(shè)備都有一個(gè)512字節(jié)的設(shè)備頭,如果這個(gè)設(shè)備可引導(dǎo),最后兩個(gè)字節(jié)必須為0x55(低),0xAA(高),如果BIOS找到這個(gè)標(biāo)志,就會(huì)將這512字節(jié)(注意:只有512字節(jié))讀到內(nèi)存的0x0000:0x7C00,然后將控制權(quán)轉(zhuǎn)交給(跳到)0x0000:0x7C00的程序,這就意味著:如果我們將軟盤的第一個(gè)扇區(qū)最后兩個(gè)字節(jié)打上"0x55,0xAA"的標(biāo)志,這個(gè)軟盤就可以啟動(dòng)了!當(dāng)然,BIOS不會(huì)知道你這個(gè)引導(dǎo)程序是不是有效的,它只認(rèn)0x55,0xAA。

            好了,我們知道寫自己第一個(gè)引導(dǎo)程序的關(guān)鍵在于: 
            1. 一個(gè)兩字節(jié)(一個(gè)字長(zhǎng))的引導(dǎo)標(biāo)志 0x55,0xAA
            2. 引導(dǎo)程序必須占512字節(jié)

          三、看看實(shí)例

            代碼用NASM編譯:nasmw -f bin boot.asm -o boot.bin
            解釋一下上面的命令:在M$命令提示行下編譯,-f bin 表示編譯為純二進(jìn)制文件(我們不需要任何文件頭),-o boot.bin 編譯。

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ; boot.asm
          ; A demo to show how bootsect works
          ; Last modified:2005-4-3 10:57:45
          ; Copyright (c) 2005,E-mean X.
          ;
          ; This program is released under GPL,See document for details
          ; You can use this code anywhere you want in condition keep autor's info
          ; original
          ;
          ; Author: E-mean X.
          ; Contact: xemean@sina.com
          ; Website: http://www.xemean.net/
          ; April,02,2005
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          bits 16         ; 偽指令,告訴編譯器這是 16位代碼
          org 0x7C00      ; 偽指令,告訴編譯器這段代碼由0x0:0x7C00開始
          ;===========================================================================
          ; 程序執(zhí)行的第一條指令必須是跳轉(zhuǎn)(如果你想使用FAT12這類文件系統(tǒng)的磁盤)
          ; 必須占用3字節(jié)
          ;===========================================================================
          jmp SHORT main ; 2 bits,跳轉(zhuǎn)到主程序執(zhí)行
          nop            ; 1 bit
          ;===========================================================================
          ; FAT12 文件系統(tǒng)頭,從NYAOS 借過(guò)來(lái)的,可以參考相關(guān)的文檔以獲得更多細(xì)節(jié)
          ; 這個(gè)塊會(huì)讓 Winimage 認(rèn)出編譯后的二進(jìn)制文件為有效的引導(dǎo)文件
          ; 如果不使用這個(gè)塊,Winimage將不會(huì)將其作為引導(dǎo)程序處理
          ; 但我們可以借助其它方法和工具處理,比如DEBUG
          ;===========================================================================
          bsOEM       db "ExOS0.01"               ; OEM String,任意你喜歡的8字節(jié)ASCII碼
          bsSectSize  dw 512                      ; Bytes per sector
          bsClustSize db 1                        ; Sectors per cluster
          bsRessect   dw 1                        ; # of reserved sectors
          bsFatCnt    db 2                        ; # of fat copies
          bsRootSize  dw 224                      ; size of root directory
          bsTotalSect dw 2880                     ; total # of sectors if < 32 meg
          bsMedia     db 0xF0                     ; Media Descriptor
          bsFatSize   dw 9                        ; Size of each FAT
          bsTrackSect dw 18                       ; Sectors per track
          bsHeadCnt   dw 2                        ; number of read-write heads
          bsHidenSect dd 0                        ; number of hidden sectors
          bsHugeSect  dd 0                        ; if bsTotalSect is 0 this value is
                                                  ; the number of sectors
          bsBootDrv   db 0                        ; holds drive that the bs came from
          bsReserv    db 0                        ; not used for anything
          bsBootSign  db 29h                      ; boot signature 29h
          bsVolID     dd 0                        ; Disk volume ID also used for temp
                                                  ; sector # / # sectors to load
          bsVoLabel   db "NO NAME    "            ; Volume Label
          bsFSType    db "FAT12   "               ; File System type <- FAT 12文件系統(tǒng)
          ;===========================================================================
          ; Main start here
          ;===========================================================================
          main:
               cli  ; 關(guān)閉可屏蔽中斷,以備我們接下來(lái)初始化寄存器的工作
               mov  ax,cs ; 將代碼段傳給ax,實(shí)模式下,代碼段與數(shù)據(jù)段沒(méi)什么分別
               mov  ds,ax ; 數(shù)據(jù)段寄存器,實(shí)際上都是0
               mov  es,ax ; 附加段
               mov  ax,ss ; 堆棧段
               mov  sp,0x7C00-1   ; 堆棧指針,指向0x7BFF
               sti  ; 基本工作已經(jīng)完成,開放中斷

               ;
               mov  si,msgHello ; 使 si指向 "Hello World!"字符串
               call printStr    ; 調(diào)用顯示子程序
              
               mov  si,fixLine  ; 回車換行
               call printStr
              
               mov  si,msgMore  ; 顯示更多信息
               call printStr

               ; Mission complete,take a break
               .loop:
               xor  ax,ax       ; ax 清0
               int  0x16        ; 調(diào)用int 16h 讀取鍵盤輸入

          ; 重啟計(jì)算機(jī)
          ;     mov  ax,0x40
          ;     mov  ds,ax
          ;     xor  ax,ax
          ;     mov  [0x0072],ax  ; 向 0x40:0x72寫0后再跳到_
          ;     jmp  0xFFFF:0x0    ; 0xFFFF:0x0 可以實(shí)現(xiàn)重啟

               jmp  .loop       ; 跳轉(zhuǎn)到 .loop,什么也不做了

          ;------- END OF MAIN ----------------

          ;===========================================================================
          ; printStr
          ; sub function for print a string to screen by INT 10H
          ; 入口:ds:si = 指向目標(biāo)字符串
          ; 返回:無(wú)
          ;===========================================================================
          printStr:
               push si  ; 保護(hù)寄存器
               push ax
               push bx

                    cld    ; 清除進(jìn)位標(biāo)志位,這個(gè)標(biāo)志位會(huì)影響 si 的遞增方向
                    mov  ah,0x0E    ; int 0x10 子功能號(hào),顯示字符,參看相關(guān)資料以獲得細(xì)節(jié)
                    mov  bx,0x0007  ; 頁(yè)號(hào)0,字符前景色 7,淺灰色,試著改變這個(gè)數(shù)值
                                    ; 會(huì)給你的文字增添色彩
               .nextChar:
                    lodsb           ; [si] -> al,取一個(gè)字節(jié)碼
                    or  al,al       ; 如果取得的字節(jié)是0,則表示字符串結(jié)束
                    jz  .OK         ; 退出
                    int 0x10        ; 調(diào)用BIOS int 10h 中斷
                    jmp .nextChar   ; 繼續(xù)下一個(gè)字符,直到遇到0
               .OK:
               pop  bx ; 恢復(fù)寄存器
               pop  ax
               pop  si
               ret     ; 返回調(diào)用程序
          ;------- END OF printStr --------------

          ; data area

          msgHello db 'Hello World!',0          ; 以物理 0結(jié)束
          msgMore  db 'Wow,my FIRST boot sector!',0
          fixLine  db 13,10,0   ; 回車,換行的ASCII碼

          ; 引導(dǎo)程序必須為512字節(jié),不用的地方以0填充
            times 510-($-$$) db 0            ; $表示程序當(dāng)前位置,$$表示程序開始位置,由編譯器自動(dòng)計(jì)算
           
          BOOT_SIGN     DW 0xAA55            ; 最后兩個(gè)字節(jié)為引導(dǎo)標(biāo)志55AA

          ;--------------------------- End of this programme --------------------------------------

          編譯成功之后,會(huì)生成一個(gè)512字節(jié)的boot.bin,用Winimage創(chuàng)建一個(gè)新的軟盤,在“Options(選項(xiàng))”菜單里,"Winimage mode selection ..." 選擇“WinImage Professional mode(專家模式)”(如果不選專家模式,將不能進(jìn)行引導(dǎo)扇區(qū)的編輯),之后,"Image-> Boot Sector Properties"(映像->引導(dǎo)扇區(qū)屬性)中,將引導(dǎo)扇區(qū)改為你剛才編譯的程序,保存,用Vmware/Qemu/Bochs之類的虛擬機(jī)工具試試你的啟動(dòng)盤吧!引導(dǎo)成功

          發(fā)揮你的想像力,讓你的引導(dǎo)程序?qū)崿F(xiàn)更多的功能!

          -----------------------------------------------------------

          E-mean X.
          April,03,2005

          轉(zhuǎn)載請(qǐng)說(shuō)明作者及出處


          閱讀全文(787) | 回復(fù)(5) | 引用(24)
           


          回復(fù):[原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)
          xemean發(fā)表評(píng)論于2005-8-15 19:59:11

          文件系統(tǒng)基本上可認(rèn)為是文件在磁盤上的組織形式,由操作系統(tǒng)管理文件系統(tǒng),比如MS$系統(tǒng)就用過(guò)FAT12、FAT16、FAT32、NTFS...,Linux有EXT等等,這東西不是幾個(gè)字就可以說(shuō)清楚的,還需要看相關(guān)的資料。

          操作系統(tǒng)基于文件系統(tǒng)來(lái)管理文件,比如讀、寫和修改文件,磁盤從物理上以CHS來(lái)定位文件(目前大硬盤有LBA模式),我們?cè)趹?yīng)用中當(dāng)然不可能通過(guò)CHS來(lái)定位文件,應(yīng)用中,我們通過(guò)一個(gè)路徑來(lái)標(biāo)識(shí)一個(gè)文件,比如c:\boot.ini、/boot/grub/grub.conf,這是文件系統(tǒng)的一個(gè)基本功能。


          個(gè)人主頁(yè) | 引用 | 返回
           


          回復(fù):[原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)
          11(游客)發(fā)表評(píng)論于2005-7-9 11:54:21
          我想問(wèn)的就是說(shuō)文件系統(tǒng)是什么概念呢?引導(dǎo)程序原理我是看懂了 請(qǐng)指教

          個(gè)人主頁(yè) | 引用 | 返回
           


          回復(fù):[原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)
          你好(游客)發(fā)表評(píng)論于2005-7-9 11:30:16

          你們這么一回 我有點(diǎn)暈了 這里可以去除FAT12的文件系統(tǒng)嗎? 文件系統(tǒng)啟到什么作用?我有點(diǎn)把文件系統(tǒng)和引導(dǎo)程序弄混了,還請(qǐng)指教!

          ;===========================================================================
          bsOEM       db "ExOS0.01"               ; OEM String,任意你喜歡的8字節(jié)ASCII碼
          bsSectSize  dw 512                      ; Bytes per sector
          bsClustSize db 1                        ; Sectors per cluster
          bsRessect   dw 1                        ; # of reserved sectors
          bsFatCnt    db 2                        ; # of fat copies
          bsRootSize  dw 224                      ; size of root directory
          bsTotalSect dw 2880                     ; total # of sectors if < 32 meg
          bsMedia     db 0xF0                     ; Media Descriptor
          bsFatSize   dw 9                        ; Size of each FAT
          bsTrackSect dw 18                       ; Sectors per track
          bsHeadCnt   dw 2                        ; number of read-write heads
          bsHidenSect dd 0                        ; number of hidden sectors
          bsHugeSect  dd 0                        ; if bsTotalSect is 0 this value is
                                                  ; the number of sectors
          bsBootDrv   db 0                        ; holds drive that the bs came from
          bsReserv    db 0                        ; not used for anything
          bsBootSign  db 29h                      ; boot signature 29h
          bsVolID     dd 0                        ; Disk volume ID also used for temp
                                                  ; sector # / # sectors to load
          bsVoLabel   db "NO NAME    "            ; Volume Label
          bsFSType    db "FAT12   "               ; File System type <- FAT 12文件系統(tǒng)
          ;===========================================================================

          您這一段是干什么用的? 還有我有個(gè)問(wèn)題文件系統(tǒng)是實(shí)質(zhì)存在?還是我們邏輯存在的?由誰(shuí)管理呢?我看了很多天這文章和其他東西。搞不清楚~還請(qǐng)多多指教!


          個(gè)人主頁(yè) | 引用 | 返回
           


          回復(fù):[原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)
          xemean發(fā)表評(píng)論于2005-4-8 20:42:31

          To WY.lslrt:

          呵呵,的確,我忽略了這一點(diǎn)。

          謝謝提醒。


          個(gè)人主頁(yè) | 引用 | 返回
           


          回復(fù):[原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)
          WY.lslrt(游客)發(fā)表評(píng)論于2005-4-8 18:27:08

          小謝:

            硬盤的引導(dǎo)代碼不能是510字節(jié)吧,因?yàn)閺?/P>

          0x1BE-0x1FD是硬盤的基本分區(qū)表啊,這可是64字節(jié)啊

          posted on 2005-09-14 00:22 春雷的博客 閱讀(474) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: [開發(fā)教程][原創(chuàng)] 操作系統(tǒng)DIY - 啟動(dòng)你的計(jì)算機(jī) 2008-10-06 01:33 思維機(jī)器

          原來(lái)也有同樣的愛(ài)好者!

          我也寫過(guò)。。。很簡(jiǎn)單的功能
          沒(méi)有用什么工具,資料也不足,只能從軟盤啟動(dòng)。
          還需要寫保護(hù)模式下的代碼編譯程序。。。。巨大的工程。。。沒(méi)時(shí)間。。沒(méi)精力,更沒(méi)希望。
          大家多努力
            回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 吉隆县| 玉山县| 岑溪市| 铁岭县| 左云县| 平原县| 黔南| 溧水县| 巫山县| 文山县| 石泉县| 东乌| 南宁市| 茌平县| 融水| 蒲江县| 全椒县| 凤城市| 纳雍县| 星子县| 自贡市| 定远县| 前郭尔| 胶州市| 永靖县| 浦城县| 大埔县| 新平| 乌拉特前旗| 六枝特区| 怀集县| 凤山县| 铜川市| 桑日县| 普洱| 麟游县| 遵义市| 寿宁县| 九江县| 呼和浩特市| 邵武市|