迈入操作系统的大门(一)

迈入操作系统的大门(一)

本系列博客是学习于渊的《Orange’s 一个操作系统的实现》所做的一些笔记和记录,用于记录个人学习。
本书的大概结构是:

  1. 一些准备工作,包括对简单操作系统的了解和环境的配置
  2. 保护模式
  3. 扩充内核
  4. 进程概述及实现
  5. I/O

我还将参考Andrew S. Tanenbaum 和 Albert S. Woodhull的《操作系统设计与实现》。
现在,我们开始!

一、准备工作

书上说要用一个软盘,当然现在都9102年了,当然不用软盘了,我们可以通过Linux来制作一个软盘镜像。不过我们先来看代码吧:

1.一个20行的操作系统

主引导记录代码 boot.asm:

;boot.asm 主引导记录代码
	org	07c00h
;10h中断,用来显示字符
	mov		ax, cs
	mov 	ds, ax
	mov 	es, ax
	call	DispStr
	jmp		$				;无限循环
DispStr:
	mov		ax, BootMessage
	mov		bp, ax			;串地址
	mov		cx, 24			;cx=串长度
	mov		ax, 01301h		;AH=13, AL=01h
	mov		bx, 000ch		;页号为0(BH=0)黑底红字(BL=0CH,高亮)
	mov		dl, 0
	int		10h				;10h号中断
	ret
BootMessage:		db	"Hello, Operation System!"
times	510-($-$$)	db	0	;填充剩下的空间,使其为512B
dw	0xaa55					;结束标志

将这段代码用NASM编译一下,对于NASM汇编器,可以到我的网盘下载(提取码:z582 )已经编译好的NASM.

nasm boot.asm -o boot.bim

该命令在Linux下和Windows下都可以。

2. 制作软盘镜像

然后我们就要将生成的主引导记录bin文件生成一个软盘镜像文件:
首先,我们用Linux的dd命令制作一个空的软盘镜像:

dd if=/dev/zero of=empty.img bs=512 count=2880

然后我们制作一个包含主引导记录的镜像文件cherryOS(这个名字自己随便起):

dd if=boot.bin of=cherryOS.img bs=512 count=1

然后,将empty.img中1个扇区后的数据拷贝到cherryOS.img的后面:

dd if=empty.img of=cherryOS.img skip=1 seek=1 bs=512 count=2879

注意: ifof后面不能有空格,具体如下图:
软盘镜像制作
在这里插入图片描述
然后将这个镜像文件(在我这里是cherryOS.img)传到Windows下,这里方法很多,什么XFTP软件,SFTP,SCP都可以,不会的话去百度吧。

3. 设置虚拟机从软盘启动

这里我用的虚拟机是Virtual Box,其实什么虚拟机软件都无所谓,这里以我的Virtual Box为例:
首先新建虚拟机,先不要创建虚拟硬盘,分配的内存512M足矣,反正图形界面都没有,不吃什么内存的。然后在设置中只选择软驱启动:
虚拟机从软驱启动
然后添加一个Floppy:
添加软盘驱动
然后添加刚刚的软盘驱动(cherryOS.img),再次启动虚拟机,看到下面的显示,说明成功了!

Success!!!每次这样都要打开两个虚拟机来制作镜像,有点太麻烦了,我的电脑风扇现在已经呼啦啦的响了,我们可以用一个软盘制作工具FloppyWriter,从我的网盘下载:(FloppyWriter 提取码:zo97)

然后就可以直接将bin文件写入img镜像文件了:
在这里插入图片描述

二、代码解释

刚刚那20行代码其实就是一个引导扇区,并不属于真正意义上的操作系统,但是已经是一个良好的开端了。
我们知道,当计算机电源打开时,他会先进行加电自检(POST),然后寻找启动盘,如果是从软盘启动,计算机会检查软盘的0面0磁道1扇区,如果发现他以0xaa55结束,则BIOS会认为他是一个引导扇区。一个引导扇区不仅需要以0xaa55结束之外,还要包含一段少于512字节的执行码。
然后BIOS发现引导扇区,将这512字节的内容装载到内存地址为0000:7c00处,然后将控制权交给这段引导代码,由操作系统控制。

1. 关于 $ 和 $$

我们将boot.asm反汇编来看一下:

ndisasm -0 0x7c00 root.bin >> disboot.asm

-o后面的参数就是从0x7c00地址读取512字节的内容,我们看到:
反汇编
$在这里就是当前指令的地址,$$其实是表示一个“节”的意思,就是程序开始的地址,这里org 07c00h就表示将程序加载到地址为7c00的地方,因此$$表示7c00
后面$-$$可能还会用到很多,他表示本行距离程序开始处的相对距离,因此汇编代码510-($-$$)就是表示将0这个字节重复510-($-$$)遍,加上结束标志0xAA55两个字节正好是512字节。

2. 关于8086

上面的代码设计将代码加载到7c00处,因为在8086CPU中,0x0000h0x7c00h这一段存的是BIOS中断向量和一些BIOS数据,相当于系统数据。至于int 10h,就是8086的一种内中断,学过汇编语言和操作系统或者组成原理的应该都知道,就不做解释了。

3. 关于汇编

cx寄存器是默认的处理字符串长度的寄存器,因此输出的字符串可以自行修改,同时修改cx即可。

这样我们就完成了第一节的内容,实际上非常简单。

发布了40 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42650988/article/details/103631000