一直觉得操作系统是一个很神秘的东西,这学期学习了操作系统原理后萌生了自己编写操作系统的想法,刚好到假期有时间,决定编写一个自己的操作系统。
第一天 开发前的准备
学习FAT12文件格式,使用自己编写的软盘映像启动计算机。
计算机在开机时会从第一个扇区读取软盘,但是只能读取512字节,也就是一个扇区;如果这个扇区最后2字节是0x55AA说明这是启动区,如果不是则说明不是启动区,bios转交给下一个启动设备来启动计算机。
成功显示 了自己定义的数据
之后再了解了解计算机开机引导过程, つづく
第二天 汇编复习和makefile
其实CPU的每个通用寄存器是有特定的用处的,虽然通用寄存器可以混用,但是如果按照用途使用寄存器会让程序更有条理,
比如:
AX-----累加寄存器
CX-----计数寄存器
DX-----数据寄存器
第一天写的“代码”是用纯数据写的,今天来写成汇编语言
第三天 制作真正的IPL
前几天有事一直没有继续,今天好不容易空下来继续写。
昨天了解了系统启动过程,但是昨天那个实在不能算是IPL,因为它只是执行了启动区那段的程序而已,今天首先需要制作一个能够加载操作系统的IPL
因为本IPL目前只能读取一个扇区,所以之后再将该程序改写成读取内容多一些的程序
接下来就要写“操作系统了”,先写一个小程序,作用是CPU暂停
程序很简单,一句HLT就行了,但是问题是如何让IPL读取这个程序并且执行
通过观察发现软盘映像中0x2600后存放文件名,0x4200后存放文件内容,这样的话只需要把程序保存在软盘的0x4200后就行了
第四天 导入C语言并修改显示画面
如果整个操作系统都使用汇编完成那工作量太大了,这时候需要将C语言导入到我们的系统中,并且完成汇编与C的结合,这个很简单,使用编译器将C语言编译成汇编,再把这个文件和汇编写的代码链接起来就可以了,之后再把这段代码添加到img文件中即可。
我勒个去又想起了这学期的windows编程,算坐标累死了,不过最后终于弄出来了
第五天 32位环境显示字符串
前一天做好了所谓的“系统界面”,今天需要让这个系统显示文字以及鼠标指针。
首先先想一想显示文字的原理,在这个空的操作系统中,目前是没有字体和字库的概念的,电脑中显示的文字都是加载磁盘中的字体,再通过调用实现的,所以首先我们需要一个字库,先来个最简单的字母A。如果好奇可以打开电脑中附件里的的造字工具,可以看到编辑文字的过程。我用记事本0和1写出来
就是这样的一个东西,现在可以不太好看,但是如果把0替换成白方块,1换成黑方块(黑白大小一样,因为是像素点),可以看出来是个字母A,现在以每行为单位输入进电脑就是
第一天 开发前的准备
学习FAT12文件格式,使用自己编写的软盘映像启动计算机。
计算机在开机时会从第一个扇区读取软盘,但是只能读取512字节,也就是一个扇区;如果这个扇区最后2字节是0x55AA说明这是启动区,如果不是则说明不是启动区,bios转交给下一个启动设备来启动计算机。
使用编译器将这段“代码”编译成软盘映像,使用软盘开机
之后再了解了解计算机开机引导过程, つづく
第二天 汇编复习和makefile
其实CPU的每个通用寄存器是有特定的用处的,虽然通用寄存器可以混用,但是如果按照用途使用寄存器会让程序更有条理,
比如:
AX-----累加寄存器
CX-----计数寄存器
DX-----数据寄存器
第一天写的“代码”是用纯数据写的,今天来写成汇编语言
第一句ORG指定了程序的装载地址,程序运行时装载到7c00这个地址中,之后FAT磁盘头代码不变,运行到后面给栈指针寄存器指定了程序的地址,之后重点来了,调用了显卡BIOS函数INT 0x10,让计算机显示字符的定义是:AH=0x0e,AL=“字符”,BX=“颜色代码”;既然了解了显卡BIOS那就按照格式填写就可以了,使用AL保存SI指向的数据,直到AL=0为之,读取结束。至此主程序主要部分就结束了
对了,之前为什么是7c00,因为规定启动区内容装载的范围是7c00~7dff,512字节
接下来就是makefile,makefile相当于一个智能版版批处理文件,可以省去很多重复的工作交给make自动处理,而且写这种程序磁盘头代码一般是不会变的,可以单独生成头代码,之后只需要写程序,再连接起来即可
今天主要复习了汇编语言,并且了解了显卡BIOS的INT 0x10中断, つづく
对了,之前为什么是7c00,因为规定启动区内容装载的范围是7c00~7dff,512字节
接下来就是makefile,makefile相当于一个智能版版批处理文件,可以省去很多重复的工作交给make自动处理,而且写这种程序磁盘头代码一般是不会变的,可以单独生成头代码,之后只需要写程序,再连接起来即可
今天主要复习了汇编语言,并且了解了显卡BIOS的INT 0x10中断, つづく
第三天 制作真正的IPL
前几天有事一直没有继续,今天好不容易空下来继续写。
昨天了解了系统启动过程,但是昨天那个实在不能算是IPL,因为它只是执行了启动区那段的程序而已,今天首先需要制作一个能够加载操作系统的IPL
这段代码告诉计算机应该读取C0-H0-S1的的程序,启动计算机
计算机成功执行程序,但是现在那段扇区还没有程序,所以无法启动
接下来就要写“操作系统了”,先写一个小程序,作用是CPU暂停
程序很简单,一句HLT就行了,但是问题是如何让IPL读取这个程序并且执行
通过观察发现软盘映像中0x2600后存放文件名,0x4200后存放文件内容,这样的话只需要把程序保存在软盘的0x4200后就行了
现在只需要在软盘中插入IPL程序,然后把这段程序放在磁盘中就行了。
和预期结果相同,说明这段程序执行成功。
如果整个操作系统都使用汇编完成那工作量太大了,这时候需要将C语言导入到我们的系统中,并且完成汇编与C的结合,这个很简单,使用编译器将C语言编译成汇编,再把这个文件和汇编写的代码链接起来就可以了,之后再把这段代码添加到img文件中即可。
这段代码只有一个功能,还是hlt,但是这次程序主体是用C编写的,在C语言中调用了汇编的代码;其中左侧是c语言,右边是编译器生成的汇编。
现在重头戏来了,让屏幕上显示其他内容。这就牵扯到了内存写入,屏幕中显示的内容都是保存在VRAM中的,想让屏幕显示不同的内容,就得修改VRAM中的内容,但是C语言中没有向某内存地址写入数据的函数,所以还需要用汇编自己写一个,这个很简单。
成功让屏幕显示了绿色。现在我再让屏幕显示条纹 ,这个更简单了,只需要把中间的内存修改语句修改为
write_memint(i,i&0x0f);就行了
第四天 操作系统基本界面
昨天终于让屏幕显示了其他内容,但是在显示内容时是直接向VRAM赋值的色号,这样很不方便,为此首先先做一个调色板,把常用颜色录入进去。
现在重头戏来了,让屏幕上显示其他内容。这就牵扯到了内存写入,屏幕中显示的内容都是保存在VRAM中的,想让屏幕显示不同的内容,就得修改VRAM中的内容,但是C语言中没有向某内存地址写入数据的函数,所以还需要用汇编自己写一个,这个很简单。
然后在C语言中调用这个函数就行了 ,接下来写修改屏幕内容的C语言。因为当前的显示模式地址在0xa0000~0xaffff中,我们只需要修改这段内容即可。
最终的显示效果终于不是简单的黑屏了
成功的显示了条纹。
明天将绘制基本的一些图形,还有显示鼠标指针等功能, つづく
明天将绘制基本的一些图形,还有显示鼠标指针等功能, つづく
昨天终于让屏幕显示了其他内容,但是在显示内容时是直接向VRAM赋值的色号,这样很不方便,为此首先先做一个调色板,把常用颜色录入进去。
调色板是由RGB颜色定义的,所以定义了这个以后只需要把调色板输入到显卡中就可以了,其中就涉及到了设备访问,使用汇编的IN、OUT语句访问设备
其中汇编语句很简单就不放出来了,最后再次运行程序发现条纹的颜色按照调色板颜色顺序显示了。
接下来解决了调色板,就要开始研究如何在屏幕上画图,以便显示出想要的系统界面。首先就是最简单的矩形
在VRAM中内存地址的计算是0xa0000+x+y*320(两个数字可能是其他值,取决于显示模式),所以需要写一个函数来填充矩形
接下来解决了调色板,就要开始研究如何在屏幕上画图,以便显示出想要的系统界面。首先就是最简单的矩形
在VRAM中内存地址的计算是0xa0000+x+y*320(两个数字可能是其他值,取决于显示模式),所以需要写一个函数来填充矩形
然后在主函数调用即可
成功显示了3个矩形,接下来要把坐标定好让他显示一个相对好看的界面
前一天做好了所谓的“系统界面”,今天需要让这个系统显示文字以及鼠标指针。
首先先想一想显示文字的原理,在这个空的操作系统中,目前是没有字体和字库的概念的,电脑中显示的文字都是加载磁盘中的字体,再通过调用实现的,所以首先我们需要一个字库,先来个最简单的字母A。如果好奇可以打开电脑中附件里的的造字工具,可以看到编辑文字的过程。我用记事本0和1写出来
再通过与操作就可以判断出每行需要显示的像素点了
学过数电的人应该知道,判断某位是否为1就让这个数字与这位的大小进行与操作即可。
终于显示出字母A了,如果要显示其他字母原理也相同。
终于显示出字母A了,如果要显示其他字母原理也相同。
如果这样一个个写字库太麻烦了,这里就用到了开源库,有现成的ASCII码表,直接转换一下导入即可
之后要进行的就是字符串的输出,原理和字母差不多,就不多说了
之后要进行的就是字符串的输出,原理和字母差不多,就不多说了