30天自制操作系统(第二天)

 一、内存区域

1、启动区

地址范围:0x7C00~0x7DFF

特点:地址7DFE储存的值为0x55、7DFF储存的值为0xAA

2、Boot data/stack区(引导数据/堆栈

地址范围:0x7E00~0x7FFF

3、启动区预留

因为把C0-H0-S2装载到了0x8200,等价于C0-H0-S1装载到了0x8000。

地址范围:0x8000~0x81FF

4、系统区

地址范围:0x8200~0x9FBFF

二、代码解析

1、Makefile

#变量定义
TOOLPATH = ../z_tools/
MAKE     = $(TOOLPATH)make.exe -r
NASK     = $(TOOLPATH)nask.exe
EDIMG    = $(TOOLPATH)edimg.exe
IMGTOL   = $(TOOLPATH)imgtol.com
COPY     = copy
DEL      = del

# 初始化动作,输入make时执行img编译
default :
	$(MAKE) img

# 文件生成規則
# 检查文件是否齐全,然后实施制作
ipl10.bin : ipl10.nas Makefile
	$(NASK) ipl10.nas ipl10.bin ipl10.lst

haribote.sys : haribote.nas Makefile
	$(NASK) haribote.nas haribote.sys haribote.lst

haribote.img : ipl10.bin haribote.sys Makefile
	$(EDIMG)   imgin:../z_tools/fdimg0at.tek \
		wbinimg src:ipl10.bin len:512 from:0 to:0 \
		copy from:haribote.sys to:@: \
		imgout:haribote.img

# 定义命令
img :
	$(MAKE) haribote.img

run :
	$(MAKE) img
	$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin
	$(MAKE) -C ../z_tools/qemu

install :
	$(MAKE) img
	$(IMGTOL) w a: haribote.img

clean :
	-$(DEL) ipl10.bin
	-$(DEL) ipl10.lst
	-$(DEL) haribote.sys
	-$(DEL) haribote.lst

src_only :
	$(MAKE) clean
	-$(DEL) haribote.img

借助.bat启动make.exe,从而实施mafile文件。

..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9

2、汇编代码

ipl代码的作用:

①、初始化寄存器

②、向软盘写数据(写到对应地址位置)

③、跳到系统区汇编代码地址

; haribote-ipl
; TAB=4

CYLS	EQU		10				; 10个柱面都要读入,这里是循环读入次数

		ORG		0x7c00			; ipl的起始地址是0x7C00

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

		JMP		entry
		DB		0x90
		DB		"HARIBOTE"		; ブートセクタの名前を自由に書いてよい(8バイト)
		DW		512				; 1セクタの大きさ(512にしなければいけない)
		DB		1				; クラスタの大きさ(1セクタにしなければいけない)
		DW		1				; FATがどこから始まるか(普通は1セクタ目からにする)
		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				; パーティションを使ってないのでここは必ず0
		DD		2880			; このドライブ大きさをもう一度書く
		DB		0,0,0x29		; よくわからないけどこの値にしておくといいらしい
		DD		0xffffffff		; たぶんボリュームシリアル番号
		DB		"HARIBOTEOS "	; ディスクの名前(11バイト)
		DB		"FAT12   "		; フォーマットの名前(8バイト)
		RESB	18				; とりあえず18バイトあけておく

; 下面是程序本体

entry:
		MOV		AX,0			; 寄存器初始化
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX

;读磁盘

		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			; 柱面0
		MOV		DH,0			; 磁头0
		MOV		CL,2			; 扇区2
readloop:
		MOV		SI,0			; 记录失敗回数的寄存器
retry:
		MOV		AH,0x02			; AH=0x02 : 读磁盘命令
		MOV		AL,1			; 1个扇区大小
		MOV		BX,0            ; 段寄存器指定的地址=ES*16+BX
		MOV		DL,0x00			; A驱动器
		INT		0x13			; 调用磁盘BIOS执行读取
		JNC		next			; 没出错的话,读下一个扇区(jump if not carry)
		ADD		SI,1			; 出错了SI加1
		CMP		SI,5			; SI和5比较
		JAE		error			; SI >= 5进入err
		MOV		AH,0x00
		MOV		DL,0x00			; A驱动器
		INT		0x13			; 重置驱动器
		JMP		retry
next:
		MOV		AX,ES			; ES加0x20,地址后移0x20*16=0x200
		ADD		AX,0x0020       ; ES加0x20,地址后移0x20*16=0x200
		MOV		ES,AX			; ES加0x20,地址后移0x20*16=0x200
		ADD		CL,1			; 扇区+1
		CMP		CL,18			; 18个扇区,全部读取
		JBE		readloop		; CL <= 18 跳readloop读取(jump if below or equal)
		MOV		CL,1            
		ADD		DH,1
		CMP		DH,2
		JB		readloop		; DH < 2 跳readloop读取(jump if below)
		MOV		DH,0
		ADD		CH,1
		CMP		CH,CYLS
		JB		readloop		; CH < 10 跳readloop读取(jump if below)

; 读完了10*2*18*512=184320字节=180kb

		MOV		[0x0ff0],CH		; 记下IPL读到了什么程度
		JMP		0xc200          ; 跳到系统区首地址

error:
		MOV		SI,msg          ; SI是源变址寄存器,这时储存的是msg的首地址
putloop:                        ; 初始化完成后,进入循环
		MOV		AL,[SI]         ; 把地址为SI的值取出(msg的一个字符),赋值给AX寄存器的低8位AL
		ADD		SI,1			; SI加1就是地址后移一个字节,指向msg的下一个字符的地址
		CMP		AL,0            ; 判断msg是否结束
		JE		fin             ; 如果发现msg已经结束,跳转到结束,让CPU低功耗运行
		MOV		AH,0x0e			; msg有字符,设置单字显示功能
		MOV		BX,15			; 设置字体颜色
		INT		0x10			; 在屏幕窗口显示
		JMP		putloop         ; 继续循环
fin:
		HLT						; 何かあるまでCPUを停止させる
		JMP		fin				; 無限ループ
msg:
		DB		0x0a, 0x0a		; 改行を2つ
		DB		"load error"
		DB		0x0a			; 改行
		DB		0

		RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令

		DB		0x55, 0xaa

二、遇到的问题和解决办法

1、copy失败的问题 

如果make run提示copy失败,可以把copy改为cp,亲测有效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值