[自制简单操作系统] 3、内存管理和窗口叠加

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


 

 

 

1、本次主要进展

>_<" 这次主要学习了系统内存管理和窗口叠加~由于上两篇都做了详细的框架说明和介绍,这里直接上代码!


 

2、文件及函数构成

>_<" 这里和第二篇相比,把鼠标和键盘的相关函数独立出来放进各自相应的文件中,并主要在内存管理和窗口叠加进行探索,同时还有部分代码整理~

  bootpack.h

 

PS: 这里因为多了几个.c文件,所以makeFile中OBJS_BOOTPACK要把他们加进来~

OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj

PS: 为了整体清晰,上面的结构图把bootpack.h和字库文件没有列入~


 

3、主函数分析

复制代码
  1 /* bootpack */
  2 
  3 #include "bootpack.h"
  4 #include <stdio.h>
  5 
  6 void make_window8(unsigned char *buf, int xsize, int ysize, char *title);
  7 
  8 void HariMain(void)
  9 {
 10     struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
 11     char s[40], keybuf[32], mousebuf[128];
 12     int mx, my, i;
 13     unsigned int memtotal, count = 0;
 14     struct MOUSE_DEC mdec;
 15     struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
 16     struct SHTCTL *shtctl;
 17     struct SHEET *sht_back, *sht_mouse, *sht_win;
 18     unsigned char *buf_back, buf_mouse[256], *buf_win;
 19 
 20     init_gdtidt();//在dsctbl.c中,负责分区和中断分区初始化[包括键盘和鼠标中断设定]
 21     init_pic();//在int.c中,负责中断初始化(硬件)
 22     io_sti();//在naskfunc.nas中,仅仅执行STI指令,是CLI的逆指令,前者是开中断,后者是禁止中断
 23     fifo8_init(&keyfifo, 32, keybuf);//在fifo.c中,负责缓冲区初始化(缓冲区结构体,大小,缓冲区首址)
 24     fifo8_init(&mousefifo, 128, mousebuf);
 25     /*这里IMR是(interrupt mask register),意思是“中断屏蔽寄存器”,是8位寄存器,分别对应8路IRQ信号,如果一路是1则该路被屏蔽,因为键盘中断是IRQ1,鼠标中断是IRQ12,且PIC分主从2个,从PIC连接主PIC的IRQ2,所以想要有鼠标和键盘中断,要PIC0的IRQ1和IRQ2,和PIC1的IRQ4*/
 26     io_out8(PIC0_IMR, 0xf9); /* (11111001) */
 27     io_out8(PIC1_IMR, 0xef); /* (11101111) */
 28 
 29     init_keyboard();//初始化键盘控制电路
 30     enable_mouse(&mdec);//使能鼠标
 31     //memman需要32KB内存
 32     memtotal = memtest(0x00400000, 0xbfffffff);//计算总量memtatal
 33     memman_init(memman);
 34     memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff 将现在不用的字节以0x1000个字节为单位注册到memman里*/
 35     memman_free(memman, 0x00400000, memtotal - 0x00400000);
 36 
 37     init_palette();//调色板
 38     shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);//图层初始化函数
 39     sht_back  = sheet_alloc(shtctl);//分配一个背景窗口
 40     sht_mouse = sheet_alloc(shtctl);//分配一个鼠标窗口
 41     sht_win   = sheet_alloc(shtctl);//分配一个小窗口
 42     buf_back  = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);//为背景窗口和普通小窗口分配缓存空间
 43     buf_win   = (unsigned char *) memman_alloc_4k(memman, 160 * 52);
 44     sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 设定涂层缓冲区的大小和透明色的函数 */
 45     sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
 46     sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 设定涂层缓冲区的大小和透明色的函数 */
 47     init_screen8(buf_back, binfo->scrnx, binfo->scrny);//初始化屏幕,画矩形,形成最初的窗口界面
 48     init_mouse_cursor8(buf_mouse, 99);//准备鼠标指针(16*16),99是窗口背景颜色
 49     make_window8(buf_win, 160, 52, "counter");//就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了
 50     sheet_slide(sht_back, 0, 0);//上下左右移动窗口,即移动窗口至0,0
 51     mx = (binfo->scrnx - 16) / 2; /* 计算鼠标初始位置 */
 52     my = (binfo->scrny - 28 - 16) / 2;
 53     sheet_slide(sht_mouse, mx, my);//移动鼠标窗口
 54     sheet_slide(sht_win, 80, 72);//移动消息窗口
 55     sheet_updown(sht_back,  0);//设置窗口对的高度,背景在最下面
 56     sheet_updown(sht_win,   1);
 57     sheet_updown(sht_mouse, 2);
 58     sprintf(s, "(%3d, %3d)", mx, my);//显示鼠标位置
 59     putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
 60     sprintf(s, "memory %dMB   free : %dKB",
 61             memtotal / (1024 * 1024), memman_total(memman) / 1024);
 62     putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);
 63     sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48);
 64 
 65     for (;;) {
 66         count++;
 67         sprintf(s, "%010d", count);
 68         boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);//将消息窗口画出来
 69         putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);//显示计数器的值
 70         sheet_refresh(sht_win, 40, 28, 120, 44);//刷新对应区域
 71 
 72         io_cli();
 73         if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {
 74             io_sti();
 75         } else {
 76             if (fifo8_status(&keyfifo) != 0) {
 77                 i = fifo8_get(&keyfifo);//获取按键消息并显示
 78                 io_sti();
 79                 sprintf(s, "%02X", i);
 80                 boxfill8(buf_back, binfo->scrnx, COL8_008484,  0, 16, 15, 31);
 81                 putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
 82                 sheet_refresh(sht_back, 0, 16, 16, 32);
 83             } else if (fifo8_status(&mousefifo) != 0) {
 84                 i = fifo8_get(&mousefifo);
 85                 io_sti();
 86                 if (mouse_decode(&mdec, i) != 0) {
 87                     sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
 88                     if ((mdec.btn & 0x01) != 0) {
 89                         s[1] = 'L';
 90                     }
 91                     if ((mdec.btn & 0x02) != 0) {
 92                         s[3] = 'R';
 93                     }
 94                     if ((mdec.btn & 0x04) != 0) {
 95                         s[2] = 'C';
 96                     }
 97                     boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31);
 98                     putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s);
 99                     sheet_refresh(sht_back, 32, 16, 32 + 15 * 8, 32);
100                     /* 移动鼠标 */
101                     mx += mdec.x;
102                     my += mdec.y;
103                     if (mx < 0) {
104                         mx = 0;
105                     }
106                     if (my < 0) {
107                         my = 0;
108                     }
109                     if (mx > binfo->scrnx - 1) {
110                         mx = binfo->scrnx - 1;
111                     }
112                     if (my > binfo->scrny - 1) {
113                         my = binfo->scrny - 1;
114                     }
115                     sprintf(s, "(%3d, %3d)", mx, my);
116                     boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 嵗昗徚偡 */
117                     putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 嵗昗彂偔 */
118                     sheet_refresh(sht_back, 0, 0, 80, 16);
119                     sheet_slide(sht_mouse, mx, my);
120                 }
121             }
122         }
123     }
124 }
125 /////////////////////////////////////////////////////////////////////////////////////
126 //功能:就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了
127 //参数:
128 void make_window8(unsigned char *buf, int xsize, int ysize, char *title)
129 {
130     static char closebtn[14][16] = {
131         "OOOOOOOOOOOOOOO@",
132         "OQQQQQQQQQQQQQ$@",
133         "OQQQQQQQQQQQQQ$@",
134         "OQQQ@@QQQQ@@QQ$@",
135         "OQQQQ@@QQ@@QQQ$@",
136         "OQQQQQ@@@@QQQQ$@",
137         "OQQQQQQ@@QQQQQ$@",
138         "OQQQQQ@@@@QQQQ$@",
139         "OQQQQ@@QQ@@QQQ$@",
140         "OQQQ@@QQQQ@@QQ$@",
141         "OQQQQQQQQQQQQQ$@",
142         "OQQQQQQQQQQQQQ$@",
143         "O$$$$$$$$$$$$$$@",
144         "@@@@@@@@@@@@@@@@"
145     };
146     int x, y;
147     char c;
148     boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         xsize - 1, 0        );
149     boxfill8(buf, xsize, COL8_FFFFFF, 1,         1,         xsize - 2, 1        );
150     boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         0,         ysize - 1);
151     boxfill8(buf, xsize, COL8_FFFFFF, 1,         1,         1,         ysize - 2);
152     boxfill8(buf, xsize, COL8_848484, xsize - 2, 1,         xsize - 2, ysize - 2);
153     boxfill8(buf, xsize, COL8_000000, xsize - 1, 0,         xsize - 1, ysize - 1);
154     boxfill8(buf, xsize, COL8_C6C6C6, 2,         2,         xsize - 3, ysize - 3);
155     boxfill8(buf, xsize, COL8_000084, 3,         3,         xsize - 4, 20       );
156     boxfill8(buf, xsize, COL8_848484, 1,         ysize - 2, xsize - 2, ysize - 2);
157     boxfill8(buf, xsize, COL8_000000, 0,         ysize - 1, xsize - 1, ysize - 1);
158     putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title);
159     for (y = 0; y < 14; y++) {
160         for (x = 0; x < 16; x++) {
161             c = closebtn[y][x];
162             if (c == '@') {
163                 c = COL8_000000;
164             } else if (c == '$') {
165                 c = COL8_848484;
166             } else if (c == 'Q') {
167                 c = COL8_C6C6C6;
168             } else {
169                 c = COL8_FFFFFF;
170             }
171             buf[(5 + y) * xsize + (xsize - 21 + x)] = c;
172         }
173     }
174     return;
175 }
复制代码

>_<" 具体执行流程如下:


 

4、全部代码(含注释)

  ipl10.nas [引导]
  asmhead.nas [汇编通向C语言的准备]
  bootpack.c [C文件主函数在此]
  bootpack.h [其他.c文件函数声明及相关结构体的定义]
  dsctbl.c [分段,中断分段,类似调色板那里的分法,少对多方式]
  int.c [中断函数,键盘和鼠标放在他们自己的文件里了,一般中断是从对应汇编开始中间引用这个句柄函数,然后返回结束还是在汇编]
  fifo.c [用数组实现的一个循化链表数据结构,用于存放鼠标键盘等消息]
  keyboard.c [键盘初始化及中断等]
  mouse.c [鼠标初始化及中断相关等]
  memory.c [内存管理相关,新!]
  graphic.c [界面相关函数,包括画窗口,画鼠标,显示字符等]
  sheet.c [窗口管理,用指针实现的链表,加快插入速度,加速中断,实现窗口叠加,新!]
  naskfunc.nas [用汇编写的相关函数,c语言比较难或者不能实现的]
  hankaku.txt  [字库]
  Makefile [编译脚本相关,不属于程序部分]
  make.bat [编译脚本,不属于程序部分]

 

5、效果及说明

>_<" 已经实现了窗口叠加和内存管理,这里有背景窗口,消息窗口和鼠标窗口~本次比上次多了内存管理和窗口管理,因为要加速中断,所以我们要想方设法地优化程序,内存管理中努力去除不必要的条件判断,窗口管理中用指针链表加快插入速度...同时这也为阅读这两部分的代码带来了很大的不便,建议结合以前学的数据结构的知识,可能就会有种他乡遇故知的感觉呢!哈哈~




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

相关实践学习
基于ECS和NAS搭建个人网盘
本场景主要介绍如何基于ECS和NAS快速搭建个人网盘。
阿里云文件存储 NAS 使用教程
阿里云文件存储(Network Attached Storage,简称NAS)是面向阿里云ECS实例、HPC和Docker的文件存储服务,提供标准的文件访问协议,用户无需对现有应用做任何修改,即可使用具备无限容量及性能扩展、单一命名空间、多共享、高可靠和高可用等特性的分布式文件系统。 产品详情:https://www.aliyun.com/product/nas
相关文章
|
3天前
|
算法 调度 UED
深入理解操作系统内存管理:原理与实践
【4月更文挑战第23天】 在现代计算机系统中,操作系统的内存管理是保证系统高效、稳定运行的关键组成部分。本文旨在深入探讨操作系统中内存管理的理论基础、关键技术以及实际操作过程,通过对内存分配策略、虚拟内存技术、分页与分段机制等核心概念的详细解析,为读者提供一个清晰、全面的内存管理视角。此外,文章还将通过案例分析,展示内存管理在解决实际问题中的应用,以期加深读者对操作系统内存管理复杂性的认识和理解。
|
19天前
|
算法 程序员
深入理解操作系统内存管理:分页系统的优势与挑战
【4月更文挑战第7天】 在现代操作系统中,内存管理是一项至关重要的任务,它确保了计算机能够高效、安全地运行各种程序。分页系统作为内存管理的一种技术,通过将物理内存分割成固定大小的单元——页面,为每个运行的程序提供了一种独立且连续的内存地址空间。该技术不仅简化了内存分配,还允许更高效的内存使用和保护。本文探讨了分页系统的核心原理,优势以及面临的挑战,旨在为读者揭示其在操作系统设计中的重要性。
|
1天前
|
算法
探索现代操作系统的虚拟内存管理
【4月更文挑战第25天】 操作系统的心脏——虚拟内存管理,是确保多任务并发执行和系统稳定性的关键。本文将深入剖析虚拟内存的核心机制,包括分页、分段、请求调页以及交换技术。我们将探讨虚拟内存如何允许操作系统使用有限的物理内存来模拟更大的地址空间,以及这一过程对性能的影响。此外,文章还将介绍一些高级话题,比如内存分配策略、页面置换算法以及虚拟内存的优化方法。
|
2天前
|
存储 算法
深入理解操作系统的内存管理机制
【4月更文挑战第24天】 在现代计算机系统中,操作系统扮演着资源管理者的角色,其中内存管理是其核心职责之一。本文将探讨操作系统如何通过内存管理提升系统性能和稳定性,包括物理内存与虚拟内存的概念、分页机制、内存分配策略以及内存交换技术。我们将透过理论与实践的结合,分析内存管理的关键技术及其对系统运行效率的影响。
|
9天前
|
存储 算法 数据安全/隐私保护
深入理解操作系统的内存管理机制
【4月更文挑战第17天】 在现代计算机系统中,操作系统扮演着资源管理者的角色,其中内存管理是其核心职能之一。本文探讨了操作系统内存管理的关键技术,包括虚拟内存、物理内存分配与回收、分页和分段机制,以及内存交换技术。通过分析这些机制的原理和实现,我们旨在加深读者对操作系统如何有效管理和保护内存资源的理解。
10 1
|
11天前
|
算法
深入理解操作系统的内存管理机制
【4月更文挑战第15天】 本文将探讨操作系统中至关重要的一环——内存管理。不同于通常对内存管理概念的浅尝辄止,我们将深入研究其核心原理与实现策略,并剖析其对系统性能和稳定性的影响。文章将详细阐述分页系统、分段技术以及它们在现代操作系统中的应用,同时比较它们的效率与复杂性。通过本文,读者将获得对操作系统内存管理深层次工作机制的洞见,以及对设计高效、稳定内存管理系统的理解。
|
14天前
|
存储 大数据 量子技术
深入理解操作系统的内存管理
【4月更文挑战第12天】 在现代计算机系统中,操作系统扮演着关键角色,它负责协调和管理硬件资源,确保系统运行的高效与稳定。其中,内存管理是操作系统的核心功能之一,它涉及物理内存的分配、虚拟内存的映射以及内存保护等关键操作。本文旨在深入剖析操作系统内存管理的基本原理与实践,探讨其对系统性能和安全性的影响,并简述当前的挑战与创新方向。
|
16天前
|
存储 监控 算法
深入理解操作系统的内存管理
【4月更文挑战第10天】本文旨在深度剖析操作系统中的核心组件之一——内存管理。通过对其机制、策略和现代操作系统中的应用进行探讨,读者将获得对系统如何高效利用和管理内存资源的清晰理解。文章不仅覆盖了基础理论,还涉及了高级话题,如虚拟内存技术和内存优化策略,为希望深入了解操作系统内部工作原理的技术人员提供了宝贵的知识储备。
|
18天前
|
存储 算法
深入理解操作系统内存管理:原理与实践
【4月更文挑战第8天】 在现代计算机系统中,操作系统扮演着关键角色,特别是在内存资源的管理上。本文将深入探讨操作系统中的内存管理机制,包括虚拟内存、物理内存的分配与回收,以及页面置换算法等关键技术。通过分析不同内存管理策略的优势与局限性,本文旨在为读者提供一套系统的内存管理知识框架,帮助理解操作系统如何高效、安全地管理有限的内存资源以满足多任务处理的需求。
|
21天前
|
缓存 监控 算法
深入理解操作系统的内存管理机制
【4月更文挑战第5天】 随着现代计算机系统的发展,操作系统的内存管理已成为确保系统高效稳定运行的关键因素。本文旨在探讨操作系统中内存管理的基本原理、关键技术及其在实际应用中的优化策略。通过分析内存分配、虚拟内存技术以及内存保护和分页机制等方面,揭示内存管理对提升系统性能的重要性,并提供了一系列优化内存使用效率的方法。