[自制简单操作系统] 9、命令行与应用程序 整体回顾

本文涉及的产品
文件存储 NAS,50GB 3个月
简介:


 

>_<" 下面是整个操作系统的编译框架,这里bootpack是主程序部分,通过调用其他.c文件里的功能函数及必须用汇编写的功能函数(naskfun.nas)来实现操作系统的各项功能,这里统一把他们编译集成到bootpack.bim中,ipl10.asm是引导部分,asmhead.asm是用汇编写的用来实现汇编和C语言的桥梁及一些初始32位编程的设置。此外为了实现命令行读取文件和运行应用程序的功能,这里把2号蓝色的部分文件也加载到操作系统。此外这里1号红色框内展示的是c文件和字库转换成obj的具体过程。

 

>_<" naskfunc.nas主要是C语言有些函数无法实现必须用汇编实现,这里就是那些汇编实现的功能函数:它们包括让CPU休眠的函数,开中断,关中断,IO读写,获取某个特定寄存器或给某个特定寄存器赋值函数以及far jmp功能函数。

naskfunc.nas

>_<" graphic.c主要是调色板、画矩形、显示字符、画主窗口、画鼠标等绘图的底层函数集,供bootpack.c调用实现绘制窗口等功能~

  graphic.c

>_<" dsctbl.c主要负责GDT IDT分段相关。这里我们要定义两个结构体:SEGMENT_DESCRIPTOR 和 GATE_DESCRIPTOR,如下:

复制代码
 1 /* dsctbl.c about GDT IDT that's Global Descriptor Table and Interrupt Descriptor Table*/
 2 struct SEGMENT_DESCRIPTOR {//8 bytes segment infomation,total 8192 parts [here similar to the method of the setting palette] 
 3     short limit_low, base_low;//address of segment base[high:mid:low=1:1:2]=4 bytes =32 bits
 4     char base_mid, access_right;//segment limit[high:low=1:2],only 20 bits = high byte's low 4 bits + low 2bytes' 16bits
 5     char limit_high, base_high;//segment property access[limit_high:right=1:1],only 12 bits = limit_high's high 4 bits + access_right's 8 bits
 6 };
 7 //PS 1):segment limit equals the number of GDT's effective bytes -1 
 8 //PS 2):the segment limit just only has 20 bits, which can represent 1MB, and the segment property has 1 bit flag, 
 9 //if this flag =1,and the limit's unit uses page to replace byte(here 1 page = 4kb) 
10 //PS 3):the segment property has 16 bits liking that:xxxx0000 xxxxxxxx 
11 //the high 4 bits are extended access
12 //the low 8 bits are:
13 //  0x00:unused description table
14 //  0x92:system exclusive,readable and writable,non-executable
15 //  0x9a:system exclusive,readable and non-writable,executable
16 //  0xf2:application useing,readable and writable,non-executable
17 //  0xfa:application useing,readable and non-writable,executable
18 
19 struct GATE_DESCRIPTOR {//
20     short offset_low, selector;
21     char dw_count, access_right;
22     short offset_high;
23 };
复制代码

  dsctbl.c

>_<" int.c文件中是中断初始化函数和int27号中断句柄函数~另外鼠标和键盘的中断句柄放在了他们各自的.c文件中~

  int.c

>_<" fifo.c是存放FIFO结构及相关操作的函数集合,这里FIFO结构是用来存放鼠标、键盘等消息,用来在中断和普通函数之间传递消息~下面是FIFO的结构体及其说明。其功能函数包括初始化、放入、取出、读取FIFO状态等函数。

1 struct FIFO32 {//FIFO缓冲区数据结构
2     int *buf;//缓冲区
3     int p, q, size, free, flags;//下一个数据的写入地址,下一个数据的读出地址,缓冲区的大小,free是缓冲区没有数据的字节数,flag是是否溢出
4         struct TASK *task;//当FIFO中写数据的时候将任务唤醒,用于记录要唤醒任务的信息
5 };

 
  
fifo.c

>_<" memory.c是内存管理相关函数集,首先要定义两个结构体:FREEINFO(可用信息结构体),MEMMAN(内存管理结构体)。功能函数中包括内存检测、内存初始化、内存分配、内存释放等相关函数,其中以4K倍数分配和释放内存即找到不小于size的最小4k倍数的内存释放。

复制代码
1 struct FREEINFO {    /* 可用信息 */
2     unsigned int addr, size;
3 };
4 struct MEMMAN {        /* 内存管理 */
5     int frees, maxfrees, lostsize, losts;
6     struct FREEINFO free[MEMMAN_FREES];
7 };
复制代码

  memory.c

>_<" mouse.c文件存放的是和鼠标消息处理相关,首先还是定义一个MOUSE_DEC的结构体,用来存放鼠标消息,如下。其功能函数包括鼠标事件响应句柄函数、鼠标使能函数、鼠标信息解码函数。其中鼠标信息解码是把鼠标发过来的原信息转换为相应的鼠标信息保存在鼠标结构体中。

1 struct MOUSE_DEC {
2     unsigned char buf[3], phase;
3     int x, y, btn;
4 };

  nouse.c
>_<" mtask.c是任务管理相关函数集,首先要声明4个结构体,分别是TSS32结构体,即任务状态段,用来保存任务的相关寄存器等信息,当发生中断时,将相关数据保存在此结构体中,当恢复中断时再将此结构体内的信息加载,从而实现中断前的保存现场和中断后的恢复现场的功能;Task结构体,即任务结构体,上面的TSS32仅仅是任务状态段,一个完整的任务还要包含任务的GDT号、优先级、FIFO缓冲区等信息,所以该任务结构体封装了这些信息用来保存一个任务;TASKLEVEL,是为了实现二维的优先级,所谓的二维优先级是当高优先级的层存在任务时低优先级的层的任务被屏蔽,任务只在高优先级层内进行切换;TASKCTL是任务管理结构体,负责记录所有任务的的信息。其功能函数包括初始化任务、分配任务、添加任务、删除任务、获取任务、切换任务、闲置任务、挂起任务等和任务相关的各种函数。
复制代码
 1 struct TSS32 {//task status segment 任务状态段
 2     int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;//保存的不是寄存器的数据,而是与任务设置相关的信息,在执行任务切换的时候这些成员不会被写入(backlink除外,某些情况下会被写入)
 3     int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;//32位寄存器
 4     int es, cs, ss, ds, fs, gs;//16位寄存器
 5     int ldtr, iomap;//有关任务设置部分
 6 };
 7 struct TASK {
 8     int sel, flags; /* sel用来存放GDT的编号 */
 9     int level, priority;
10     struct FIFO32 fifo;//把FIFO绑定到任务里
11     struct TSS32 tss;
12 };
13 struct TASKLEVEL {
14     int running; /* 正在运行的任务量数 */
15     int now; /* 这个变量用来记录当前正在运行的任务是哪一个 */
16     struct TASK *tasks[MAX_TASKS_LV];
17 };
18 struct TASKCTL {
19     int now_lv; /* 正在运行的level */
20     char lv_change; /* 在下次任务切换时是否需要改变LEVEL */
21     struct TASKLEVEL level[MAX_TASKLEVELS];//最多10个level
22     struct TASK tasks0[MAX_TASKS];
23 };
复制代码

 

 
  mtask.c

>_<" sheet.c主要是窗口管理函数集,主要解决多窗口叠加问题,其中涉及刷屏,窗口叠加等,这里的多窗口的管理的数据结构和上面多任务管理的数据结构很像,都是采用链表的思路,这样插入删除都比较快速,加速了处理速度。其中结构体SHEET,即图层结构体,包括图层的大小、位置、高度、设置信息、描述窗口的缓冲区;结构体SHTCTL,即图层管理结构体,包括所有图层信息和当前最上层的图层的标记等信息。功能函数包括初始化图层控制、获取图层、设定图层、刷新图层、设定图层高度、设定图层位置、释放图层等和图层操作相关的函数。

复制代码
 1 struct SHEET {//图层结构体
 2     unsigned char *buf;//所描绘内容的地址
 3     int bxsize, bysize, vx0, vy0, col_inv, height, flags;//图层大小,图层坐标,透明色色号,土层高度,存放有关图层的设定信息
 4     struct SHTCTL *ctl;
 5 };
 6 struct SHTCTL {//图层管理结构体
 7     unsigned char *vram, *map;
 8     int xsize, ysize, top;
 9     struct SHEET *sheets[MAX_SHEETS];
10     struct SHEET sheets0[MAX_SHEETS];
11 };//top存放最上面图层的高度,sheet0图层顺序混乱,要按照升序排列,然后将地址写入sheets中,方便使用
复制代码

  sheet.c

>_<" timer.c是定时器相关函数集,还是和图层和任务的管理方法很类似,首先定义一个计时器个体数据结构TIMER,用来保存一个定时器所需的信息,然后定义一个计时器管理数据结构TIMERCTL,用来整体管理计时器。功能函数包括初始化、分配、释放、设置以及中断处理函数。

复制代码
 1 struct TIMER{
 2     struct TIMER *next;//用来指下一个即将超时的定时器地址
 3     unsigned int flags;//flags记录各个寄存器状态
 4     unsigned int timeout;//用来记录离超时还有多长时间,一旦这个剩余时间为0,程序就往FIFO缓冲区里发送数据,定时器就是用这种方法通知HariMain时间到了
 5     struct FIFO32 *fifo;//消息队列
 6     int data;//该定时器标志,用来向消息队列写的标志信息
 7 };
 8 struct TIMERCTL {
 9     unsigned int count, next;//next是下一个设定时间点,count是累加时间轴
10     struct TIMER *t0;//记录按照某种顺序存好的定时器地址,头指针
11     struct TIMER timers0[MAX_TIMER];
12 };
复制代码

  timer.c

>_<" window.c从名字就能看出来主要负责绘制窗口的函数集。他们分别包括绘制窗口、绘制标题、显示字符串、绘制文本编辑框等函数~

  window.c

>_<" keyboard.c是键盘处理函数集,类似鼠标但是比鼠标的简单些,因为键盘在硬件设计上原来就考虑到了且其信息编码也不像鼠标的那么麻烦。所以,对于键盘处理的相关函数只有初始化、中断处理及附属的一些函数,没了鼠标的复杂的解码函数。同时也不用一个键盘结构体来存放消息,这里只用一个int类型的keydata0保存键盘消息。

  keyboard.c

>_<" file.c是负责读取磁盘映像中的文件读出,如最上面的那副图蓝色2的部分,把3个文件读到操作系统磁盘映像,当操作系统运行时,想把这些内容读出,就要把FAT解压,同时根据文件保存格式解析文件信息,因此这里要定义一个FILEINFO,即文件信息结构体。

复制代码
1 struct FILEINFO {
2     unsigned char name[8], ext[3], type;
3     char reserve[10];
4     unsigned short time, date, clustno;
5     unsigned int size;
6 };//修改MakeFile中的语句,将haribote.sys、ipl10.nas、make.bat这3个文件制成操作系统镜像
7 //这样磁盘映像中0x002600字节以后的部分8(文件名)+3(文件格式)+1(文件属性)+10(留待)+2(时间)+2(日期)+2(簇号)+4(大小)字节
复制代码

  file.c

>_<" console.c是命令行及命令行的黑框相关的函数集合。因为有命令行窗口所以就需要定义一个CONSOLE结构体来保存窗口SHEET和当前的位置及背景颜色。这里命令行窗口是一个新的任务,所以存在console_task用来作为该任务的入口,也就相当于bootpack.c里的main函数,这里的新任务就像一个独立的部分做独立的运行与处理,这一点可以在多任务那部分找到的。而其他的几个函数是负责被该主函数调用实现命令行功能的功能函数。对于命令行命令这里封装成cons_runcmd函数,然后通过调用下面的CMD命令函数,实现cmd命令的功能。这里只有mem、hit、type、dir、cls命令,如果今后想扩展只要在这里写心得cmd命令函数然后在con_runcmd里加入相应的处理即可以了。其中hlt命令是运行独立的程序,如最上面的图中把hlt.asm程序编译并载入磁盘映像,在此处调用读磁盘函数,加载该应用程序并执行,实现了操作系统上运行应用程序的功能。

1 struct CONSOLE {
2     struct SHEET *sht;//console窗口图层
3     int cur_x, cur_y, cur_c;//当前位置和颜色
4 };

 

  console.c

>_<" 相关链接~

上述工程代码链接:http://pan.baidu.com/s/1pJkGdwn

[自制简单操作系统] 1、从0-1到汇编再到c语言的奥秘:http://www.cnblogs.com/zjutlitao/p/3945852.html

[自制简单操作系统] 2、鼠标及键盘中断处理事件[PIC\GDT\IDT\FIFO]:http://www.cnblogs.com/zjutlitao/p/3961048.html

[自制简单操作系统] 3、内存管理和窗口叠加:http://www.cnblogs.com/zjutlitao/p/3979306.html

[自制简单操作系统] 4、计时器(线性表实现优化中断):http://www.cnblogs.com/zjutlitao/p/3983279.html

[自制简单操作系统] 5、杂七杂八(高分辨率和键盘输入):http://www.cnblogs.com/zjutlitao/p/3991839.html

[自制简单操作系统] 6、多任务(一):http://www.cnblogs.com/zjutlitao/p/3993403.html

[自制简单操作系统] 7、多任务(二)——任务管理自动化&任务休眠:http://www.cnblogs.com/zjutlitao/p/3994405.html

[自制简单操作系统] 8、多任务(三)——多窗口与优先级 :http://www.cnblogs.com/zjutlitao/p/3995814.html

 

 



本文转自beautifulzzzz博客园博客,原文链接:http://www.cnblogs.com/zjutlitao/p/4020014.html,如需转载请自行联系原作者

相关实践学习
基于ECS和NAS搭建个人网盘
本场景主要介绍如何基于ECS和NAS快速搭建个人网盘。
阿里云文件存储 NAS 使用教程
阿里云文件存储(Network Attached Storage,简称NAS)是面向阿里云ECS实例、HPC和Docker的文件存储服务,提供标准的文件访问协议,用户无需对现有应用做任何修改,即可使用具备无限容量及性能扩展、单一命名空间、多共享、高可靠和高可用等特性的分布式文件系统。 产品详情:https://www.aliyun.com/product/nas
相关文章
|
17天前
|
开发者 UED Windows
操作系统的演变:从命令行到图形界面
本文将探讨操作系统从最初的命令行界面(CLI)到现代图形用户界面(GUI)的发展历程。我们将回顾这一转变背后的技术驱动因素,以及它对用户交互和软件开发的影响。通过对比不同阶段的操作系统特点,我们可以更好地理解现代操作系统的设计哲学和未来趋势。
|
20天前
|
人工智能 数据可视化 vr&ar
操作系统的哲学:从命令行到图形界面的演变
【10月更文挑战第22天】 本文探讨了操作系统用户界面(UI)的发展,特别是从早期的命令行界面(CLI)到现代图形用户界面(GUI)的转变。通过分析这一转变背后的技术、社会和心理因素,我们不仅能够理解操作系统设计的演变,还能够洞察人类与技术互动方式的根本变化。文章采用总分总结构,先概述操作系统UI的历史发展,然后详细分析CLI和GUI的特点及其对用户的影响,最后总结这一转变对人类生活和技术发展的深远意义。
34 3
|
21天前
|
安全 算法 Unix
深入浅出操作系统:从基础概念到实践应用
【10月更文挑战第22天】本文旨在以浅显易懂的语言,为读者揭开操作系统的神秘面纱。我们将从操作系统的基本概念出发,逐步深入其核心功能与设计哲学,并通过具体代码示例,展示操作系统如何在实际中发挥作用。无论你是计算机科学的学生,还是对技术有浓厚兴趣的爱好者,这篇文章都将为你提供一次轻松愉快的操作系统之旅。
35 4
|
1月前
|
人工智能 Unix 人机交互
揭秘操作系统:从命令行到图形界面的演变之旅
【10月更文挑战第3天】本文将带你穿越时空,探索操作系统从简单的命令行界面(CLI)如何进化为今天广泛使用的图形用户界面(GUI)。我们将一探究竟,了解这一变革背后的故事和技术进步,同时通过代码示例,揭示现代操作系统如何实现这一转换。文章不仅回顾了历史,还展望了未来可能的技术革新,旨在激励读者思考操作系统设计的哲学和未来发展方向。
43 4
|
2月前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
25天前
|
人工智能 搜索推荐 物联网
操作系统的进化之路:从命令行到智能时代
【10月更文挑战第18天】 本文将带你穿越操作系统的演变历程,从最初的命令行界面到今天的智能操作系统。我们将探讨操作系统如何从简单的任务管理工具发展成为支持复杂应用程序和人工智能的多功能平台。
24 0
|
1月前
|
存储 API C语言
MacOS环境-手写操作系统-46,47-C语言开发应用程序
MacOS环境-手写操作系统-46,47-C语言开发应用程序
35 0
|
1月前
|
编译器 API C语言
MacOS环境-手写操作系统-45-C语言开发应用程序
MacOS环境-手写操作系统-45-C语言开发应用程序
44 0
|
2月前
|
物联网 iOS开发 MacOS
操作系统的演变之旅:从命令行到图形界面
在数字世界的长河中,操作系统作为计算机技术的核心,不断演进,塑造着我们与机器交互的方式。本文将带您穿越时空,探索操作系统从最初的命令行接口(CLI)到现代图形用户界面(GUI)的转变历程,揭示这一进程如何深刻影响我们的工作和日常生活。
49 7
|
2月前
|
物联网 Linux Android开发
探索操作系统的核心:从命令行到图形用户界面的演变
在数字时代的浪潮中,操作系统作为计算机硬件与软件之间的桥梁,其发展历程映射了技术进步的足迹。本文将通过浅显易懂的叙述,带领读者一探究竟,从早期的命令行界面(CLI)到现代图形用户界面(GUI)的转变,揭示这一变迁背后的意义及其对日常生活的深远影响。
43 1