本文仅对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博客
