30天自制操作系统:第五天:文字显示与GDT/IDT初始化

2024-05-31 17:48

本文主要是介绍30天自制操作系统:第五天:文字显示与GDT/IDT初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第五天:文字显示与GDT/IDT初始化

1.从内存中读出保存的值.

昨天程序中300x200都是直接写入程序,本来应该从asmhead.nas先前保存的值中取,不然当画面模式改变时,系统就挂了.

所以得修改bootpack.c文件代码从asmhead.nas写入的内存中取值.

2.显示字符

原理:将每一个bit当成一个黑点,那么,字符a就可以当成下图所示:

在这里插入图片描述

那么字符a要显示赋值给显卡的话,用字符数组表示就变成:

static char font_A[16]={0x00,0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x7e,0x42, 0x42,0x42, 0xe7, 0x00, 0x00};

3.增加字体

作者自己写了一个字体生成小工具,可以将图像字符转成16进制数据.

在这里插入图片描述

这个很简单,有c语言基础的一看就知道这个工具是怎么写的了.

生成的字体数据存到hankaku[4096]数组中,后边程序会调用.

4.显示鼠标指针

将鼠标大小定为16x16,先准备16x16的内存,然后写入鼠标指针的数据.

void init_mouse_cursor8(char *mouse, char bc)
/* 初始化鼠标*/
{static char cursor[16][16] = {"**************..","*OOOOOOOOOOO*...","*OOOOOOOOOO*....","*OOOOOOOOO*.....","*OOOOOOOO*......","*OOOOOOO*.......","*OOOOOOO*.......","*OOOOOOOO*......","*OOOO**OOO*.....","*OOO*..*OOO*....","*OO*....*OOO*...","*O*......*OOO*..","**........*OOO*.","*..........*OOO*","............*OO*",".............***"};int x, y;for (y = 0; y < 16; y++) {for (x = 0; x < 16; x++) {if (cursor[y][x] == '*') {mouse[y * 16 + x] = COL8_000000;}if (cursor[y][x] == 'O') {mouse[y * 16 + x] = COL8_FFFFFF;}if (cursor[y][x] == '.') {mouse[y * 16 + x] = bc;}}}return;
}

然后分别对* 0 . 进行颜色替换.

5.GDT和IDT初始化.

有分段,分页和中断的概念,自己百度吧.
在这里插入图片描述

GDT(全局段号记录表):

​ 为了表示一个段,需要一下信息:

  • 段的大小是多少.
  • 段的起始地址在哪里.
  • 段的管理属性(禁止写入,禁止执行,系统专用等).

​ cpu 用8个字节(64位)来表示这些信息. 表示段的寄存器只有16位,而且由于cpu设计上的原因,段寄存器的低3位不能使用,因此只有13位,能够处理的就只有位于0~8191的区域了. 因此能够定义8192个段, 而设定8192个段需要8192x8=65536(64kb), 将这64kb存到内存中表示,就是GDT.

IDT(中断记录表):

​ idt记录了0~255的中断号码与调用函数的对应关系.

struct SEGMENT_DESCRIPTOR {short limit_low, base_low;char base_mid, access_right;char limit_high, base_high;
};struct GATE_DESCRIPTOR {short offset_low, selector;char dw_count, access_right;short offset_high;
};//初始化<全局段号记录表><中断记录表>.
void init_gdtidt(void)
{//随便选了内存地址0x00270000~0x0027ffff设为GDT.只是因为未被使用.struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x00270000; struct GATE_DESCRIPTOR    *idt = (struct GATE_DESCRIPTOR    *) 0x0026f800;int i;/* GDT的初始化 */for (i = 0; i < 8192; i++) {set_segmdesc(gdt + i, 0, 0, 0);}//段号为1的段的属性为0x4092 , 歧视地址是0, 大小是0xffffffff,刚好是4GB.表示cpu所能管理的全部内存.set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092); set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a); //段号为2的段的属性为0x409a//c语言不给能GDTR赋值.调用汇编给GDTR赋值.load_gdtr(0xffff, 0x00270000);/* IDT的初始化 */for (i = 0; i < 256; i++) {set_gatedesc(idt + i, 0, 0, 0);}load_idtr(0x7ff, 0x0026f800);return;
}
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{if (limit > 0xfffff) {ar |= 0x8000; /* G_bit = 1 */limit /= 0x1000;}sd->limit_low    = limit & 0xffff;sd->base_low     = base & 0xffff;sd->base_mid     = (base >> 16) & 0xff;sd->access_right = ar & 0xff;sd->limit_high   = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);sd->base_high    = (base >> 24) & 0xff;return;
}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{gd->offset_low   = offset & 0xffff;gd->selector     = selector;gd->dw_count     = (ar >> 8) & 0xff;gd->access_right = ar & 0xff;gd->offset_high  = (offset >> 16) & 0xffff;return;
}

6.至此,就把GDT和IDT写入到内存中. 执行结果如下:

在这里插入图片描述

这篇关于30天自制操作系统:第五天:文字显示与GDT/IDT初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1018623

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

idea中project的显示问题及解决

《idea中project的显示问题及解决》:本文主要介绍idea中project的显示问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录idea中project的显示问题清除配置重China编程新生成配置总结idea中project的显示问题新建空的pr

C++类和对象之初始化列表的使用方式

《C++类和对象之初始化列表的使用方式》:本文主要介绍C++类和对象之初始化列表的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C++初始化列表详解:性能优化与正确实践什么是初始化列表?初始化列表的三大核心作用1. 性能优化:避免不必要的赋值操作2. 强