这里是我需要写的 《操作系统原理及实践》的草稿,只是一个框架,会有一些省略的地方,比如图表,文字也是一些大纲性质的,并没做很细致的说明,但是代码是可以保证的,代码分析相对简单,为什么这么做的说明也是一个提示性的文字,这些会在后面进行补充。如果有心学,并没有太大的困难。
===============================================================================================================
这里,我将通过一个小型的操作系统来讲解操作系统原理,这个操作系统我把他命名为Lenix,因为这个系统是学习用的,所以用了Learn这个词,然后随大流的用了ix后缀,就有了Lenix这个名字,也就是学习用的os。呵呵,我有两个操作系统了,一个SHEMOX,一个lenix。
因为是学习用的,所以我就避开了一些很重要,但实际上不属于操作系统核心的内容,比如保护模式、系统引导。这两项内容,让很多想动手的人望而却步。当然,这也有很大一部分原因是目前流传的资料误导而造成的。这些所谓的操作系统编写教程或者书籍,一开篇就讲这两样,而且还是用汇编来写的代码,写的人也许懂,但可以保证,单单看这些资料,肯定看不懂,还得去找相应的保护模式的资料,学了一遍,在会过头来学操作系统。通常情况就是学会保护模式了,能引导机器了,就以为自己能写操作系统了。但实际上到了这一步,连OS的边都没摸着。废话不多说了。
Lenix使用BC3.1,在DOS下开发。BC31可以编译汇编文件,这就不必使用多种开发工具了。当然,这也会受到一定的限制,就是一些286以后的指令不能使用,比如pusha,还有就是寄存器的使用会受到限制,现在的汇编中,可以使用任何一个寄存器作为基址寄存器,可以写 mov ebx,[eax + 8]这样的程序,但是在BC31中,只能用bx、bp来做基址寄存器,也就是必须写为 mov ax,[bx + 2],注意16位和32位的区别啊。
而硬件方面,甚至可以跳过硬件初始化的过程,因为DOS已经初始化好了。但是为了给大家一个比较完整的概念,Lenix还是会对基本的硬件进行初始化,其实最主要的就是初始化8259中断控制器和时钟。别的硬件暂时还不用。在正式进入操作系统理论学习前,还是要进行一个基础训练的。
实验环境嘛,现在虚拟机很多,任选一个就可以,我选择了VPC,因为VPC的文件夹共享功能很方便。我是把一个文件夹设置为VPC中的一个盘,用VS写程序,然后在VPC的DOS中进行编译。可以方便的利用当前方便的工具。
第一个基础是:直接写屏。
感觉比较怪异吧?为什么是这个呢?这时因为,直接写屏是为了调试。调试就要输出信息,直接写屏是输出信息的第一步。所以直接写屏程序是写操作系统第一步。
定义一个变量
word_t con_attr;
这个变量是显示属性,可以通过改变这个变量来改变字符的显示状态。
word_t类型是在type.h文件中定义的
typedef unsigned char byte_t;
typedef unsigned short word_t;
定义几个函数
/*
* Con_write_byte:向屏幕指定位置写入一个字节
*/
void Con_write_byte(int pos,const byte_t dat)
{
pos *= 2; /* 计算具体的内存地址,相对显存起始地址 */
asm{
mov bx,pos;
mov ax,con_attr;
push es ; /* 保存ES段寄存器 */
mov dx,0B800h
mov es,dx; /* 将ES设置为显存段 */
mov al,dat
mov es:[bx],ax; /* 写显存 */
pop es; /* 恢复ES段寄存器 */
}
}
/*
* Con_cls:清屏。
*/
void Con_cls(void)
{
int x = 0;
while ( x < 80*25 )
Con_write_byte(x++,0x0720);
}
/*
* Con_write_string:向屏幕输出数据,遇到0则停止输出,但是数据不一定是字符串,当然,我的本意是输出字符串。
*/
int Con_write_string(int x,int y ,const char * string)
{
const char * str;
str = string;
x += y * 80;
while( *str)
Con_write_byte(x++,(const byte_t)*str++);
return str - string;
}
/*
* Con_write:向屏幕输出指定长度的数据,不一定是字符。
*/
void Con_write(int x,int y,const byte_t * buffer,int size)
{
x += y * 80;
for( ;size--; )
Con_write_byte(x++,*buffer++);
}
测试一下:
void main(void)
{
Con_cls();
Con_write_string(40,10,"lenix write consol");
}
看看测试结果

在这里,假设显示模式是80*25。
直接写屏,其实就是直接操作显存,在通常情况下,显存是安排在物理内存0xB8000处,在字符模式下,每个字符用两个字节表示,高字节是显示属性,用来控制字符的前景和背景,低字节就是字符本身。具体的格式这里就不画了,如果出书了,在书上画。
在处理显存的时候,直接将段寄存器设置为B800,利用CPU处理地址的方式,
本文介绍了一个名为Lenix的学习用操作系统,旨在通过一个小型的BC3.1环境在DOS下开发,简化操作系统核心内容的学习。重点在于提供一个基础训练,如直接写屏等操作,帮助初学者理解并实践操作系统的基本原理。

被折叠的 条评论
为什么被折叠?



