随笔-65  评论-68  文章-4  trackbacks-0

今天的程序编写倒不是很长时间,但是DEBUG花了我好长时间,具体前几次崩溃的原因没有找出来,但是最终可以运行了。
截个图片,然后是汇编程序。



org 0x100
[bits 16]
jmp loaderStart

_GRAPH_SEG_OFFSET_ equ 0xb800

_RootEntCnt_ equ 0xe0

BS_OEMName db 'XXXXXXXX'
BPB_BytsPerSec dw 0x200
BPB_SecPerClus db 1
BPB_RsvdSecCnt dw 1
BPB_NumFATs db 2
BPB_RootEntCnt dw _RootEntCnt_
BPB_totSec16 dw 0xb40
BPB_Media db 0xf0
BPB_FATSz16 dw 9
BPB_SecPerTrk dw 0x12
BPB_NumHeads dw 2
BPB_HiddSec dd 0
BPB_totSec32 dd 0
BS_DrvNum db 0
BS_Reserved1 db 0
BS_BootSig db 0x29
BS_VolID dd 0
BS_VolLab db '11111111111'
BS_FileSysType db 'FAT12   '

parameters:
 screenPo dd 0
 STR_LEN equ 12
 bootStr db 'Loading...  '
 noLoaderStr db 'No Kernel...'
 ready db 'Ready       '
 KernelBase equ 0x8000
 KernelOffset equ 0x0
 rootEntryNum db _RootEntCnt_
 loaderName db 'KERNEL  BIN'


loaderStart:
 mov ax,cs
 mov ds,ax
 mov es,ax
 mov ss,ax
 mov sp,0100
 mov ax,_GRAPH_SEG_OFFSET_
 mov gs,ax
 
 mov dh,0
 call displayStr
 
 xor ah,ah
 mov dl,[BS_DrvNum]
 int 0x13
 
 mov ax,KernelBase
 mov es,ax
 mov bx,0
 mov ax,19
 mov cl,14
 call readSector
 
 
 xor edi,edi
 
anotherFile:
 xor esi,esi
 cmp byte [rootEntryNum],0
 je noLoader
 
nextChar:
 mov al,byte [es:edi]
 cmp byte [ds:loaderName+si],al
 jne notThisFile
 cmp si,10
 je found
 inc esi
 inc edi
 jmp nextChar
 
 notThisFile:
 shr edi,5
 inc edi
 shl edi,5
 dec byte [rootEntryNum]
 jmp anotherFile
 
noLoader:
 mov dh,1
 call displayStr
 jmp $
 
found:
 mov dh,2
 call displayStr
 
 mov ax,word [es:edi+(0x10)]
 mov cl,1
 
 push ax
 mov ax,KernelBase
 mov es,ax
 mov ebx,KernelOffset
 pop ax
 
 readEntry:
 
 cmp ax,0xfff
 je readEnd
 push ax
 add ax,19+14-2
 call readSector
 pop ax
 
 add ebx,512
 call getFATEntry
 
 jmp readEntry
 readEnd:
 
 jmp toProtectMode

displayStr:
 ; dh: String index
 push cx
 push ax
 push bx
 push esi
 push edi
 mov cx,STR_LEN
 mov edi,dword [screenPo]
 mov esi,bootStr
 xor eax,eax
 mov al,dh
 mov bl,STR_LEN
 mul bl
 add esi,eax
 .1:
 lodsb
 mov [gs:edi],al
 inc edi
 inc edi
 loop .1
 
 mov dword [screenPo],edi
 pop edi
 pop esi
 pop bx
 pop ax
 pop cx
 ret

readSector: ;ax: starting sector cl:number of sectors
 ; ah 0x2          al:number of sector to read
 ;      bx: es:bx
 ; ch:cylinder   cl:start sector
 ; dh:head num   dl:Drive
 push bp
 mov bp,sp
 push cx
 push dx
 push ax
 
 mov dl,[BPB_SecPerTrk]
 div dl
 mov cl,ah
 inc cl
 
 mov ch,al
 shr ch,1
 
 mov dh,al
 and dh,1
 
 mov dl,byte [BS_DrvNum]
 
 .1:
 mov ah,2
 mov al,byte [bp-2]
 int 0x13
 jc .1
  
 pop ax
 pop dx
 pop cx
 pop bp
 ret
 
getFATEntry:
 FATBaseInMem equ 0x7000
 ;ax is the entry number
 ;return ax is the next entry
 
 push es
 push bx
 push dx
 push cx
 
 mov bx,FATBaseInMem
 mov es,bx
 
 mov bx,3
 mul bx ;dx:ax
 mov bx,2
 div bx ;dx is the rest
 push dx
 
 xor dx,dx
 mov bx,[BPB_BytsPerSec]
 div bx
 mov cl,2
 xor bx,bx
 add ax,1
 call readSector
 mov bx,dx; mov byte index
 
 pop dx
 xor ax,ax
 cmp dx,0
 jne oddPart
 

 mov ax,word [es:bx]
 and ax,0x0fff
 
 jmp after
 oddPart:
 
 mov ax,word [es:bx]
 shr ax,4


 after:
 pop cx
 pop dx
 pop bx
 pop es
 
 ret
 
 
toProtectMode:
 jmp start
 
%macro Descriptor 3
 dw %2 & 0xffff
 dw %1 & 0xffff
 db (%1 >> 16) & 0xff
 dw ((%2 & 0x0f0000) >> 8) | (%3 & 0xf0ff)
 db (%1 >> 24) & 0xff
%endmacro

DummyGDT: Descriptor 0,0,0
CodeGDT: Descriptor 0,0xfffff,1100000010011010b
DataGDT: Descriptor 0,0xfffff,1000000010010010b
ScreenGDT: Descriptor 0xb8000,0xffff,0000000010010010b

GDTPtr dw $-DummyGDT-1
 dd 0x9000*0x10+DummyGDT

CodeSelector equ CodeGDT-DummyGDT
DataSelector equ DataGDT-DummyGDT
ScreenSelector equ ScreenGDT-DummyGDT

start:
 call killMotor
 cli
 mov dh,2
 call displayStr
 
 lgdt [GDTPtr]
 
 in al,0x92
 or al,10b
 out 0x92,al
 
 mov eax,cr0
 or eax,1
 mov cr0,eax
 
 jmp dword CodeSelector:(0x9000*0x10+ProtectMode)

killMotor:
 push dx
 mov dx,0x3f2
 mov al,0
 
 out dx,al
 pop dx
 ret


[bits 32]
ProtectMode:
 mov ax,ScreenSelector
 mov gs,ax
 xor edi,edi
 .again:
 inc byte [gs:edi]
 jmp .again

posted on 2007-01-18 16:22 小爽 阅读(728) 评论(5)  编辑  收藏 所属分类: 我的经验我的操作系统

评论:
# re: 今天的Loader实验总算DEBUG完成[未登录] 2007-03-14 14:41 | Sam
请教个问题:
我在Virtual PC 上安装了DOS7.1。 然后把一个于渊chapter3/a/pmtest1.com放在上面运行。结果出错。
我发现是在lgdt那句的问题。 你有什么建议吗?
我的MSN:sam_code@hotmail.com  回复  更多评论
  
# re: 今天的Loader实验总算DEBUG完成 2007-03-14 15:17 | wilson
@Sam
应该是因为DOS版本太高的缘故吧。一般都是用DOS 6.22。安装一下DOS6.22试一下。
这仅仅是猜测啊。因为很有可能微软的DOS7能够进入使用保护模式了。  回复  更多评论
  
# re: 今天的Loader实验总算DEBUG完成 2008-05-16 12:45 | guapibai
@wilson
你是不是单步调试了阿,如果是的话可能有问题,还有最好dos5.0进行实验。  回复  更多评论
  
# re: 今天的Loader实验总算DEBUG完成[未登录] 2008-12-12 10:49 | st
那是因为在DOS下只能实现实模式,不能跳转到保护模式
解决方法:
将pmtest1.asm编译成.bin文件放在引导盘上运行.  回复  更多评论
  
# re: 今天的Loader实验总算DEBUG完成[未登录] 2010-08-23 21:54 | YBW
那段代码本就没有返回DOS的语句!!!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: