[自制简单操作系统] 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
相关文章
|
1月前
|
人工智能 网络安全 数据安全/隐私保护
操作系统的演进:从命令行到图形用户界面
本文将带领读者穿越时光隧道,探索操作系统的发展历程。我们将从最早的命令行界面(CLI)开始,逐步走向现代的图形用户界面(GUI)。通过这篇文章,你将了解到操作系统如何适应技术变革,满足用户需求,以及它们是如何塑造我们今天数字生活的。让我们一起解锁操作系统的历史密码,发现那些改变了世界的创新故事。
|
17天前
|
物联网 iOS开发 MacOS
操作系统的演变之旅:从命令行到图形界面
在数字世界的长河中,操作系统作为计算机技术的核心,不断演进,塑造着我们与机器交互的方式。本文将带您穿越时空,探索操作系统从最初的命令行接口(CLI)到现代图形用户界面(GUI)的转变历程,揭示这一进程如何深刻影响我们的工作和日常生活。
30 7
|
16天前
|
物联网 Linux Android开发
探索操作系统的核心:从命令行到图形用户界面的演变
在数字时代的浪潮中,操作系统作为计算机硬件与软件之间的桥梁,其发展历程映射了技术进步的足迹。本文将通过浅显易懂的叙述,带领读者一探究竟,从早期的命令行界面(CLI)到现代图形用户界面(GUI)的转变,揭示这一变迁背后的意义及其对日常生活的深远影响。
24 1
|
25天前
|
Java 开发工具 Android开发
移动应用开发之旅:探索移动操作系统与应用构建的奥秘
【8月更文挑战第33天】在数字时代的浪潮中,移动应用已成为我们日常生活的一部分。本文将带您深入理解移动操作系统的工作原理,并揭示如何在这个多姿多彩的平台上开发出引人入胜的应用。我们将从基础概念出发,逐步深入到高级编程技巧,最终通过一个实际的代码示例,展示如何将理论应用于实践。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和灵感。让我们一起踏上这场激动人心的移动应用开发之旅吧!
|
26天前
|
人工智能 Linux iOS开发
操作系统的演变:从命令行到图形界面
在这篇文章中,我们将探索操作系统的发展历史,从最初的命令行界面到现代的图形用户界面。我们将了解操作系统的基本功能和重要性,以及它们如何随着时间的推移而演变。我们还将讨论一些著名的操作系统,如Windows、macOS和Linux,并了解它们的特点和优势。最后,我们将展望未来的操作系统发展趋势,包括人工智能和虚拟现实等新技术的影响。
|
26天前
|
数据可视化 Linux UED
探索操作系统:从命令行到图形界面的演变
【8月更文挑战第31天】 本文将带您穿越时空,探索操作系统的发展历程。我们将从最初的命令行界面(CLI)开始,逐步走向现代的图形用户界面(GUI)。通过深入浅出的语言和实际代码示例,我们将揭示操作系统如何影响我们的日常生活和工作。准备好跟随我们的脚步,一起揭开操作系统的神秘面纱吧!
|
27天前
|
安全 Linux 开发工具
探索Linux操作系统:从命令行到脚本编程
【8月更文挑战第31天】在这篇文章中,我们将一起潜入Linux操作系统的海洋,从最基础的命令行操作开始,逐步深入到编写实用的脚本。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和实用技能。我们将通过实际代码示例,展示如何在日常工作中利用Linux的强大功能来简化任务和提高效率。准备好了吗?让我们一起开启这段旅程,探索Linux的奥秘吧!
|
27天前
|
Rust 安全 编译器
【颠覆传统】Rust跨平台开发秘籍:如何轻松驾驭多操作系统,打造无缝兼容应用?
【8月更文挑战第31天】Rust语言凭借其内存安全、卓越性能及丰富的标准库支持,正逐渐成为跨平台开发的新宠。本文通过具体代码示例,展示如何用Rust编写可在多种操作系统上无缝运行的应用程序。Rust通过所有权、借用和生命周期等机制提升代码安全性,并在编译时检测潜在错误。其编译器支持广泛平台,包括Windows、macOS和Linux等,非常适合跨平台开发。此外,Rust还可用于开发复杂的GUI应用,利用GTK、Qt等成熟框架实现跨平台图形界面。无论开发命令行工具还是图形界面应用,Rust均能提供高效稳定的解决方案。
70 1
|
10天前
|
消息中间件 程序员 数据处理
探究操作系统中的进程间通信(IPC)机制及其在现代软件开发中的应用
本文深入探讨了操作系统中的核心概念——进程间通信(IPC),揭示了其在现代软件开发中的关键作用。通过对各种IPC机制如管道、消息队列、共享内存等的详细分析,本文旨在为读者提供一个清晰的理解框架,帮助他们掌握如何在实际应用中有效利用这些技术以实现进程间的协同工作。此外,文章还将探讨IPC在高并发环境下的性能优化策略,以及如何避免常见的IPC编程错误。通过结合理论与实践,本文不仅适合希望深入了解操作系统原理的技术人员阅读,也对那些致力于提升软件质量和开发效率的程序员具有重要参考价值。
16 0
|
1月前
|
Linux 人机交互 iOS开发
操作系统的演变之旅:从命令行到图形用户界面
【8月更文挑战第16天】 本文将带你穿越时空,探索操作系统的发展历程。我们将从最早期的命令行界面(CLI)开始,逐步走向现代的图形用户界面(GUI)。通过这篇文章,你将了解到操作系统如何适应技术变革,满足用户需求,并推动计算技术的发展。让我们一起见证这场由代码和创意交织而成的演变之旅吧!