[Rx86OS-I] 计算机开机从软盘启动显示字符串Hello World

平台

处理器:Intel Celeron(R) Dual-Core CPU

操作系统:Windows7 专业版 x86

阅读《30天自制操作系统》—川合秀实[2015.03.12 – 03.14],[03.26整理]笔记。

在笔记中将《30天自制操作系统》称为“书”。以膜拜的心情采用光盘中的工具来进行笔记。

工具:../toolset/


1 计算机从软盘启动

如果将计算机的开机设置为从软盘启动,计算机开机会驱动软盘的磁头0读其0柱面1扇区的内容到内存0x7c00~ 0x7dff处,并检查扇区最后两2字节内容,如果为55AAH,则从0x7c00开始执行这段程序。软盘的结构在“书”中“第3天制作真正的IPL”节。


如果将一个好的软盘的磁头0对应的0柱面1扇区内含有一段(让显存)显示“Hello world”的机器指令,且将扇区最后2个字节的内容为55AAH。设置计算机开机时从软盘启动后就能够显示“Hello World”。


2 往软盘内写程序的方法

2.1 下载给软盘的.img文件

通过观察下载给软盘的.img文件,它的大小要跟软盘的大小一样(80* 18 * 512 * 2 = 1474560字节)。


2.2 下载工具

“书”附带的光盘中含有很多有用的工具。采用“书”第一天中的“!cons_nt.bat”和“install.bat”工具。“!cons_nt.bat”打开命令行窗口并将命令行切换到“!cons_nt.bat”所在的目录下,在“!cons_nt.bat”打开的命令行下运行“install.bat”就可以将“helloos.img”文件中的内容下载到连接到电脑上的软盘中。


如果“helloos.img”文件内含有以上描述的“显示Hello World”加“55AAH”的内容,那么就此软盘就可以完成让计算机启动时显示“Hello world”。


3 制作helloos.img

helloos.img的内容最终在内存0x7c00~ 0x7dff处,CPU要能够执行这段内容,这段内容得是CPU能够识别的机器指令。所以在helloos.img中的内容就是让CPU驱动显存显示“Hello world”的二进制(与文本文件如“记事本”、“word”中的“10”序列不同)指令。

显示“hello world”的机器指令可以怎么来?

[1] 用二进制编辑器直接敲机器指令。(我不知道机器指令,不会干这事)

[2] 用汇编语言代替机器指令,然后用编译器将汇编程序转换成机器指令。(“书”的作者自己写了一个针对汇编程序的编译器nask.exe)

[3] 采用高级语言如C,再用对应的编译器将其转换成机器指令。(高级语言有的库函数依赖操作系统,如printf;计算机开机工作在实模式下,我手头无16位C语言编译器)

采取方法[2]。


3.1 显示Helloworld的汇编程序

查询到软盘的一个扇区能够容纳512字节的二进制位。那么显示“hello world”的程序可以这样写:

;hellowrold.nas
;tab	= 8

	ORG	0x7c00		;让BIOS将这段程序装载到0:0x7c00处

;可以写用户程序的地方
entry:
	MOV	AX, 0		;初始化段寄存器,段地址都为0
	MOV	DS, AX
	
	
	MOV	SI,msg
putloop:
	MOV	AL,[SI]		;ds:si
	ADD	SI,1			
	CMP	AL,0
	JE	fin
	MOV	AH,0x0e		;BIOS 10h程序的功能号参数,eh表示显示字符功能
	MOV	BX,15		;AH = EH时,BL表字符前景色,AL表要显示的字符
	INT	0x10		;调用BIOS 10h号中断程序
	JMP	putloop
fin:
	HLT			;省电:让CPU进入休眠状态,当复位信号或者中断来临时,
	JMP	fin		;CPU再执行HLT的下一条指令,或者转去执行中断程序,
				;当中断处理完后又执行一次HLT,CPU将再次进入休眠状态

msg:
	DB	0x0a, 0x0a	;0x0a表示换行
	DB	"hello, world"
	DB	0x0a			
	DB	0

	RESB	0x7dfe-$		;从此处填0,直到0x7dfd(org 0x7c00使得这指令的偏移地址从0x7c00开始)

	DB		0x55, 0xaa	;对应扇区最后2个字节内容
	
RESB	1474560 + 0x7c00 - $

怀着膜拜“书”作者的心情用“nask.exe helloworld.nas helloos.img”工具得到helloos.img文件,然后打开cmd运行“书”中“install.bat”将helloos.img下载到软盘中。再将软盘插在一个开机以软盘启动的计算机上,得以下结果:

Figure1. 第一扇区的Hello world程序运行结果

在cmd中运行“run.bat”命令,QEMU虚拟机中也显示“hello world”字符串。


3.2 按照软盘0磁头第一扇区、其它扇区的格式制作helloos.img

在往电脑中插含软盘的软驱的时候,给出格式化软盘的提示,格式化的格式为FAT12。此外,计算机开机读软盘的程序是BIOS的13h程序,此程序读取的磁头0对应的0柱面1扇区需要按照指定格式书写,这部分内容笔记在“软盘启动区格式”。除启动区外,另外两个地方也有固定的内容,见“软盘启动区外的内容”。


从表格中可以看出,软盘第一扇区(0磁头)从偏移62处开始的448字节可以写用户程序,其它区域的内容都已经固定,只有按照这样的格式内容,系统BIOS才能正确的读取这个扇区的内容到内存0x7c00~ 0xfdff中。

;hellowrold.nas
;tab	= 8

	ORG	0x7c00		;让BIOS将这段程序装载到0:0x7c00处
;FAT12格式软盘第一个扇区前61字节内容
	JMP	entry
	DB	0x90
	DB	"HELLOIPL"	;启动区的名称,可以是任意8字节的字符串
	DW	512		;每个扇区(sector)的大小(必须为512字节)
	DB	1		;簇(cluster)的大小(必须为1个扇区)
	DW	1		;FAT的起始位置(一般从第一个扇区开始)
	DB	2		;FAT的个数(必须为2)
	DW	224		;根目录的大小(一般设成224)
	DW	2880		;读磁盘(软盘内存数据的介质)的大小(必须是2880扇区)
	DB	0xf0		;磁盘的种类(必须是0xf0)
	DW	9		;FAT的长度(必须是9扇区)
	DW	18		;1个磁道(track)有几个扇区(必?是18)
	DW	2		;磁头个数(必是2)
	DD	0		;不使用分区,必是0
	DD	2880		;重写一次磁盘的大小
	DB	0,0,0x29	 
	DD	0xffffffff	 
	DB	"HELLO-OS   "	;磁盘的名称(11字节)
	DB	"FAT12   "	;磁盘的格式名称(8字节)
	RESB	18		;空出18字节

;可以写用户程序的地方
entry:
	MOV	AX, 0		;初始化段寄存器,段地址都为0
	MOV	DS, AX
	
	MOV	SI,msg
putloop:
	MOV	AL,[SI]		;ds:si
	ADD	SI,1			
	CMP	AL,0
	JE	fin
	MOV	AH,0x0e		;BIOS 10h程序的功能号参数,eh表示显示字符功能,
	MOV	BX,15		;AH = EH时,BL表字符前景色,AL表要显示的字符
	INT	0x10		;调用BIOS 10h号中断程序
	JMP	putloop
fin:
	HLT			;省电:让CPU进入休眠状态,当复位信号或者中断来临时,
	JMP	fin		;CPU再执行HLT的下一条指令,或者转去执行中断程序,
				;当中断处理完后又执行一次HLT,CPU将再次进入休眠状态

msg:
	DB	0x0a, 0x0a	;0x0a表示换行
	DB	"hello, world"
	DB	0x0a			
	DB	0

	RESB	0x7dfe-$		;从此处填0,直到0x7dfd(org 0x7c00使得这指令的偏移地址从0x7c00开始)

	DB		0x55, 0xaa	;对应扇区最后2个字节内容
	
DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB	RESB	0x1400 + 0x7c00 - $
DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB	1474560 + 0x7c00 - $
再编译helloworld.nas输出helloos.img使用run.bat命令将helloos.img加载到QEMU中,可以显示Hello world字样。再使用“install.bat”命令将helloos.img下载到软盘中。将软盘插到电脑上,开机选择从软盘启动,软盘咔擦几声响后,CPU执行HLT指令,在屏幕上留下以下结果:
Figure 2. 开机从软盘启动显示hello world(二进制程序)

总结

[1] 软盘的“偏移”、“扇区”、“柱面”等格式都是逻辑层面的规定,了解BIOS13h程序的参数与软盘格式的对应关系,可参考“书”中第3天“制作真正IPL”章节

[2] 0x7c00、启动区格式(除0x55aa)等规定非必须

[3][ 实模式]内存地址空间分布 CPU合成内存地址的方式  程序中段的加载


计算机开机选择从软盘启动的设置

BIOS在调用int19h之前会让用户选择进入启动菜单界面(此台电脑是按esc键进入)。按F10就可以进行BIOS设置:System Configuration >> Boot Options >> Floppy Boot(Enable);System Configuration >> Boot Options >> Boot Order >> 将USB Floppy置顶。


再按F10“保存”设置退出,计算机将重新启动。按esc键后,再按F9键,选择从检测到(如果电脑上连接了软驱,软驱内含软盘)的软盘(USB Floppy)启动(回车),计算机就会去读软盘的第一个扇区到内存

(不同的计算机选择从软盘启动的过程可能会不一样。)

[X86OS] Note Over.

[2015.04.01]

你可能感兴趣的:([Rx86OS-I] 计算机开机从软盘启动显示字符串Hello World)