📄 boot record.asm
字号:
entry:
JMP short main
NOP
brOEM db 'qimingos'
brBPS dw 512
; ****************************************************************************************************
; * data portion of the "qimingos BOOT RECORD" *
; ****************************************************************************************************
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
;brOEM DB 'qimingos' ; 0003h - OEM name & DOS version (8 chars)
;brBPS DW 512 ; 000Bh - Bytes/sector
brSPC DB 1 ; 000Dh - Sectors/cluster
brResCount DW 1 ; 000Eh - Reserved (boot) sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0E0H ; 0011h - Root directory entries
brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
brMedia DB 240 ; 0015h - Media descriptor
brSPF DW 9 ; 0016h - Sectors per FAT
brSPH DW 18 ; 0018h - Sectors per track
brHPC DW 2 ; 001Ah - Number of Heads
brHidden DD 0 ; 001Ch - Hidden sectors
brSectors DD 0 ; 0020h - Total number of sectors
;DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig
brSerialNum DD 404418EAH ; 0027h - Volume serial number (random)
brLabel DB 'QimingosLsk ' ; 002Bh - Volume label (11 chars)
brFSID DB 'FAT12 ' ; 0036h - File System ID (8 chars)
; ****************************************************************************************************
; * 数据区 变量定义
; ****************************************************************************************************
main: ; 主程序
mov ax , 0x0000 ; 以下两句设置数据段为0000
mov ds , ax
mov si , Message ; 设置基址指针
call ShowMessage ; 调用显示函数
; ****************************************************************************************************
; 这儿应该放入加载set.asm和内核模块的代码
;下面的程序是为了把位于0头0道2扇区的set程序读入内存 0X9020:0000h地址处
;注意:
; 这儿的扇区数并不一定正确!
; ****************************************************************************************************
LoadSet:
mov ah, 0
mov dl, [bootdrv]
int 0x13 ; 复位启动驱动器
; 将位于从物理2扇区开始的2个扇区的set程序从启动驱动器的读到内存中
; SETSEG:0XFA00
cld ; 方向标志置 0
mov bx, SETOFFSET ; set 地址偏移
mov ax, SETSEG ; set的段地址0XFA00(1000KB)
mov es, ax
mov ax, 0x0201 ; AH = 02 (读扇区功能号), AL=1 (扇区数)
mov cx, 0x0002 ; CH - 磁道号, CL - 逻辑扇区号
mov dh, 0 ; DH - 磁头号
mov dl, [bootdrv] ; DL - 驱动器号
int 0x13 ; 读扇区 BIOS 调用
jnc LoadKernel ; 无错误则进入set执行
;注意:
; 这儿可能不是JNC而是JC
dec byte [retries] ; 读盘计数器减1
jnz LoadSet ; 未到最大读盘次数,则继续读
mov si,ErrorMessage1 ; 到达最大读盘次数仍然读盘有错,
call ShowMessage ; 则显示错误信息
mov ah,0
int 16h ; 等待用户输入任一键
jmp REBOOTSEG:REBOOTOFFSET ; 重新启动
; ****************************************************************************************************
;下面我们加载内核模块!内核模块从0头0道3扇区开始,共两个扇区。
;注意:
; 现在我们的内核还很小所以够用,以后这儿还需要改动!
LoadKernel:
mov bx, KERNELOFFSET ; kernel 地址偏移0x0000
mov ax, KERNELSEG ; kernel 段地址 0x1000(64KB)
mov es, ax
mov ax, 0x0202 ; AH = 02 (读扇区功能号), AL=2 (扇区数)
mov cx, 0x0003 ; CH - 磁道号, CL - 逻辑扇区号
mov dh, 0 ; DH - 磁头号
mov dl, [bootdrv] ; DL - 驱动器号
int 0x13 ; 读扇区 BIOS 调用
jnc EntrySet ; 无错误则进入set执行
dec byte [retries] ; 读盘计数器减1
jnz LoadKernel ; 未到最大读盘次数,则继续读
mov si,ErrorMessage2 ; 到达最大读盘次数仍然读盘有错,
call ShowMessage ; 则显示错误信息
mov ah,0
int 16h ; 等待用户输入任一键
jmp REBOOTSEG:REBOOTOFFSET ; 重新启动
; ****************************************************************************************************
EntrySet:
mov si , SucceedMessage ; 引导成功!
call ShowMessage
;****************************************************************************************************
mov ax,SETSEG
mov ds,ax
mov al,[bootdrv]
mov [0],al
jmp SETSEG:SETOFFSET ; 跳到set代码去执行,启动扇区引导程序结束.
; ****************************************************************************************************
; 下面的程序是为了显示信息!
ShowMessage: ; 显示函数
mov ah , 0x0e ; 设置现示模式
mov bh , 0x00 ; 设置页码
mov bl , 0x07 ; 设置字体属性
nextchar:
lodsb ; 字符载入指令
; 它将DS数据段中SI为偏移地址的源串中的一个字符取出送AL,
; 同时修改SI指向下一个字符
or al , al ; 测试字符串是否为0
jz return ; 如果为零则表明字符串结束,跳转到返回指令处返回原调用函数
int 0x10 ; 调用BIOS 10号中断显示字符
jmp nextchar ; 继续显示下一下字符
return:
ret
; ****************************************************************************************************
Message:
db 'System loading... ' ; 定义显示消息
db 13 , 10 , 0 ; 13 表示回车,10 表示换到下一行,0 表示字符串结束
ErrorMessage1:
db 'set.asm loading failed!'
db 13 , 10 ; 回车并换行!其中,13 表示回车,10 表示换到下一行
db 'System loading failed ! '
db 13 , 10
db 'Any key to reboot...'
db 13 , 10 , 0
ErrorMessage2:
db 'kernel loading failed!'
db 13 , 10 ; 回车并换行!其中,13 表示回车,10 表示换到下一行
db 'System loading failed ! '
db 13 , 10
db 'Any key to reboot...'
db 13 , 10 , 0
SucceedMessage:
db 'boot.asm end! Now , we enter the set.asm!'
db 13 , 10 , 0
; ****************************************************************************************************
bootdrv db 0 ; bootdrv用于保存启动驱动器号
retries db 3 ; 重复读盘次数
; ****************************************************************************************************
; 编译条件
size equ $ -entry
%if size+2 > 512
%error "code is too large for boot sector"
%endif
; ****************************************************************************************************
times 510 - ( $ - $$ ) db 0 ; 填充 0 以满足文件大小足够512字节
; $ 表示当前语句的地址,$$ 表示程序的起始地址
db 0x55 , 0xAA ; 结束标志
set.asm如下:
; ****************************************************************************************************
; 这个程序的作用就是读取系统信息并进入32位保护模式!
; 刘胜坤 2005.4.25
; 由于前面的错误造成这个程序没有完全实现!(2005.4.28)
BITS 16
[org 0X92000] ;这一句是不必要的,甚至是多余的,应该删掉!
;**************************************************************************
;下面的语句由于还没有用到,所以注释掉了!
;KERNELSEG EQU 0x1000 ; kernel的段地址 (64KB)
;KERNELOFFSET EQU 0x0000 ; kernel的偏移地址
;SETSEG EQU 0X9200 ; set的段地址(1000KB)
;SETOFFSET EQU 0x0000 ; set的偏移地址
;REBOOTSEG EQU 0XFFFF ; 重启动段地址
;REBOOTOFFSET EQU 0X0000 ; 重启动偏移地址
;*****************************************************************************
jmp short main
main: ; 主程序
;下面两句可能有错误!
;应该修改为:
; mov ax,cs ; 设置段寄存器
; mov ds,ax
; mov es,ax
;刘胜坤2005.4.28
mov ax,0x0000 ;设置基地址!
mov ds,ax
mov si , Message ; 设置基址指针
call ShowMessage ; 调用显示函数
; ****************************************************************************************************
hang:
jmp hang ; 无限循环
;EntrySet:
; jmp KERNELSEG:KERNELOFFSET ; 跳到KERNEL代码去执行,启动扇区引导程序结束.
; ****************************************************************************************************
; 下面的程序是为了显示信息!
ShowMessage: ; 显示函数
mov ah , 0x0e ; 设置现示模式
mov bh , 0x00 ; 设置页码
mov bl , 0x07 ; 设置字体属性
nextchar:
lodsb ; 字符载入指令
; 它将DS数据段中SI为偏移地址的源串中的一个字符取出送AL,
; 同时修改SI指向下一个字符
or al , al ; 测试字符串是否为0
jz return ; 如果为零则表明字符串结束,跳转到返回指令处返回原调用函数
int 0x10 ; 调用BIOS 10号中断显示字符
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -