您的当前位置:首页正文

30天自制操作系统日志第3天

来源:化拓教育网


30天自制操作系统日志第3天

(总12页)

--本页仅作为文档封面,使用时请直接删除即可-- --内页可以根据需求调整合适字体及大小--

操作系统实验日志

学号 实验日期 520 姓名 实验项目 甘昆禄 专业年级班级 智能1601 第3天:进入32位模式并导入C语言 一、实验主要内容

1、 制作真正的IPL,即启动程序加载器,用来加载程序。

添加的代码关键部分如下:

MOV MOV MOV MOV MOV MOV MOV MOV MOV INT JC

这里有JC指令,是一些特定指令中的一种,后面知识点收录有。JC就是jump if carry,如果进位标志位1的话,就跳转。就是成功调用0x13就会跳转到error处。

2

AX,0x0820 ES,AX CH,0 DH,0 CL,2 AH,0x02 AL,1 BX,0 DL,0x00 0x13 error

; A驱动器(现在都只有一个驱动器了) ;调用磁盘BIOS

;柱面0 ;磁头0

;AH=0x02:读盘

;执行1个扇区

INT 0x13又是一个中断,这里AH是0x02的时候是读盘的意思,就是要把磁盘的内容写入到内存中。今天实验用到了4个软中断,都记在知识点里了。

至于CH\\DH\\CL\\AL三个寄存器呢,就分别是柱面号、磁头号、扇区号、执行的扇区数。那么含有IPL的启动区位于:C0-H0-S1 (Cylinder, magnetic Head, Sector) 然后ES\\BX和缓冲地址有关。 2、 缓冲区地址0x0820

MOV AL,[ES:BX] ; ES*16+BX -> AL

说是原来16位的BX只能表示0~65535,后来就引入了一个段寄存器,用MOV AL,[ES:BX] ; ES*16+BX -> AL这样的方法就可以表示更大的地址,就够当时用了,可以指定1M内存地址了。那么这里我们就是将0X0820赋值给ES,BX为0,这样ES*16后就访问0X8200的地址,那么就是讲软盘数据转载到0X8200到0X83ff的地方。 3、 试错以及读满10个柱面

MOV

AX,0x0820 ES,AX CH,0 DH,0 CL,2

MOV MOV MOV MOV

readloop:

MOV

SI,0

; 记录失败的次数,SI达到5就停止

retry:

MOV

AH,0x02

3

MOV MOV MOV INT JNC

ADD CMP JAE

MOV MOV

INT

和0X02功能不同

JMP

next: MOV ADD MOV ADD CMP JBE

MOV

ADD

AL,1 BX,0 DL,0x00 0x13 next SI,1 SI,5

error

AH,0x00 DL,0x00

0x13

retry

AX,ES

AX,0x0020 ES,AX CL,1 CL,18

readloop

CL,1 DH,1

4

; 没出错就跳到next

; SI加一 ; SI和5比较

; SI >= 5 时跳转到error

; 重置驱动器,看上面AH变为0X00

CMP JB

DH,2 DH,0 CH,1 CH,CYLS

readloop readloop

MOV ADD CMP JB

这里很明显,从CL\\DH\\CH依次循环计数,就是读取完一个磁头的扇区后换一个磁头,到这个柱面都结束了就换一个柱面,一直读完10个柱面。 4、 到正菜了,主程序操作系统

完成了启动区的制作,下一步开始编写操作系统代码。 最简单的操作系统: Fin: HLT Jmp fin

我们需要将操作系统本身的内容写到名为文件中,再把他保存到磁盘映像里,然后我们从启动区执行这个就行了。老作者用一个简单的例子告诉我们当我们向一张空软盘保存文件时,1)文件名会写在0x002600以后的地方;2)文件的内容会写在0x004200以后的地方。由于目前的启动区程序是从启动区后面开始(不包括启动区)加载到内存地址0x8200处的,所以磁盘0x4200的内容就会被加载到内存地址0xc200处,其中0xc200 = 0x8200 + 0x4200 - 512(启动区大小),现在我们就可从0xc200处加载我们自己写的程序用于执行了。需要在头加入org 0xc200,在启动区最后添加代码

5

jmp 0xc200。如此在装载完os后,即会跳到地址0xc200执行操作系统程序。 5、 让他显示图形模式

这里是中断调用显卡函数,设置显示模式,320*200*8位彩色模式,有256种颜色可以使用。

画面一片漆黑,大概是因为显存没有设置吧,下面的预存地址VRAM就是为显存留的, Video RAM,显卡内存,他的地址对应着屏幕上的像素。修改这个应该可以改颜色,黑色大概是默认老贼(把坑的作者叫老贼)也不说,唉,还要查。 6、 进入32位模式及保存画面模式

32位固然好,但是CPU32位模式不能调用BIOS功能。设定完画面模式后就要得到键盘状态。这里就是把画面的像素数、颜色数、键盘信息都保存了起来。和CYLS一样,都保存在了0X0FF0附近。

7、 C语言正式出场!小场面,戏份不足

这C关键部分真的是没讲嘛!老贼!下节的内容。 8、 文件的转换生成

流程图果然一目了然,但是真的难画,用网上的:

6

9、 一些知识点

A、

汇编指令 JC指令

JC,是“jump if carry”的缩写,意思是如果进位标志是1的话,就跳转。 JNC指令

JNC,是“jump if not carry”的缩写,意思是如果进位标志是0的话,就跳转。 JAE指令

JAE,是“jump if above or equal”的缩写,意思是大于或者等于时,跳转。

7

JBE指令

JBE,是“jump if below or equal”的缩写,意思是小于或者等于时,跳转。 JB指令

JB,是“jump if below”的缩写,意思是大于或者等于时,跳转。

B、 软中断

新学到的4个软中断

(1)INT 13h AH=02h: 读盘,即从磁盘中读取扇区 参数: AH: 02h

AL: 读入的扇区数 CH: 柱面号 CL: 扇区号 DH: 磁头号 DL: 磁盘号 ES:BX, 缓冲区地址 返回值:

CF: 错误置1,正确置0 AH: 返回值代码 AL: 实际读取的扇区数

(2)INT 13h AH=00h: 复位磁盘驱动 参数:

8

AH: 00h DL: 磁盘号 返回值: CF: 错误置为1

(3)INT 10h AH=00h: 设置显示模式 参数: AH: 00h AL: 显示模式 返回值:

AL = video mode flag / CRT controller mode byte

(4)INT 16H AH=02h: 获取键盘的状态信息

C、 文件的转换 工具 作用

输入 输出

cc1

gcc以gas汇编语言为基础,输出gas用的源程序 .c

gas2nask 把gas变换成nask能翻译的语法 .gas

nask

翻译成机器语言,生成目标文件.obj .nas

obi2bim 目标文件需与其他文件link才能编程真正可以执行的

机器语言,bim是二进制映像文件,是一种代替的形式

bim2hrm 为了能够实际使用,要做成适合本书操作系统要求的形式9

.gas

.nas .obj

.obj .bim.bim .hrb

二、遇到的问题及解决方法

1、

这里有些疑惑,说什么0X8000~0x83ff是留给启动区的,但是启动区明明是在0X7C00到0X7DFF的。8000留给启动区是作什么用途呢还有这中间的地址又是作什么用呢 目前没有解决。

三、程序设计创新点

1、硬盘知识

上面没有细讲到软盘的结构,是我对这个真的感兴趣,就去网上找了一些资料,果然

更全面。下面是内容: 概述

盘片(platter) 磁头(head) 磁道(track) 扇区(sector) 柱面(cylinder) 盘片 片面 和 磁头

硬盘中一般会有多个盘片组成,每个盘片包含两个面,每个盘面都对应地有一个读/写磁头。受到硬盘整体体积和生产成本的限制,盘片数量都受到限制,一般都在5片以内。盘片的编号自下向上从0开始,如最下边的盘片有0面和1面,再上一个盘片就编号为2面和3面。

10

如下图:

图1

扇区 和 磁道

下图显示的是一个盘面,盘面中一圈圈灰色同心圆为一条条磁道,从圆心向外画直线,可以将磁道划分为若干个弧段,每个磁道上一个弧段被称之为一个扇区(图践绿色部分)。扇区是磁盘的最小组成单元,通常是512字节。(由于不断提高磁盘的大小,部分厂商设定每个扇区的大小是4096字节)

11

图2

磁头 和 柱面

硬盘通常由重叠的一组盘片构成,每个盘面都被划分为数目相等的磁道,并从外缘的“0”开始编号,具有相同编号的磁道形成一个圆柱,称之为磁盘的柱面。磁盘的柱面数与一个盘面上的磁道数是相等的。由于每个盘面都有自己的磁头,因此,盘面数等于总的磁头数。 如下图

12

图3

磁盘容量计算

存储容量 = 磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数

图3中磁盘是一个 3个圆盘6个磁头,7个柱面(每个盘片7个磁道) 的磁盘,图3中每条磁道有12个扇区,所以此磁盘的容量为: 存储容量 6 * 7 * 12 * 512 = 258048

每个磁道的扇区数一样是说的老的硬盘,外圈的密度小,内圈的密度大,每圈可存储的数据量是一样的。新的硬盘数据的密度都一致,这样磁道的周长越长,扇区就越多,存储的数据量就越大。

13

磁盘读取响应时间

寻道时间:磁头从开始移动到数据所在磁道所需要的时间,寻道时间越短,I/O操作越快,目前磁盘的平均寻道时间一般在3-15ms,一般都在10ms左右。

旋转延迟:盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间,旋转延迟取决于磁盘转速。普通硬盘一般都是7200rpm,慢的5400rpm。 数据传输时间:完成传输所请求的数据所需要的时间。

小结一下:从上面的指标来看、其实最重要的、或者说、我们最关心的应该只有两个:寻道时间;旋转延迟。

读写一次磁盘信息所需的时间可分解为:寻道时间、延迟时间、传输时间。为提高磁盘传输效率,软件应着重考虑减少寻道时间和延迟时间。 块/簇 概述

磁盘块/簇(虚拟出来的)。 块是操作系统中最小的逻辑存储单位。操作系统与磁盘打交道的最小单位是磁盘块。

通俗的来讲,在Windows下如NTFS等文件系统中叫做簇;在Linux下如Ext4等文件系统中叫做块(block)。每个簇或者块可以包括2、4、8、16、32、64…2的n次方个扇区。 为什么存在磁盘块

读取方便:由于扇区的数量比较小,数目众多在寻址时比较困难,所以操作系统就将相邻的扇区组合在一起,形成一个块,再对块进行整体的操作。

分离对底层的依赖:操作系统忽略对底层物理存储结构的设计。通过虚拟出来磁盘块的概念,在系统中认为块是最小的单位。 Page:

14

操作系统经常与内存和硬盘这两种存储设备进行通信,类似于“块”的概念,都需要一种虚拟的基本单位。所以,与内存操作,是虚拟一个页的概念来作为最小单位。与硬盘打交道,就是以块为最小单位。 扇区、块/簇、page的关系 扇区: 硬盘的最小读写单元

块/簇: 是操作系统针对硬盘读写的最小单元 page: 是内存与操作系统之间操作的最小单元。 扇区 <= 块/簇 <= page

以上是网络搜寻的知识概要。

下面是我用虚拟机查看的硬盘基本信息(绕了一些弯路),

根据以上信息可以得出: 1,该硬盘总容量为10 GB 。

2, sectors表示总共有那么多个扇区。

3,其中Units = sectors of 1 * 512 = 512 bytes表示扇区的容量,这里好像没有柱面~

15

4,Sector size (logical/physical): 512 bytes / 512 bytes 扇区大小物理和逻辑都是512bytes。 5,I/O size (minimum/optimal): 512 bytes / 512 bytes 表示磁盘最小I/O读写大小512bytes。 6,Disk identifier表示硬盘标识符。

四、实验心得体会

最开始我们讲要编写一个一通电就能运行的程序。启动盘的第一个扇区是启动区,把

程序代码保存到这个扇区即可,这样就是一个通电就能运行的程序。这个程序最开始我们只是在屏幕上显示一个字符串信息“Hello,world!”,最终改造为一个IPL,即把其他程序装载进入内存的程序(从磁盘读取操作系统的程序)。先写个最简单的操作系统,即显示一个字符串即可,再慢慢添加新的功能。现在我们的操作系统能显示画面模式了,虽然还是全黑,但是很快就可以修改显存来更改显示颜色了,还是很期待的。

16

因篇幅问题不能全部显示,请点此查看更多更全内容