动手学操作系统(三、通过IO接口直接控制显卡)
在之前的学习内容中,我们成功编写了MBR主引导记录,在终端上进行了打印显示,在这一节我们使用MBR通过IO接口来直接控制显卡输出字符。
文章目录
- 动手学操作系统(三、通过IO接口直接控制显卡)
- 1. 什么是IO
- 2. 显卡
- Reference
1. 什么是IO
为了兼容大量的硬件外设,CPU需要增加一“层”来解决不兼容的问题,在CPU和外设之间的这一层就是IO接口,IO接口的形式不限,它可以是电路板,芯片,插槽等等,它的作用就是在CPU和外设之间做相互协调的转化。
IO接口的功能有:
- 设置数据缓冲,解决CPU与外设的速度不匹配
- 设置信号电平转换电路
- 设置数据格式转换
- 设置时序控制电路来同步CPU和外设
- 提供地址译码
同一时刻,CPU只能和一个IO接口通信,当很多IO接口都需要和CPU通信的时候,需要再增加一“层”来仲裁IO接口的竞争,这个部分就是输入输出控制中心(I/O control hub, ICH),一般被称为南桥芯片。
2. 显卡
显卡想必不用过多的介绍,只需要理解我们为什么需要操作显卡,我们在上一节使用了MBR在实模式下运行,使用了BIOS的0x10
中断来打印了字符串,但是操作系统的正常工作状态是保护模式,在保护模式下就没有了中断向量表,则BIOS的中断也不能使用了,所以凡是涉及到需要向屏幕打印的操作,我们都需要操作显卡来实现。
无论哪种显卡,我们都只关心其向我们提供的可编程接口:IO端口和显存。
显卡的显存地址分布如下
从起始地址0xB8000
到0xBFFFF
,这片32KB的内存区域是用于文本显示的,我们往0xB8000
处输出的字符会直接落到显存中,显存中有了数据,显卡会自动将其显示到屏幕上,这后续的处理过程交给显卡自动完成即可,我们不需要关心。
在显卡的文本模式下,每个字符由2
个连续字节组成,一个表示字符本身的ASCII码,另一个表示该字符的其他显示特性(颜色、闪烁等)
修改之前的mbr.S
文件如下
; ~/d2los/src/mbr.S
; 主引导程序
;
; LOADER_BASE_ADDR equ 0xA000
; LOADER_START_SECTOR equ 0x2
;------------------------------------------------------------
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0xb800
mov gs,ax
; 清屏
; 利用0x06号功能,上卷全部行,可以清屏。
; -----------------------------------------------------------
; INT 0x10 功能号:0x06 功能描述:上卷窗口
; ------------------------------------------------------
; 输入:
; AH 功能号= 0x06
; AL = 上卷的行数(如果为0,表示全部)
; BH = 上卷行属性
; (CL,CH) = 窗口左上角的(X,Y)位置
; (DL,DH) = 窗口右下角的(X,Y)位置
; 无返回值:
mov ax, 0600h
mov bx, 0700h
mov cx, 0 ; 左上角: (0, 0)
mov dx, 184fh ; 右下角: (80, 25),
; 因为VGA文本模式中,一行只能容纳80个字符,共25行。
; 下标从0开始,所以0x18=24,0x4f=79
int 10h ; int 10h
; 输出背景色绿色,前景色红色,并且跳动的字符串"1 MBR"
mov byte [gs:0x00],'H'
mov byte [gs:0x01],0xA4 ; A表示绿色背景,4表示前景色为红色
mov byte [gs:0x02],'e'
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'l'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'l'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'o'
mov byte [gs:0x09],0xA4
mov byte [gs:0x0A],' '
mov byte [gs:0x0B],0xA4
mov byte [gs:0x0C],'W'
mov byte [gs:0x0D],0xA4
mov byte [gs:0x0E],'r'
mov byte [gs:0x0F],0xA4
mov byte [gs:0x10],'o'
mov byte [gs:0x11],0xA4
mov byte [gs:0x12],'l'
mov byte [gs:0x13],0xA4
mov byte [gs:0x14],'d'
mov byte [gs:0x15],0xA4
jmp $ ; 通过无限循环使程序停在此处
times 510-($-$$) db 0
db 0x55,0xaa
然后编译,链接,执行
cd ~/d2los
nasm -o bin/mbr.bin src/mbr.S
cd ~/d2los
dd if=./bin/mbr.bin of=~/bochs/bin/hardisk60MB.img bs=512 count=1 conv=notrunc
~/bochs/bin/bochs -f ~/bochs/bin/bochsrc.disk
执行的效果如下
Reference
[1]《一个64位操作系统的设计与实现》
[2]《操作系统真象还原》