天天看點

第4章 讓作業系統走進保護模式

按着書上給的代碼打進去後,把tasm裝進虛拟機後,要注意一下的是:它選擇的不是安裝路徑,而是源檔案的盤。

還有在虛拟機運作中,老是出現NOLoad,為什麼找不到loader.bin呢?排錯排了很久,最後使用老辦法,發現是定義

LoaderFileName    db  "LOADER  BIN", 0;

LoaderFileName    db  "LOADER  BIN", 0 ;

我還真搞不清楚這兩個定義有那裡不同,但就是用CD光牒上的代碼的時候,才可以運作找到loader。why?

實在太奇怪了。

發現用debug調試.bin的時候,到13h程式就不能走下去了。就算我把軟碟加載進去了,也不行。

代碼:

%define _BOOT_DEBUG_

%ifdef _BOOT_DEBUG_

 org 0100h

%else

 org 07c00h

%endif

%ifdef _BOOT_DEBUG

 BaseOfStack equ 0100h

%else

 BaseOfStack equ 07c00h

%endif

BaseOfLoader  equ  09000h;Loader.bin ±»¼ÓÔص½µÄλÖ᪡ª¶ÎµØÖ·

OffsetOfLoader  equ  0100h ;Loader.bon ±»¼ÓÔص½µÄλÖ᪡ªÆ«ÒƵØÖ·

RootDirSectors  equ  14  ;¸ùĿ¼ռÓõĿռä

SectorNoOfRootDirectory  equ  19  ;Root Directory µÄµÚÒ»¸öÉÈÇøºÅ

SectorNoOfFAT1  equ  1; FAT1µÄµÚÒ»¸öÉÈÇøºÅ£¨=BPB_RsvdSecCnt£©

DeltaSectorNo  equ  17

jmp short LABEL_START

nop; Õâ¸ö nop ²»¿ÉÉÙ

;ÏÂÃæÊÇFAT12´ÅÅ̵ÄÍ·

BS_OEMName  db  'ForrestY'   ;OEM String,±ØÐëÊÇ8×Ö½Ú

BPB_BytsPerSec DW  512     ;ÿÉÈÇø×Ö½ÚÊý

BPB_SecPerClus DB  1      ;ÿ×å¶àÉÙÉÈÇø

BPB_RsvdSecCnt DW  1      ;Boot ¼Ç¼ռÓöàÉÙÉÈÇø

BPB_NumFATs  DB  2      ;¹²ÓжàÉÙ FAT ±í

BPB_RootEntCnt DW  224     ;¸ùĿ¼ÎļþÊý×î´óÖµ

BPB_TotSec16 DW  2880     ;Âß¼­ÉÈÇø×ÜÊý

BPB_Media  DB  0xF0     ;ýÌåÃèÊö·û

BPB_FATSz16  DW  9      ;ÿFATÉÈÇøÊý

BPB_SecPerTrk DW  18      ;ÿ´ÅµÀÉÈÇøÊý

BPB_NumHeads DW  2      ;´ÅÍ·Êý£¨ÃæÊý£©

BPB_HiddSec  DW  0      ;Òþ²ØÉÈÇøÊý

BPB_TotSec32 DD  0      ;Èç¹û wTotalSectorCountÊÇ0£¬ÓÉÕâ¸öÖµ¼Ç¼ÉÈÇøÊý

BS_DrvNum  DB  0      ;ÖжÏ13 µÄÇý¶¯Æ÷ºÅ

BS_Rservedl  DB  0      ;δʹÓÃ

BS_BootSig  DB  29h  ; À©Õ¹Òýµ¼±ê¼Ç£¨29h£©

BS_VolID   DD  0  ;  ¾íÐòÁкÅ

BS_VolLab  DB  'Tinix0.01  '; ¾í±ê£¬±ØÐë11×Ö½Ú

BS_FileSysType DB  'FAT12   ' ; ÎļþϵͳÀàÐÍ£¬±ØÐë8×Ö½Ú

LABEL_START:

mov ax, cs

mov ds, ax

mov es, ax

mov ss, ax

mov sp, BaseOfStack

xor ah, ah

xor dl, dl

int 13h

;ÏÂÃæ ÔÚAÅ˵ĸùĿ¼ѰÕÒ Loader.bin

mov word [wSectorNo], SectorNoOfRootDirectory

LABEL_SEARCH_IN_ROOT_DIR_BEGIN:

 cmp word [wRootDirSizeForLoop], 0

 jz  LABEL_NO_LOADERBIN

 dec word [wRootDirSizeForLoop]

 mov ax, BaseOfLoader

 mov es, ax

 mov bx, OffsetOfLoader

 mov ax, [wSectorNo]

 mov cl, 1

 call ReadSector

 mov si, LoaderFileName

 mov di, OffsetOfLoader

 cld ;×÷Óã¿

 mov dx, 10h

LABEL_SEARCH_FOR_LOADERBIN:

 cmp dx, 0

 jz  LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR

 dec dx

 mov cx, 11

LABEL_CMP_FILENAME:

 cmp cx, 0

 jz  LABEL_FILENAME_FOUND

 dec cx

 lodsb

 cmp al, BYTE [es:di]

 jz  LABEL_GO_ON

 jmp LABEL_DIFFERENT

LABEL_GO_ON:

 inc di

 jmp LABEL_CMP_FILENAME

LABEL_DIFFERENT:

 and di, 0FFE0H

 add di, 20h

 mov si, LoaderFileName

 jmp LABEL_SEARCH_FOR_LOADERBIN

LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:

 add word [wSectorNo], 1

 jmp LABEL_SEARCH_IN_ROOT_DIR_BEGIN

LABEL_NO_LOADERBIN:

 mov dh, 2

 call DispStr

%ifdef _BOOT_DEBUG_

 mov ax, 4c00h

 int 21h

%else

 jmp $

%endif

LABEL_FILENAME_FOUND:

 mov ax, RootDirSectors

 and di, 0ffe0h

 add di, 01ah

 mov cx, word [es:di]

 push cx

 add cx, ax

 add cx, DeltaSectorNo

 mov ax, BaseOfLoader

 mov es, ax

 mov bx, OffsetOfLoader

 mov ax, cx

LABEL_GOON_LOADING_FILE:

 push ax

 push bx

 mov ah, 0Eh

 mov al, '.'

 mov bl, 0fh 

 int 10h

 pop bx

 pop ax

 mov cl, 1

 call ReadSector

 pop ax

 call GetFATEntry

 cmp ax, 0FFFH

 jz  LABEL_FILE_LOADED

 push ax

 mov dx, RootDirSectors

 add ax, dx

 add ax, DeltaSectorNo

 add bx, [BPB_BytsPerSec]

 jmp LABEL_GOON_LOADING_FILE

LABEL_FILE_LOADED:

 jmp BaseOfLoader:OffsetOfLoader

;***************************************

;********************************

wRootDirSizeForLoop  dw  RootDirSectors

wSectorNo     dw  0

bOdd       db  0

;LoaderFileName    db  "LOADER BIN", 0;0   loader.bin

LoaderFileName    db  "LOADER  BIN", 0 ;

MessageLength    equ 9

BootMessage:    db  "Booting  "

Message1      db  "Ready.   "

Message2      db  "No LOADER"

;*********************************

;ReadSector

;********************************

ReadSector:

 push bp

 mov bp, sp

 sub esp, 2

 mov byte [bp -2], cl

 push bx

 mov bl, [BPB_SecPerTrk]

 div bl

 inc ah  ;Z++

 mov cl, ah

 mov dh, al

 shr al, 1

 mov ch, al

 and dh, 1

 pop bx

 mov dl, [BS_DrvNum]

.GoOnReading:

 mov ah, 2

 mov al, BYTE [bp -2]

 int   13h

 jc  .GoOnReading

 add esp, 2

 pop bp

 ret

;*******End of ReadSector

;**********************

;DispStr

DispStr:

 mov ax, MessageLength

 mul dh

 add ax, BootMessage

 mov bp, ax

 mov ax, ds

 mov es, ax

 mov cx, MessageLength

 mov ax, 01301h

 mov bx, 0007h

 mov dl, 0

 int 10h

 ret

;***End of DispStr

;;****************************

;GetFATEntry

GetFATEntry:

 push es

 push bx

 push ax

 mov ax, BaseOfLoader

 sub ax, 0100h

 mov es, ax

 pop ax;  mov byte [bOdd], 0

 mov bx, 3

 mul bx

 mov bx, 2

 div bx

 cmp dx, 0

 jz  LABEL_EVEN

 mov byte [bOdd], 1

LABEL_EVEN:

 xor dx, dx

 mov bx, [BPB_BytsPerSec]

 div bx

 push dx

 mov bx, 0

 add ax, SectorNoOfFAT1

 mov cl, 2

 call ReadSector

 pop dx

 add bx, dx

 mov ax, [es:bx]

 cmp byte [bOdd], 1

 jnz LABEL_EVEN_2

 shr ax, 4

LABEL_EVEN_2:

 and ax, 0FFFH

LABEL_GET_FAT_ENRY_OK:

 pop bx

 pop es

 ret

;End of GetFATEntry

times  510-($-$$) db 0 ; Ìî³äʣϵĿռ䣬ʹÉú³ÉµÄ¶þ½øÖÆ´úÂëÇ¡ºÃΪ512×Ö½Ú

dw  0xaa55    ;