这几天看了下下操作系统方面的书,然后自己写了一段,与书上有些不同。汇编不熟,英语很烂,内存使用也不合理,但总归自己写的,放上来记录一下~
org 0x7c00
;===================================================
;Constants
LoaderBaseAddr equ 0100h
FATEntryAddr equ 0500h
RootDirEntriesAddr equ 0900h
;===================================================
jmp short start
nop
;Fat12 filesystem description
db 'Weper '
dw 0x200
db 1
dw 1
db 2
dw 224
dw 2880
db 0xf0
dw 0x9
dw 0x12
dw 2
dd 0
dd 0
db 0
db 0
db 0x29
dd 0
dd "Floppy "
dd "FAT12 "
start:
mov ax,cs
mov ds,ax
mov es,ax
;clear screen
mov ax,0700h
mov cx,0000h
mov dx,0184fh
mov bh,07h
int 10h
mov ax,Message1
mov cx,14
mov dx,0
call DispStr ;Print "Now booting..."
;Read sectors of root directory
mov ax,RootDirEntriesAddr
mov es,ax
mov bx,0 ;set cache address as 0900:0h
mov ax,020dh ;Read 14 sectors of root directory
mov cx,0002h
mov dx,0100h
int 13h
;find boot.bin
mov ax,0
mov es,ax
mov ax,Message2
mov cx,17
mov dx,0100h
call DispStr ;Print "Finding Loader..."
mov ax,RootDirEntriesAddr
mov ds,ax
mov di,filename
xor si,si
mov cx,224 ;Loop for 224(root directory entry times) times
cld ;set "D flag"'s direction as forward
findfile:
dec cx
cmp cx,0
jz Loader_Not_Find
mov dx,11
Match_Continue:
lodsb ;mov ds:si to al
cmp al,[es:di]
jnz Filename_Unmatch
inc di
dec dx
cmp dx,0
jz Loader_Find
jmp Match_Continue
Filename_Unmatch:
and si,0ffe0h
add si,020h
mov di,filename
jmp findfile
Loader_Not_Find:
mov ax,0
mov es,ax
mov ax,Message4
mov cx,18
mov dx,0200h
call DispStr
jmp $
;===================================================================
Loader_Find:
;Read FAT entries sectors
mov ax,0209h
mov cx,0002h
mov dx,0
mov bx,FATEntryAddr
mov es,bx
xor bx,bx ;set the cache [es:bx] as 0800:0h
int 13h
;when program be here,[ds:si] point to the filename entry's +11
;then i want get the file's FAT entries
mov ax,LoaderBaseAddr
mov es,ax
mov bx,0 ;set the cache address as 0100:0h
add si,15
lodsw ;mov ds:si to ax (word)
readLoader:
call readSector
call getFATEntry
cmp ax,0ff7h
jl readLoader
mov ax,0
mov es,ax
mov ax,Message3
mov cx,16
mov dx,0200h
call DispStr
;jmp $
jmp 01000h
;=======================================================================
readSector:
push ax
add ax,31 ;because the 1st data sector entry number is 2
mov cl,18
div cl
mov ch,al
shr ch,1 ;get cylinder number
mov dh,al
and dh,1 ;get the magnetic head number
mov cl,ah
inc cl ;get the sector number
mov ax,0201h
int 13h
add bx,0200h
pop ax
ret
getFATEntry:
mov si,0
mov cx,FATEntryAddr
mov ds,cx ;set ds:si to 0x5000h
mov cl,2
div cl ;ax/cl -> quotient in al,remainder in ah
mov cl,al
shl cl,1
add al,cl ;al * 3
xor cx,cx
mov cl,al
add si,cx ;mov si to the entry
cmp ah,1
jz Odd_Number
mov ax,[ds:si]
and ax,0fffh ;set the high 4bits zero
ret
Odd_Number:
inc si
mov ax,[ds:si]
shr ax,4 ;roll 4bits right
ret
DispStr:
mov bp,ax
mov ax,01301h
mov bx,000ch
int 10h
ret
Message1: db "Now booting..."
Message2: db "Finding loader..."
Message3: db "Loader finded..."
Message4: db "Loader not find..."
filename: db "LOADER BIN"
;===================================================================
times 510-($-$$) db 0
dw 0xaa55
times (2879*512) db 0
=====================================================================
这段代码可用nasm编译直接生成软盘镜像。在linux下,用命令:
sudo mount -o umask=000 floppy.img Floppy
即可挂载至Floppy文件夹下。如用作引导分区,可将根目录下的loader.bin文件加载至内存01000h处,并跳转执行~