操作系统实验第三天:进入32位模式并导入C语言

一、实验主要内容
内容1:制作真正的IPL
因为磁盘最初的512字节是启动区,所以要装载下一个512字节的内容。添加的内容如下:
在这里插入图片描述

将harib00a复制粘贴到tolset来。新出现的指令总结如下:
JC:jump if carry,即如果进位标志位为1,就跳转。
INT 13:调用BIOS的13号函数,但是不知道它是干什么用的。查询网页了解到,是控制器驱动诊断的意思。
磁盘读、写、扇盘校验以及寻道:
AH=0x02;读盘,本次使用的功能
AH=0x03;写盘
AH=0x04;校验
AH=0x0c;寻道
AL=处理对象的扇区数;(只能同时处理连续的扇区)
CH=柱面号&0Xff
CL=扇区号(0-5位)|(柱面号&0x300)>>2;
DH=磁头号;
DL=驱动器号;
ES:BX=缓冲地址;(校验及寻道时不使用)
返回值:
FLACS.CF(进位标志)0:没有错误,AH0
FLAGS.CF==1: 没有错误,错误号码存入AH内(等于reset)
CH、CL、DH、DL分别是柱面号、扇区号、磁头号、驱动器号。
一张软盘有80个柱面(0-79)、两个磁头(0-1)、18个扇区(1-18),一个扇区有512个字节。所以一张软盘的容量可以算出是1440KB。
含有IPL的启动器,位于C0-H0-S1(柱面0,磁头0,扇区1)。
关于缓冲区地址的问题,为了解决一个BX只能表示0x0-0xffff的值,最大只有64K的问题,增加了一个叫EBX的寄存器。但是在这之前,使用的是起辅助功能的段寄存器。以ES:BX的形式来表示地址,比如MOV AL,[ES:BX],这样的地址形式表示ES*16+BX的地址的内存地址。
因为我们一般都会省略段寄存器,所以系统会默认将DS作为段寄存器,所以需要将DS事先指定为0。
内容2:试错
由于软盘很不可靠,有时会发生不能读数据的情况。所以每次读取失败就让它再读一次就可以了。我们设置为五次重试,再不行就报错。代码部分如下:
在这里插入图片描述

这里出现了几个新的指令:
JNC:另一个条件跳转指令,jump if not carry,即进位标志为0的话就跳转。
JAE:也是条件跳转指令,jump if above or equal,即在大于或等于的时候跳转。
AH=0x00,DL=0x00,INT=0x13,这是在读盘之前的系统复位操作。
内容3:读到18扇区
这次添加的新代码部分如下:在这里插入图片描述

出现了新的指令:
JBE:也是跳转指令,即jump if below or equal,即在小于或等于的时候跳转。
在代码中可以看到,要读下一个扇区,只需要给CL加1,给ES加上0x20即可,因为ES还要乘16,所以也就相当于是加了512个内存地址,当然,也可以直接给BX加上512,效果是一样的。
虽然说代码中不是非要用循环才行,在调用读盘函数的INT 0x13的地方,只要将AL的值设置为17即可,就可以一下子将扇区2-18共17个扇区的数据完整的读进来。之所以使用循环,是因为会在下一次的程序中出现问题,所以特意用循环来一个一个扇区的读盘。
内容4:读入10个柱面
在这里插入图片描述

新出现的指令JB:是jump if below的缩写。即如果小于的话,就跳转。
还有一个新指令,就是在程序开头使用的EQU指令。这相当于一个#define命令,用来声明常数。CYLS EQU 10意思是“CYLS=10”。
然后启动区程序写的差不多了。如果算上最开始加载的启动扇区,现在已经能够装入180KB。
内容5:着手开发操作系统
先编写一个很短小的程序,就只让它HLT。
Fin:
HLT
JMP fin
然后按下面这样操作,将文件保存在磁盘映像haribote.img中:
1.使用make install指令,将磁盘映像文件写入磁盘。
2.在windows里打开那个磁盘,把haribote.sys保存到磁盘。
3.使用工具将磁盘备份为磁盘映像。
当然,我们借助之前使用过的工具:edimg.exe就可以直接得到磁盘映像和文件。
查看生成的二进制文件之后可以看到F4 EB FD,这也就是haribote的内容。
总结为:一般想一个空软盘保存文件时,
1)文件名会写在0x002600以后的地方。
2)文件的内容会写在0x004200以后的地方。
内容6:从启动区执行操作系统
因为程序是从启动区开始,把磁盘上的内容装载到内存0x8000号地址,所以磁盘就应该位于0x8000+0x4200=0xc200的位置。
所以,就往haribote.nas里加上ORG 0xc200,然后在ipl.nas处理的最后加上JMP 0xc200这里指令。
内容7:确认操作系统的执行情况
考虑到之后要做windows那样的画面,所以切换一下画面模式。文件hariboog如下:
在这里插入图片描述

设定AH=0x00后,调用显卡BIOS的函数,就可以切换显示模式。
设置显卡模式(video,mode)
AH=0x00
AL=模式:(省略了一些不重要的画面模式)
0x03: 16色字符模式
0x12: VGA图形模式,6404804位彩色模式,独特的4面存储模式
0x13: VGA图形模式,3202008位彩色模式,调色板模式
0x6a: 扩展VGA图形模式,8006004位彩色模式,独特的4面存储模式
暂且选择0x13画面模式,因为8位彩色模式可以使用256种颜色,这一点看来不错。
Make run之后,应该看到画面一片漆黑。
在这里插入图片描述

内容8:32位模式前期准备
CPU有16位和32位两种模式,但是32位模式下可以使用的内存容量更大,且CPU在32位模式下可以有自己的自我保护功能。
32位下不可以调用BIOS功能,因为BIOS是16位下写的,所以所有想用BIOS来写的功能,都放在开头做。
BIOS要做的事情,除了画面模式的设定之外,就是得到键盘状态,即ON or OFF.修改后的代码部分如下:
在这里插入图片描述

设置画面模式之后,还把画面模式的信息保存在了内存里。这是因为,以后我们可能要支持各种不同的画面模式,需要把现在的设置信息保存起来以备后用。
启动的信息称为:BOOT_INFO
[VRAM]里保存的是0xa0000。VRAM指的是显卡内存,它的各个地址都对应着画面上的像素。可以利用这一机制在画面上绘制出五彩缤纷的图案。
画面的像素数,颜色数,以及从BIOS取得的键盘信息都保存了下来。保存的位置在内存0x0ff0附近。
内容9:开始导入C语言
c部分代码如下:
在这里插入图片描述

goto指令是新出现的,相当于汇编语言中的JMP,实际上也是被编译成JMP指令。
由“/”和“/”括出来的部分是注释,正如这里所写的那样,C语言种不能使用HLT,也没有DB的命令。
Bootpack.c变成机器语言的步骤:
首先,使用ccl.exe从bootpack.c生成bootpack.gas。cc1是C编译器,可以将c语言程序编译成汇编语言源程序,输出是gas用的源程序。
第二步,使用Gas2nask.exe从bootpack.gas生成 bootpack.nas。gas2nask是能将gas文件转换成nask文件的程序。
第三步,使用Nask.exe从bootpack.nas生成bootpack.obj。用nask制作obk文件,即目标文件,但目标文件必须与其他文件链接后才能变成真正可以执行的机器语言。
第四步,使用Obi2bim.exe从bootpack.obj生成bootpack.bim。obj2bim是将必要的目标文件全部连接上,bim是一个二进制映像文件。映像文件其实不是文件本来的状态,是一种代替。
最后,使用Bim2hrb.exe从bootpack.bim生成bootpack.hrb。
内容10:实现HLT
为了使计算机最后还是能处于HALT状态,写了下面程序:
在这里插入图片描述

然后再bootpack.c中事先声明之后,调用这个文件中的_io_hlt函数。
Make run之后的结果:
在这里插入图片描述

二、遇到的问题及解决方法
这次实验进行的比较顺利,按着书上的步骤下来没有遇到什么操作上的问题。只有在实验过程中对扇区的读取代码过程有些问题,如下:
在这里插入图片描述

当时不是很懂这个循环的过程,后来和旁边的同学一起讨论了一下这个执行过程,因为readloop是在上面retry的上面,那么每次在比较之后如果还没有读够18个扇区,那么就到上面readloop部分,然后往下走,retry部分读的就是在加一之后的扇区部分,够了18之后,那么就将扇区位置指到1,需要将磁头从0更新到1。整个的思路过程大就这样。
三、程序设计创新点
1、创新点1
书上写着,VRAM指的使显卡内存,也就是用来显示画面的内存,它的各个地址都对应着画面上的像素。那么考虑可以通过在C代码中对背景颜色进行修改。
VRAM的范围是0xa0000-0xaffff,代码修改如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
如果循环设置为一个常数,也可以随意切换背景色,如上图。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值