在上一篇中我们使用bootimage制作bootloader并通过QEMU来引导并调入到内核中,我们的内核现在很干净,我们迫切希望能够在屏幕上显示一些字符,本节我们开始实现这个功能
一些无聊的理论
为了能在屏幕上显示一些字符,我们需要通过文本缓冲器写入VGA硬件,VGA文本缓冲区是一个二维的数字,总共25行,80列,他们直接渲染到屏幕上,在这个二维的空间中每个元素都会用一下形式描述
比特位 | 效果 |
---|---|
0-7 | ASCII 码点 |
8-11 | 文字的前景色(文字的颜色) |
12-14 | 文字的背景色 |
15 | 闪烁文字 |
第一项代表应以ASCII编码打印的字符,实际上它不是ASCII,它其实时ASCII字符内码列表( Code page 437)是 最初的IBM PC代码页,实现了扩展ASCII字符集
第二项定义了文字如何显示,你可以使用自己喜欢的颜色,最后一项表示字符是否会闪烁
以下颜色是可以使用的
数字 | 颜色 | 数字 | 颜色 |
---|---|---|---|
0x0 | 黑色 | 0x8 | 暗灰色 |
0x1 | 蓝色 | 0x9 | 亮蓝色 |
0x2 | 绿色 | 0xa | 亮绿色 |
0x3 | 青色 | 0xb | 亮青色 |
0x4 | 红色 | 0xc | 亮红色 |
0x5 | 品红色 | 0xd | 粉色 |
0x6 | 棕色 | 0xe | 黄色 |
0x7 | 亮灰色 | 0xf | 白色 |
颜色的第4位是亮位,它例如将蓝色变成亮蓝色。对于背景色,该位被重新用作闪烁
VGA文本缓冲区可通过内存的0xB8000访问,这意味着我们直接向普通内存地址一样读写,但是它不经过RAM,因为我们直接访问硬件上的VGA文本缓冲区
注意:内存映射的硬件可能不支持所有的RAM操作,例如我们可以向一个设备写入数据,但是读取该设备时会给我们一堆垃圾数据,但是VGA支持正常的读和写(不然我们读取的就是一些奇怪的数据)
建立库
随着我们的代码逐渐增多,就不能在main.rs文件中了,我们需要份文件,做到模块化
首先我们创建一个lib.rs
写添加以下内容
lib.rs
#![no_std]
同main.rs一样我们也不需要std库,接着我们在main.rs中添加这一行
#[macro_use]
extern crate kernel;
因为我们需要用到自己定义的宏,因此加上了macro_use属性