一 核心内容:制作真正IPL (Initial Program Loader), -- 引导读取磁盘内容
1 一个读取磁盘内容的例子
; ORG命令指明将整个程序加载到内存的0x7c00处,0x7c00是人为规定的地址,不能更改。 //Day 3
ORG 0x7c00
; Format of floppy disk in fat12 标准FAT12格式软盘结构
JMP entry ;JMP 跳转到目标内存地址 entry 表示entry代码段在内存中的起始位置
DB 0x90
DB "MyOS IPL" ;写入启动扇区名字,必须8个字节
DW 512 ;启动扇区大小512字节
DB 1 ; 一个簇大小是一个扇区
DW 1 ; FAT从第一个扇区启动
DB 2 ; FAT个数为2个
DW 224 ; 根目录大小224
DW 2880 ; 磁盘包含2880个扇区
DB 0xf0 ; 磁盘种类必须为0xf0
DW 9 ; FAT长度为9扇区
DW 18 ; 1个磁道18个扇区
DW 2 ; 2个磁头
DD 0 ; 不使用分区
DD 2880 ; 同上,磁盘大小
DB 0,0,0x29 ; 无意义,固定这么写
DD 0xffffffff ; 无意义,固定这么写
DB "MyOS " ; 磁盘名,11字节
DB "FAT12 " ; 磁盘格式名,8字节
RESB 18 ; 空18个字节,填充0x00
;BOOT KERNEL 中断调用
entry:
MOV AX,0
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
; READ DISK
MOV AX,0x0820
MOV ES,AX
MOV CH,0 ; 柱面 0
MOV DH,0 ; 磁头 0
MOV CL,2 ; 扇区 2
MOV AH,0x02 ; AH=0x02 : 读入磁盘
MOV AL,1 ; 1个扇区
MOV BX,0
MOV DL,0x00 ; A驱动器
INT 0x13 ; BIOS 磁盘读中断
JC error ; 出错时跳转到ERROR
JMP succeed ; 未发生错误,打印succeed
fin:
HLT
JMP fin
;Debug print
;error msg
error:
MOV SI,error_msg
JMP print
;error_msg
error_msg:
; msg 进入系统后打印内容
DB 0x0a, 0x0a ; 换行
DB "DISK LOAD ERROR "
DB 0x0a ; 改行
DB 0
;succeed
succeed:
MOV SI,succeed_msg
JMP print
;succeed msg
succeed_msg:
DB 0x0a, 0x0a ; 换行
DB "DISK LOAD SUCCEED! "
DB 0x0a ; 改行
DB 0
print:
MOV AL,[SI]
ADD SI,1
CMP AL,0
JE fin
MOV AH,0x0e
MOV BX,15
INT 0x10 ; bios 显示中断
JMP print
; BOOT END
RESB 32254-$
DB 0x55, 0xaa
2 运行结果
3 汇编指令
JC: jump if carry 的缩写,表示如果进位标志(carry flag) 为1的话,就跳转。
本例子中的进位标志,表示调用磁盘读之后,无错,进位标识为0,有错,进位标志为1。
二 核心内容,启动自制系统
IPL实现跳转,进入操作系统部分,firstOS.nsm,其内容可以是打印一句话,或者显示黑色屏幕。
1.修改IPL.nsm
将 JMP succeed 修改为 JMP 0xc200
2.创建firstOS.nsm 显示黑色屏幕
ORG 0xc200
MOV AL,0x13
MOV AH,0x00
INT 0x10
final:
HLT
RET
3. 编译
nasm IPL.nsm -o IPL.bin
nasm myos.nsm -o myos.bin
edimg imgin:fdimg0at.tek wbinimg src:IPL.bin len:512 from:0 to:0 copy from:firstOS.bin to:@: imgout:MYOS.img
虚拟机加载镜像启动,显示如下图
不显示光标。