64位操作系统-屏幕显示
为了在屏幕上显示颜色,必须通过桢缓冲存储器完成。桢缓冲存储器(Frame Buffer),简称桢缓存或桢存。它是屏幕显示画面的一个内存映像,桢缓存的每个存储单元对应屏幕的一个像素,整个桢缓存对应一幅图像。桢缓存的特点是可对每个像素点进行操作,不仅可以借助它在屏幕上画出屏幕上色彩,还可以在屏幕上用像素点绘制文字以及图片。
此前设置说显示芯片的显示模式(模式号:0x180,分辨率:1400*900,颜色深度:32bit),而且内核执行头程序还将桢缓存的物理基地址映射到线性地址0xffff800000000000和0xa00000处。
屏幕上显示色彩
桢缓存格式:一个像素点能够显示的颜色值位宽。Loader引导加载程序设置的显示模式可支持32位颜色深度的像素点,其中0~7位代表蓝色,8~15位代表吝啬,16~23位代表红色,24~31位是保留位。
如果想设置屏幕上某个像素点的颜色,必须知道这个点在屏幕上的位置,并计算处该点距离屏幕原点的偏移值。屏幕坐标位于左上角。
显示屏幕色带如下:
1 | void start_kernel(void) { |
桢缓存区被映射的线性地址是0xffff800000a00000,在显示模式的过程中,有个寄存器位可以在设置显示模式后清除屏幕上的数据。Loader引导加载程序已将该寄存器位置位,所以先前在屏幕上显示的信息已经被清除。
在屏幕上显示LOG
在一个固定像素方块内用像素点画出字符,即可实现屏幕上的字符显示功能。
ASCII字符库
ASCII字符集共有256个字符,其中包括字母、数字、符号和一些非显示信息。当前只显示一些常用的显示字符。
数字0和一个8*16的像素点矩阵,像素点矩阵中的黑色像素点在屏幕上映射组成了数字0,它们是数字0的字体颜色。只要根据像素点矩阵的映射原理,计算出每行的16进制数值,再将这16行数值组合起来就构成了字符像素位图。一行刚好一个字节,所以只需要保留16字节的位图即可。
显示彩色字符
实现color_printk函数前,需要先准备一个用于屏幕信息的结构体struct position。该结构体记录这当前屏幕的分辨率、字符光标所在位置、字符像素矩阵尺寸、桢缓冲区起始地址和桢缓冲区容量大小。
1 | struct position { |
初始化全局屏幕信息描述:
kernel/main.c:
1 | struct position pos; |
打印字符函数实现:
kernel/printk.c:
1 | /** |
只能将数值字母转换成整数值:
1 |
|
字符串长度:
1 | /** |
strlen先将AL寄存器赋值为0,随后借助scasb汇编指令逐字节扫描字符串,每次扫描都会与AL寄存器进行对比,并根据对比结果置位相应的标志位,如果扫描的数值与AL寄存器的数值相等,ZF标志位被置位。repne对一直重复执行scasb指令,知道ecx寄存器递减为0或ZF标志位被置位。又因为ecx寄存器的初始值是负值(0xffffffff),repne指令执行结束后,ecx寄存器依然是负值(ecx寄存器在函数执行过程中递减,使用负值可统计出扫描次数),对ECX寄存器取反减1后得到字符串长度。
将长整型变量值转换成指定进制规格的字符串
1 | /** |
用于解析color_printk函数所提供的格式化字符串及其参数,vsprintf函数会将格式化后(就像汇编语言用db定义的一串字符那样,可以直接搬运到显存输出那样)的字符串结果保存到一个4096B的缓冲区中buf,并返回字符串长度
1 | /** |
color_printk函数实现:
1 | int color_printk(unsigned int fr_color, unsigned int bk_color, const char *fmt, |




