VESA编程GUI离我们并不遥远.docx
- 文档编号:13485405
- 上传时间:2023-06-14
- 格式:DOCX
- 页数:29
- 大小:25.26KB
VESA编程GUI离我们并不遥远.docx
《VESA编程GUI离我们并不遥远.docx》由会员分享,可在线阅读,更多相关《VESA编程GUI离我们并不遥远.docx(29页珍藏版)》请在冰点文库上搜索。
VESA编程GUI离我们并不遥远
VESA编程——GUI离我们并不遥远
分类:
操作系统相关2010-09-2017:
011602人阅读评论
(2)收藏举报
编程attributes图形videostandardsvmware
目录(?
)[+]
VESA编程——GUI离我们并不遥远
自从学习操作系统开发以来,所接触到的操作系统开发资料都是关于文本模式的。
然而黑色的命令行始终没有色彩斑斓的图形界面吸引眼球,所以查阅了很多资料后终于找到了真正的图形界面实现方法——VESA。
先上图:
这是一个800X600分辨率32位色(实际上是一个24位色,最高字节没用)的demo,当然你也可以把分辨率设置成1024X768或者1280X1024。
什么是VBE?
VBE的全称是VESABIOSExtension。
什么是VESA?
VESA的全称是VideoElectronicsStandardsAssociation即视频电子标准协会,是由代表来自世界各地的、享有投票权利的超过165家成员公司的董事会领导的非盈利国际组织。
VESA致力于开发、制订和促进个人计算机(PC)、工作站以及消费类电子产品的视频接口标准,为显示及显示接口业界提供及时、开放的标准,保证其通用性并鼓励创新和市场发展。
VBE视频模式
先来看看VBE的模式号及其对应的分辨率与颜色:
VBE最高可以支持1280X1024的分辨率,24位真彩色,完全可以满足我们创建图形化操作系统的需求。
下面是一张视频标准图:
只可惜VBE的标准比较老,不支持宽屏显示器。
用到的VBE函数
要实现图形模式就要用到vbe函数,vbe函数标准定义了一系列VGAROMBIOS服务扩展。
这些vbe函数可以在实模式下通过10h中断调用或者直接通过高性能的32位程序和操作系统调用。
我们的demo是通过实模式下的int10h中断来调用VBE函数的。
我们将使用以下三个函数:
功能00h–返回控制器信息
1
输入:
2
AX =4F00h 返回VBE控制器信息
3
ES:
DI = 指向存放VbeInfoBlock结构体的缓冲区指针
4
5
输出:
6
AX = VBE返回状态
7
8
备注:
其他的寄存器被保留。
这个函数返回一个VbeInfoBlock结构体,该结构体定义如下:
01
//VbeInfoBlock
02
typedef struct {
03
unsigned char vbe_signature;
04
unsigned short vbe_version;
05
unsigned long oem_string_ptr;
06
unsigned char capabilities;
07
unsigned long video_mode_ptr;
08
unsigned short total_memory;
09
unsigned short oem_software_rev;
10
unsigned long oem_vendor_name_ptr;
11
unsigned long oem_product_name_ptr;
12
unsigned long oem_product_rev_ptr;
13
unsigned char reserved[222];
14
unsigned char oem_data[256];
15
}VbeInfoBlock;
我解释一下上面的结构体中比较重要的几个变量。
vbe_signature是VBE标识,应该填充的是”VESA”
vbe_version是VBE版本,如果是0300h则表示3.0版本
oem_string_ptr是指向oem字符串的指针,该指针是一个16位的selector:
offset形式的指针,在实模式下可以直接使用。
video_mode_ptr是指向视频模式列表的指针,与oem_string_ptr类型一样
total_memory是64kb内存块的个数
oem_vendor_name_ptr是指向厂商名字符串的指针
oem_product_name_ptr是指向产品名字符串的指针
功能01–返回VBE模式信息
1
输入:
2
AX = 4F01h 返回VBE模式信息
3
CX = 模式号
4
ES:
DI = 指向ModeInfoBlock结构体的指针
5
6
输出:
7
AX = VBE返回状态
8
9
备注:
所有其他的寄存器保留。
这个函数返回一个ModeInfoBlock结构体,该结构体定义如下:
01
//VbeModeInfoBlock
02
typedef struct {
03
//MandatoryinformationforallVBErevisions
04
unsigned short mode_attributes;
05
unsigned char wina_attributes;
06
unsigned char winb_attributes;
07
unsigned short win_granularity;
08
unsigned short win_size;
09
unsigned short wina_segment;
10
unsigned short winb_segment;
11
unsigned long win_func_ptr;
12
unsigned short bytes_per_scan_line;
13
14
//MandatoryinformationforVBE1.2andabove
15
unsigned short xresolution;
16
unsigned short yresolution;
17
unsigned char xchar_size;
18
unsigned char ychar_size;
19
unsigned char number_of_planes;
20
unsigned char bits_per_pixel;
21
unsigned char number_of_banks;
22
unsigned char memory_model;
23
unsigned char bank_size;
24
unsigned char number_of_image_pages;
25
unsigned char reserved1;
26
27
//DirectColorfields(requiredfordirect/6andYUV/7memorymodels)
28
unsigned char red_mask_size;
29
unsigned char red_field_position;
30
unsigned char green_mask_size;
31
unsigned char green_field_position;
32
unsigned char blue_mask_size;
33
unsigned char blue_field_position;
34
unsigned char rsvd_mask_size;
35
unsigned char rsvd_field_positon;
36
unsigned char direct_color_mode_info;
37
38
//MandatoryinformationforVBE2.0andabove
39
unsigned long phys_base_ptr;
40
unsigned long reserved2;
41
unsigned short reserved3;
42
43
//MandatoryinformationforVBE3.0andabove
44
unsigned short lin_bytes_per_scan_line;
45
unsigned char bnk_number_of_image_pages;
46
unsigned char lin_number_of_image_pages;
47
unsigned char lin_red_mask_size;
48
unsigned char lin_red_field_position;
49
unsigned char lin_green_mask_size;
50
unsigned char lin_green_field_position;
51
unsigned char lin_blue_mask_size;
52
unsigned char lin_blue_field_position;
53
unsigned char lin_rsvd_mask_size;
54
unsigned char lin_rsvd_field_position;
55
unsigned long max_pixel_color;
56
unsigned char reserved4[189];
57
58
}VbeModeInfoBlock;
解释一下几个我们要用到的比较重要的字段。
首先是mode_attributes字段,这个字段描述了图形模式的一些重要属性。
其中最重要的是第4位和第7位。
第4位为1表示图形模式(Graphicsmode),为0表示文本模式(Textmode)。
第7位为1表示线性帧缓冲模式(Linearframebuffermode),为0表示非线性帧缓冲模式。
我们主要要检查这两个位。
xresolution,表示该视频模式的X分辨率。
yresolution,表示该视频模式的Y分辨率。
bits_per_pixel,表示该视频模式每个像素所占的位数。
phys_base_ptr,这是一个非常重要的字段,它给出了平坦内存帧缓冲区的物理地址,你可以理解为显存的首地址。
如果每个像素占32位的话,屏幕左上角第一个点所占的缓冲区就是phys_base_ptr所指的第一个4个字节。
按照先行后列的顺序,每个像素点所占缓冲区依次紧密排列。
我们要想在屏幕上画出像素点,就得操作以phys_base_ptr为起始的物理内存空间。
功能02–设置VBE模式
01
输入:
02
AX =4F02h 设置VBE模式
03
BX = 需要设置的模式
04
D0-D8 =模式号
05
D9-D10 =保留(必须为0)
06
D11 =0使用当前缺省刷新率
07
=1使用用户指定的CRTC值为刷新率
08
D12-D13 =为VBE/AF保留(必须为0)
09
D14 =0使用窗口帧缓冲区模式
10
=1使用线性/平坦帧缓冲区模式
11
D15 =0清除显示内存
12
=1不清除显示内存
13
ES:
DI = 指向CRTCInfoBlock结构体的指针
14
15
输出:
16
AX = VBE返回状态
17
18
备注:
所有其他的寄存器保留
这个函数就是用来设置我们的视频模式,通过用功能01查找我们所需要模式,然后用功能02即可设置我们所需要的模式。
具体实现方法
因为我们要操作显存,对于一个1280X102432bit的视频模式来说,需要用到5M的内存,而我们知道在实模式下我们只能用段:
位移的方式访问1M的地址空间,而我们的显存是在这1M的地址空间之外,那么我们如何才能在实模式下访问32位的地址空间呢?
这里有一种方法,那就是进入Unreal模式,Unreal模式是实模式的一个变体,在这种模式下我们的代码还是16位的实模式方式,但是我们可以使用32位的代码段来访问32位地址空间,这样我们就可以向显存中写数据来画图了。
下面是我们代码中main函数的片段:
01
;-------------------------------;
02
; InstallourGDT ;
03
;-------------------------------;
04
05
call InstallGDT ;installourGDT
06
07
;-------------------------------;
08
; EnableA20 ;
09
;-------------------------------;
10
11
call EnableA20_KKbrd_Out
12
sti
13
14
;-------------------------------;
15
; InitVesa ;
16
;-------------------------------;
17
call GetVbeInfo
18
call SetVideoMode
19
call EnterUnrealMode
20
21
;-------------------------------;
22
; Initvideo ;
23
;-------------------------------;
24
25
call VideoInit
在上面的代码中,我们要进入Unreal模式首先要调用InstallGDT来安装GDT,接着调用EnableA20_KKbrd_Out来打开A20地址总线,然后调用EnterUnrealMode来进入Unreal模式。
下面是EnterUnrealMode的代码:
01
;=========================================
02
; EnterUnrealMode
03
; enterunrealmode
04
;=========================================
05
EnterUnrealMode:
06
cli
07
push ds
08
09
mov eax,cr0
10
or al,1
11
mov cr0,eax
12
13
mov bx,0x08
14
mov ds,bx
15
16
and al,0xFE
17
mov cr0,eax
18
19
pop ds
20
sti
21
ret
在上面的代码中,我们先暂时进入保护模式,接着将ds设为0×08,0×08是所安装的GDT的代码段的选择子。
接着我们又返回到实模式,这样,处理器会使用所缓存的描述符,就像在保护模式中那样,我们就可以在实模式下访问4GB的内存空间了。
在main函数中,我们调用GetVbeInfo来获取VBE控制器的信息,下面是这个函数的代码:
01
;=============================================
02
; GetVbeInfo
03
; getvebcontrollerinformationtovbe_info_blockstructure
04
;=============================================
05
GetVbeInfo:
06
pushad
07
mov ax,4F00h ;GetVBEinformation
08
mov di,0x7E00 ;Setparam
09
int 10h
10
;call CheckVbeReturn ;Check return value
11
;call CheckVesaVersion ;Checkvesaversion
12
;call ShowOEMString
13
call FindVideoMode ;FindVideoMode
14
15
.end:
16
popad
17
ret
在这个函数中,我们会调用FindVideoMode函数来查找我们所需要的模式,并将其存放在VideoMode变量中。
下面是FindVideoMode函数的代码:
01
;=============================================
02
; FindVideoMode
03
;=============================================
04
FindVideoMode:
05
pushad
06
mov si,[0x7E00+vbe_info_block.video_mode_ptr]
07
08
.loop:
09
push ds
10
mov ax,[0x7E00+vbe_info_block.video_mode_ptr+2]
11
mov ds,ax
12
lodsw
13
pop ds
14
mov [VideoMode],ax
15
cmp ax,0xFFFF
16
je .notfound
17
18
.getmode:
19
call GetVideoMode
20
;mov ax,word[0x8000+mode_info_block.xresolution]
21
;mov bx,word[0x8000+mode_info_block.yresolution]
22
;mov cl,byte[0x8000+mode_info_block.bits_per_pixel]
23
cmp word[0x8000+mode_info_block.xresolution],SCREEN_WIDTH
24
jne .cnt
25
cmp word[0x8000+mode_info_block.yresolution
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VESA 编程 GUI 我们 并不 遥远