本文仅对boot中的内容进行更新实现引导loader的功能
将下列代码代替原boot.asm(内涵部分注释)
org 0x7c00
BaseOfStack equ 0x7c00
BaseOfLoader equ 0x1000
OffsetOfLoader equ 0x00
RootDirSectors equ 14
SectorNumOfRootDirStart equ 19
SectorNumOfFAT1Start equ 1
SectorBalance equ 17
jmp short Label_Start
nop
BS_OEMName db 'MINEboot'
BPB_BytesPerSec dw 512
BPB_SecPerClus db 1
BPB_RsvdSecCnt dw 1
BPB_NumFATs db 2
BPB_RootEntCnt dw 224
BPB_TotSec16 dw 2880
BPB_Media db 0xf0
BPB_FATSz16 dw 9
BPB_SecPerTrk dw 18
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 'boot loader'
BS_FileSysType db 'FAT12 '
Label_Start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, BaseOfStack
;======= clear screen
mov ax, 0600h
mov bx, 0700h
mov cx, 0
mov dx, 0184fh
int 10h
;======= set focus
mov ax, 0200h
mov bx, 0000h
mov dx, 0000h
int 10h
;======= display on screen : Start Booting......
mov ax, 1301h
mov bx, 000fh
mov dx, 0000h
mov cx, 10
push ax
mov ax, ds
mov es, ax
pop ax
mov bp, StartBootMessage
int 10h
;======= reset floppy
xor ah, ah
xor dl, dl
int 13h
;======= search loader.bin
mov word [SectorNo], SectorNumOfRootDirStart
Lable_Search_In_Root_Dir_Begin:
cmp word [RootDirSizeForLoop], 0
jz Label_No_LoaderBin
dec word [RootDirSizeForLoop]
mov ax, 00h
mov es, ax
mov bx, 8000h
mov ax, [SectorNo]
mov cl, 1
call Func_ReadOneSector
mov si, LoaderFileName
mov di, 8000h
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 [SectorNo], 1
jmp Lable_Search_In_Root_Dir_Begin
;======= display on screen : ERROR:No LOADER Found
Label_No_LoaderBin:
mov ax, 1301h
mov bx, 008ch
mov dx, 0100h
mov cx, 21
push ax
mov ax, ds
mov es, ax
pop ax
mov bp, NoLoaderMessage
int 10h
jmp $
;======= found loader.bin name in root director struct
Label_FileName_Found:
mov ax, RootDirSectors
and di, 0ffe0h
add di, 01ah
mov cx, word [es:di]
push cx
add cx, ax
add cx, SectorBalance
mov ax, BaseOfLoader
mov es, ax
mov bx, OffsetOfLoader
mov ax, cx
Label_Go_On_Loading_File:
push ax
push bx
mov ah, 0eh
mov al, '.'
mov bl, 0fh
int 10h
pop bx
pop ax
mov cl, 1
call Func_ReadOneSector
pop ax
call Func_GetFATEntry
cmp ax, 0fffh
jz Label_File_Loaded
push ax
mov dx, RootDirSectors
add ax, dx
add ax, SectorBalance
add bx, [BPB_BytesPerSec]
jmp Label_Go_On_Loading_File
; Label_File_Loaded:
; jmp $
;======= read one sector from floppy
Func_ReadOneSector:
push bp
mov bp, sp
sub esp, 2
mov byte [bp - 2], cl
push bx
mov bl, [BPB_SecPerTrk]
div bl
inc ah
mov cl, ah
mov dh, al
shr al, 1
mov ch, al
and dh, 1
pop bx
mov dl, [BS_DrvNum]
Label_Go_On_Reading:
mov ah, 2
mov al, byte [bp - 2]
int 13h
jc Label_Go_On_Reading
add esp, 2
pop bp
ret
;======= get FAT Entry
Func_GetFATEntry:
push es
push bx
push ax
mov ax, 00
mov es, ax
pop ax
mov byte [Odd], 0
mov bx, 3
mul bx
mov bx, 2
div bx
cmp dx, 0
jz Label_Even
mov byte [Odd], 1
Label_Even:
xor dx, dx
mov bx, [BPB_BytesPerSec]
div bx
push dx
mov bx, 8000h
add ax, SectorNumOfFAT1Start
mov cl, 2
call Func_ReadOneSector
pop dx
add bx, dx
mov ax, [es:bx]
cmp byte [Odd], 1
jnz Label_Even_2
shr ax, 4
Label_Even_2:
and ax, 0fffh
pop bx
pop es
ret
;======= tmp variable
RootDirSizeForLoop dw RootDirSectors
SectorNo dw 0
Odd db 0
;======= display messages
StartBootMessage: db "Start Boot"
NoLoaderMessage: db "ERROR:No LOADER Found"
LoaderFileName: db "LOADER BIN",0
;=========================
Label_File_Loaded:
jmp BaseOfLoader:OffsetOfLoader
;======= fill zero until whole sector
times 510 - ($ - $$) db 0
dw 0xaa55
其他同上文。
代码详解请看:
在原有基础上添加 loader.asm(简单的显示功能)
loader.asm内容
org 10000h
mov ax,cs
mov ds,ax
mov es,ax
mov ax,0x00
mov ss,ax
mov sp,0x7c00
;========== 显示 Start Loader....
mov ax,1301h
mov bx,000fh
mov dx,0200h
mov cx,12
push ax
mov ax,ds
mov es,ax
pop ax
mov bp,StartLoaderMessage
int 10h
jmp $
;=============
StartLoaderMessage : db "Start Loader"
对loader.asm进行下列操作:
nasm loader.asm -o loader.bin
当loader.asm程序编译结束后,必须将生成的二进制程序loader.bin复制到虚拟软盘镜像文件boot.img中。此处的复制过程与boot.bin程序的写入过程采用了完全不同方法,当boot.bin程序写入到boot.img虚拟软盘镜像文件后,boot.img虚拟软盘已经拥有了FAT12文件系统,那么应该借助挂载命令mount和复制命令cp,把引导加载程序loader.bin复制到文件系统中。
整个复制过程需要执行以下命令:
mount boot.img /media/ -t vfat -o loop 挂载 目录 -t vfat 指定磁盘文件系统
cp loader.bin /media/ 复制到文件系统
sync //强制同步命令
umount /media/ //卸载目录
然后运行引导成功即可:
具体运行请参考:在Linux下安装配置bochs,并成功跑一个简单的boot引导(超详细)_What’smean的博客-CSDN博客