30天自制操作系统------命令行

来源:互联网 发布:淘宝csv数据包制作 编辑:程序博客网 时间:2024/05/29 17:06


    实现一个命令行任务,首先需要一个命令行窗口,然后需要一个命令行任务,在命令行任务中实现命令行的相关功能。

 

一、创建一个命令行窗口

创建命令行窗口就是在屏幕上画个窗口出来,实际就是操作显存,这一部分利用前面已经实现的makewindow8函数即可实现。

 

二、创建一个命令行任务

有了命令行窗口,我们再来实现命令行的功能。

(1)光标闪烁功能

      在刚开始做命令行时,命令行的功能就是光标闪烁即可,也就是说命令行任务中需要一个定时器来控制光标色块的颜色,使之产生闪烁的效果。在HariMain函数中已经实现过光标的闪烁功能,该功能还需要使用一个FIFO队列,通过在队列中存放不同的数值,可以使得光标的颜色进行变换,实现方法与HariMain中光标闪烁的实现方法相同。

     

(2)切换输入窗口

     目前用户使用键盘输入数据时,所有的数据都被task_a给接收了,新建的命令行窗口完全就是个摆设,为了使得命令行窗口可以接收数据,在HariMain中设置整型变量key_to

key_to=0时,task_a接收键盘数据;key_to=1时,命令行任务接收键盘数据。键盘数据都保存在各任务的FIFO中。而key_to值的切换则是由主程序HariMain负责监听Tab键来进行切换的,同时在切换窗口的同时,窗口标题栏的颜色发生改变。

 

(3)实现字符输入

     只要各个任务可以接收到字符编码,那么该任务就可以实现字符输入的功能,各个任务接收到的字符编码都保存在其FIFO中,在《30天自制操作系统》中,作者将FIFOTASK绑定,结构体FIFO中还有个TASK的指针成员,作者的代码运行起来没有问题,但是我根据作者的步骤编写出来的操作系统就运行不起来,在VMWare上就会出现导致虚拟CPU关闭的错误。

所以我直接将命令行任务的FIFObookpack.c定义为全局变量来避免此问题。

 

(4)符号的输入

     键盘上的有些按键与SHIFT键结合就可以产生其他字符,为了使得编写的操作系统可以显示这些字符,我们需要监测SHIFT键的状态,SHIFT键的按下与抬起都有相应的编码,只需要监测是否有这些编码产生即可。

 

按下

抬起

SHIFT

0x2a

0xaa

SHIFT

0x36

0xb6

 

不同字符的编码不同,为了实现一个按键可以产生两个字符,我们需要两套keytable与之对应,大概是因为日本的键盘与中国键盘有所不同,作者的keytable并不能与我的键盘完全对应,所以我对keytable做了些许修改,修改之后的keytable如下:

static char keytable0[0x80]={

  0,  0,'1','2','3','4','5','6','7','8','9','0','-','=',  0,  0,

'Q','W','E','R','T','Y','U','I','O','P','[',']',  0,  0,'A','S',

'D','F','G','H','J','K','L',';',0x27,  0,  0,'\\','Z','X','C','V',

'B','N','M',',','.','/',  0,'*',  0,' ',  0,  0,  0,  0,  0,  0,

  0,  0,  0,  0,  0,  0,  0,'7','8','9','-','4','5','6','+','1',

'2','3','0','.',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

  0,  0,  0,0x5c, 0,  0,  0,  0,  0,  0,  0,  0,  0,0x5c, 0,  0

};

static char keytable1[0x80]={

  0,  0,'!','@','#','$','%','^','&','*','(',')','_','+',  0,  0,

'Q','W','E','R','T','Y','U','I','O','P','{','}',  0,  0,'A','S',

'D','F','G','H','J','K','L',':',0x22,  0,  0,'|','Z','X','C','V',

'B','N','M','<','>','?',  0,'*',  0,' ',  0,  0,  0,  0,  0,  0,

  0,  0,  0,  0,  0,  0,  0,'7','8','9','-','4','5','6','+','1',

'2','3','0','.',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

  0,  0,  0,0x5c, 0,  0,  0,  0,  0,  0,  0,  0,  0,0x5c, 0,  0

};

 

(5)大小写字母转换

为了尽可能保证键盘输入的正确性,字母的大小写转换也是非常必要的。在我们使用电脑的过程中,控制大小写的就只有两个键:SHIFT键和Capslock键。我们可以根据SHIFT键以及Capslock键的状态来区分输入的是大写字母还是小写字母。

CapsLock状态

SHIFT状态

大写/小写

OFF

OFF

小写

OFF

ON

大写

ON

OFF

大写

ON

ON

小写

 

SHIFT键状态的监测只需要根据其按键编码来监测即可,CapsLock键的状态也可以根据其按键编码来监测,但是因为BIOS中保存有CapsLock键的状态,所以我们采用的方式是通过binfo中的leds来查询其状态。

至于大小写字母的转换,因为大写字母的ASCII编码比小写字母的ASCII编码要小0x20,所以是很好转换的。

 

(6)控制光标闪烁

     目前我们的操作系统有两个窗口:task_aconsole

     当我们选中task_a任务时,希望只有task_a窗口的光标闪烁;当选中console任务是,希望只有console窗口的光标闪烁。

 实现该功能的思路是每个窗口都有个变量cursor_c来记录其光标的颜色,根据定义其正常的取值范围为0~15,那么我们可以在对其光标颜色作修改之前,先判断其cursor_c的取值是否在正常范围内,若在正常范围内,则对其作修改,若不在,则不对其作修改。也就是说当某个窗口的cursor_c取值异常时,那么该窗口的光标就不再闪烁。

之前我们使用Tab键实现任务的切换,在HariMain中使用Tab键进行任务切换时顺便可以对task_acursor_c赋值,当任务要切换到task_a时,对cursor_c正常赋值,当任务要切换到console是,给cursor_c赋个非正常值,这样就实现了task_a的光标闪烁的控制。

同时为了控制命令行任务中的光标闪烁,还需要通过命令行的FIFO来给命令行发送光标的控制信息,在实现过程中定义2表示命令行窗口光标ON3表示命令行窗口光标OFF

 

(7)对回车键的支持

命令行任务对回车键的支持仅仅通过监听回车键的按键编码即可,监听到回车键之后,光标闪烁位置变为下一行的起始位置,当然下一行要首先显示提示符。

 

(8)对窗口滚动的支持

     命令行对窗口滚动的支持,实际上就是将命令行窗口中的像素全都上移一行,最后一行全部涂黑即可。

 

9)对相关命令的支持

用命令行执行相关指令一般都是在按下回车键之后,在这之前对于任何字符输入我们都需要将其保存在cmdline字符数组中,当按下回车键之后,判断cmdline中存储的内容是啥,然后再作出相关处理。

 

10dir命令 :显示文件名等信息

显示文件名等信息需要读取磁盘,但是当前系统处于32位模式,无法使用BIOS,但是在前面的实现过程中,我们已经读取了很多内容到内存0x00100000~0x00267fff1440KB)中去。又因为一般像一个空软盘保存文件时,文件名会写在0x002600以后的地方,文件的内容会写在0x004200以后的地方,所以我们可以从地址0x00100000+0x002600开始的地方开始查找相关文件信息。根据

根据作者实验可得,每个文件信息使用32个字节来保存,所以文件信息最多存放(0x004200-0x002600)/32=244个。

文件信息的结构如下:

struct FILEINFO

{

unsigned char name[8],ext[3],type;/*文件名,扩展名,文件属性信息*/

char reserve[10]; /*为了将来可能会保存更多的文件信息而预留*/

unsigned short time,date,clustno; /*存放文件的时间,日期,簇号(扇区)*/

unsigned int size;/*文件大小,单位为字节*/

};

说明:文件名第一个字节为0x00,代表这一段不包含任何文件名信息;

          文件名第一个字节为0xe5,代表这一段这个文件已经删除。

 

type值的说明:0x01  -----只读文件(不可写入)

                  0x02  -----隐藏文件

  0x04  -----系统文件(比如磁盘名称等)

  0x10  -----目录

原创粉丝点击