DIY操作系统(8):内核实现之屏幕打印

环境

在这里插入图片描述

这篇开始换用CentOS,不知道是不是因为MinGW,总之在Windows下编译链接一直各种各样的问题,bochs连OS内核都加载不进去。

代码目录说明

在这里插入图片描述
boot/mbr.S:mbr代码
boot/loader.S:内核加载器代码
boot/include/boot.inc:mbr与loader两份汇编代码的公用宏定义
kernel/main.c:内核代码主文件
lib/kernel:内核程序用到的库文件
lib/user:用户程序用到的库文件

编译顺序:
mbr单独编译为bin文件,写入硬盘第一扇区
loader单独编译为bin文件,写入硬盘第三扇区
print.S单独编译生成.o文件(elf格式)
main.c单独编译生成.o文件
链接main.o和print.o生成kernel.bin,写入硬盘第十扇区

VGA寄存器

在这里插入图片描述
寄存器子类分为Address RegisterData Register的原因:一个寄存器分组下会有多个寄存器,要想对其中的某一个寄存器进行操作,就使用Address Register的内容指出此寄存器在寄存器数组中的下标,将Data Register作为此寄存器的替身,对Data Register进行的读写操作可间接作用于此寄存器上。

CRT Controller Registers寄存器组中的ARDR的端口地址比较特殊,其端口地址不是固定的,而是含有x,x的值取决于Miscellaneous Output Register寄存器中的Input/Output Address Select字段,即I/OAS

在这里插入图片描述
当此位为0时,x取值为B;当此位为1时,x取D
默认为1。

CRT Controller Registers寄存器组中的各索引及其对应寄存器如下:
在这里插入图片描述

打印单个字符

数据类型

对一些数据类型的宏定义。
在这里插入图片描述

总体流程

总体处理流程如下:

  1. 备份寄存器现场。
  2. 获取光标坐标值,作为下一个可打印字符的位置。
  3. 获取待打印的字符。
  4. 判断字符是否为控制字符,若为回车符、换行符、退格符之一,则进入相应的处理流程;否则按可见字符处理,进行输出。
  5. 判断是否需要滚屏显示。
  6. 更新光标的坐标值,使其指向下一个打印字符的位置。
  7. 恢复寄存器现场,退出。

以下所有的函数都在print.S中实现,拆分开来讲解。

put_char

在这里插入图片描述

打印原理是直接写显存。对内存中的视频段进行操作,需要有视频段选择子和段内偏移。

  1. 第一到三行:定义了视频段的选择子。
  2. 第十二行:使用pushad指令备份全部的32位寄存器,压栈顺序为EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI。
  3. 第十四、十五行:段寄存器GS赋值,保证在写显存前,GS中的值是正确的段选择子。
  4. 第十七到三十四行:获取光标位置。光标位置是一维的,如80*25的窗口尺寸,共可容纳2000个字符,所以光标位置的取值为0~1999。光标位置的低8位和高8位分别放在CRT Controller Registers中索引为0EH0FH的两个寄存器中。以取高8位为例:先往端口地址为0x03D4的Address Register写入索引0x0EH,然后读端口地址为0x03D5的Data Register,获得光标的高8位,并将其存至ah寄存器的高8位。低8位同理,再将光标位置复制到bx寄存器中。
  5. 第三十六行:获取待打印字符的ASCII码。调用规则是压栈一个字符的ASCII码后,再调用put_char函数,调用时会将其4B的返回地址压栈,且函数中使用了pushad指令压入了8个4B的寄存器数据,共32B,故待打印的字符ASCII码在栈顶偏移36B的位置。
  6. 第三十七到四十四行:对字符ASCII进行判断(回车?换行?退格?可见字符?)并跳转至相应处理函数。

is_backspace

在这里插入图片描述
退格键的处理原理:将光标向回移动一个位置,并将该处的字符用空格覆盖。

put_other

在这里插入图片描述
处理可见字符。

处理LF与CR

在这里插入图片描述

roll_screen

处理滚屏
在这里插入图片描述

set_cursor

设置光标
在这里插入图片描述

put_char_done

在这里插入图片描述

测试

内核主代码如下
在这里插入图片描述

请添加图片描述

打印字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值