自制操作系统学习第七天
今天要做什么?
- 实现HLT,不让计算机处于HALT(HLT).
- 用C语言实现内存写入(错误,需要分析)
一:使用HLT,让计算机处于睡眠状态
写了下面这个程序,naskfunc.nas
函数名叫io_hlt,虽然只叫hlt也行,但在cpu的指令之中,HLT也属于I/O指令,所以就起了这么一个名字。
MOV属于转送指令,ADD属于演算指令。用汇编写的函数,之后还要与bootpack.obj链接,所以也需要编译成目标文件,因此输出格式设定位WCOFF模式,还需要设定成32位机器语言模式。
在nask目标文件的模式下,必须设定文件名信息,然后在写明下面程序的函数值,注意要再函数名的前面加上”_”,否则就不能很好的与C语言函数链接,需要链接的函数名,都要用GLOBAL指令声明。
下面写一个实际的函数,写起来很简单bootpack.c
二:内存写入
修改naskfunc.nas
bootpack.c
修改完后make 执行生成镜像后,执行,并没有显示成想要达成的效果,于是需要读一读文章,二进制文件分析,根据文章内容,修改相应文件。
需要一个好的二进制编辑工具
报错内容记录:
; haribote-ipl
; TAB =4
cyls equ 10 ; 声明CYLS=10
ORG 0x7c00 ; 指明程序装载地址
; 标准FAT12 格式软盘专用的代码 Stand FAT12 format flppy code
JMP entry
DB 0x90
DB "HARIBOTE" ;启动扇区名称(8字节)
DW 512 ;每个扇区(sector)大小(必须512字节)
DB 1 ; 簇(cluster)大小 必须为一个扇区
DW 1 ; FAT起始位置(一般为第一个扇区)
DB 2 ; FAT个数(必须为2)
DW 224 ; 根目录大小(一般为224项)
DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512)
DB 0xf0 ; 跳过引导扇区,必须为0xf0
DW 9 ; 跳过引导扇区后的第一个数据分区,必须为9?
DW 18 ; 该磁盘的扇区数,必须为18
DW 2 ; 磁头每个扇区扇区数,必须为2?
DD 0 ;不适用分区,必须为0
DD 2880 ;重写一次磁盘大小
DB 0,0,0x29 ;磁盘号,卷标,磁盘长度??必须为0x29
DD 0xffffffff ;磁盘序列号,必须为0xffffffff
DB "HARIBOTEOS " ;磁盘名称,必须为11字,不足填空格
DB "FAT12 " ;磁盘格式名称(必须为8字?,不足填空格)
RESB 18 ;先空出18字节
; 程序主体
entry:
MOV AX,0 ;初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
;读磁盘 读入10个柱面
MOV AX, 0x0820
MOV es,AX
MOV CH,0 ; 柱面0
MOV DH,0 ; 磁头
MOV CL,2 ; 扇区2
readloop:
MOV SI,0 ; 缓冲区偏移 记录失败次数
retry:
MOV AH,0x02 ; 读入磁盘
MOV AL,1 ; 1个扇区
MOV bx,0 ;0
MOV dl,0X00 ; A驱动器
INT 0x13 ; 调用磁盘BIOS
JNC next ;没出错时跳转到next
ADD SI,1 ;SI加1
CMP SI,5 ;比较SI与5
JAE error ;SI>5时,跳转到error
MOV AH,0x00
MOV DL,0x00 ;A驱动器
INT 0x13 ;重置驱动器
JMP retry
next:
MOV AX,ES ;把内存地址后移0x200
ADD AX,0X0020 ;往CL里加1
MOV ES,AX ;因为没有ADD ES,0x020指令,所以这里稍微绕个弯
ADD CL,1 ;CL加1
CMP CL,18 ;比较CL与18
JBE readloop ;如果CL<=18.则跳转至readloo
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 ;如果CL <=18跳转到readloop
; 读取完毕,跳转到haribote.sys执行!
MOV [0x0ff0],CH ; IPLがどこまで読んだのかをメモ
JMP 0xc200
fin:
HLT ; 让CPU停止,等待指令
JMP fin ; 无限循环
error:
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; 给SI加1
CMP AL,0
JE fin
MOV AH,0x0e ; 显示一个文字
MOV BX,15 ; 指定字符颜色
INT 0x10 ; 调用显卡BIOS
JMP putloop
msg:
DB 0x0a, 0x0a ; 换行两次
DB "load error"
DB 0x0a ; 换行
DB 0
RESB 0x7dfe-$ ; 填写0x00直到0x001fe
DB 0x55, 0xaa
需要仔细分析一下生成文件,才能更好的去写。