1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
;%define _BOOT_DEBUG_ ; 做Boot Sector时把这行注释掉
; 启用这行就用nasm Boot.asm -o Boot.com生成.com文件用于调试
%ifdef _BOOT_DEBUG_
org 0100h%
else
org 07c00h
%endif
CYLS EQU 10 ; 一共读取10个柱面, 共 10柱面*2面*18扇区*512字节 = 184320 byte = 180K; 把软盘按Fat12格式填充
start:
JMP init ; 跳转指令
DB 0x90 ; 空 DB,DD用来写单字节
DB "NotOneOS" ; 厂商名,8字节,DB用来写双字节
DW 512 ; 每个扇区大小512字节,DW用来写4字节
DB 1 ; 每个簇的扇区数
DW 1 ; Boot占的扇区
DB 2 ; 有2个FAT表
DW 224 ; 根目录大小224
DW 2880 ; 磁盘扇区总数 2880
DB 0xf0 ; 介质描述符,磁盘种类必须为0xf0
DW 9 ; 每个FAT扇区数
DW 18 ; 每个磁道18个扇区
DW 2 ; 2个磁头
DD 0 ; 隐藏扇区数
DD 2880 ; 同上,磁盘大小
DB 0, 0, 0x29 ; 0x29 扩展引用标记
DD 0xffffffff ; 无意义,固定这么写
DB "NotOneOS " ; 磁盘名(卷标),11字节
DB "FAT12 " ; 磁盘格式名,8字节
RESB 18 ; 空18个字节,填充0x00
init:
MOV AX,0
MOV SS,AX
MOV SP,0x7c00 ; 堆栈空间,从0x7c00向前
MOV DS,AX; 读取磁盘
MOV AX,0x0820 ; 把磁盘数据加载到内存0x0820处。 0x8000~0x81ff的512字节给启动区用的,所以从0x8200开始
MOV ES,AX ; 注意 ES:BX 是指向的地址,后面还需要对BX赋值0
; 初始化磁盘接口
MOV CH,0 ; 柱面 0
MOV DH,0 ; 磁头 0
MOV CL,2 ; 扇区 2
readloop:
MOV SI,0 ; 记录失败次数
retry:
MOV AH,0x02 ; 0x02 读磁盘
MOV AL,1 ; 读1个扇区
MOV BX,0
MOV DL,0x00 ; A驱动器
INT 0x13 ; BIOS 读磁盘功能
JNC next ; 成功跳转
ADD SI,1 ; 失败加一次
CMP SI,5 ; 到5次就跳到error
JAE error
MOV AH,0x00 ; 复位磁盘功能
MOV DL,0x00 ; A 驱动器
INT 0x13 ; 重置磁盘驱动器
JMP retry ; 重试
next:
MOV AX,ES ; 内存地址向后移动0x0020
ADD AX,0x0020
MOV ES,AX ; 通过AX给ES加0x0020
ADD CL,1 ; 扇区+1
CMP CL,18 ; 有没有到18个扇区
JBE readloop ; CL<=18,就跳到 readloop
MOV CL,1
ADD DH,1
CMP DH,2
JB readloop ; 如果 DH < 2 ,则跳到readloop
MOV DH,0
ADD CH,1
CMP CH,CYLS
JB readloop ; 如果CH
|