前言:
接下来我们可以拿着MBR这把钥匙探索其他地方了,屏幕黑漆漆的有点无聊,我们干脆来探索一下显示器这个副本,并让他说说话吧。再此之前我们要先学会如何和硬件“沟通”。
参考资料:
《操作系统真象还原》
一,CPU与外设通信的翻译官---IO接口
其实在0day的时候就介绍过IO接口的作用,不过在这里还是形象的说一下CPU,外设,IO接口三者的关系。
CPU:中国,外设:美国。
让我们想想中国和美国的区别有啥
1,语言不通,一个汉语,一个英语,大家互相听不懂,这个时候就需要有人来翻译翻译2,文化不同,中国经常接受到美国的文化输出,但是文化输出的种类多种多样,有一部分不符合国情的文化难以被接受,所以要有人对外来文化进行筛选转换
3,时间不同,地理因素哈,两国之间的时区不同,合作起来不方便,你在白天吃午饭,我在晚上准备睡觉,双方的合作就会因为时间受到影响
4,发展不同,中国发展速度快于美国(举个例子)
虽然不知道IO接口是干嘛的,结合上面的对比我们可以大概总结出IO接口的作用:
- 设置信号电平转换电路
CPU采用的是TLL电平,而外设大部分是机电设备,所以需要电平转换电路去转换。
- 数据格式转换
外设多种多样,输出的信号可能是模拟信号,数字信号,而CPU只能处理数字信号。同时,外设可能是并行或串行数据,但是CPU使用的是并行数据,需要互相转换成对方自己的格式才行
- 设置时序控制电路来同步CPU和外设设备
外设和CPU都有自己的时序系统,双方时序不同,就需要接口电路来进行协调
- CPU与外设速度不匹配,设置数据缓存
CPU速度飞快,为了弥补CPU与外设速度上面的差异,便设立了缓冲区(很常见的思想)
- 提供地址译码
CPU 同多个硬件打交道,每个硬件要反馈的信息很多,所以一个 IO 接口必须包含多个端口,即 IO 接口上的寄存器,来存储这些信息内容 但同 时刻,只能有一个端口和 CPU 数据交换,这就需要 IO 口提供地址译码电路,使 CPU 可以选中某个端口,使其可以访问数据总线
所以说了这么多,IO接口实际上就是连接 CPU 与外部设备的逻辑控制部件,利用适配器模式和分层思想,来为CPU与外设之间做协调转换。
IO接口又分为两部分:硬件(负责速度缓冲区,数据格式转换)和软件(负责电路控制,数据传输)
软件部分又分为:可编程芯片和不可编程芯片
CPU可以与多个IO接口通信,一个IO接口可能连接多个外设
二,南桥芯片
我们设想这么一个情况,当许多IO接口向CPU发送过来信号时,我们该与哪个IO接口通信呢?
这个时候我们继续利用分层的思想,再加一层嘛,这一层就负责进行仲裁,处理IO接口并且连接各种内部总线,而这一层就叫做输入输出控制中心,南桥芯片
南桥用于连接 pci pci-express AGP 等低速设备
北桥用于连接高速设备,内存等等
CPU通过一条总线连接到南桥内部,南桥内部集成了一些IO接口,如并口硬盘 PATA( 就是我们平时所说的 IDE 硬盘)、串口硬盘 SAIA ,USB, PCI 设备、电源管理等接口。PCI接口时专门负责扩展的接口,在主板上有很多插槽,它们就是预留的 pci 接口, pci 设备可以即插即用 由于它们延伸到了南桥外面,又像公路一样,很多 pci 设备都可以连接上来, 所以这条延长的 PCI 接口便成了 PCI 总线。
在此之前有说过,CPU与IO接口通信是通过IO接口上面的端口(即寄存器),那我们该如何访问端口呢?答案:是把内存地址作为端口映射,访问内存地址即可访问到端口,CPU专门提供了in和out指令去执行该操作
- in从端口读数据
in al, dx:
in ax, dx
其中al和ax用来存储从端口获取的数据, dx 是指端口号。
ps:al还是ax具体看你的寄存器位数
- out从端口输出数据
out dx, al
out dx, ax
out 立即数, al
out 立即数, ax
三,显卡
显卡即显示器的设配器,IO接口,pcie设备。
PCI和PCIE:
PCI是并行架构,PCIE是串行架构,现在的显卡都是串口。
串口和并口:
有人可能就会问了,并行设备不比你串行设备快多了,实际上并不是这样的
1,如果是8位并行总线,你要保证同时发送8位数据,并且接收方同时接收到8位数据,这实际上是很难的,而且你随着你位宽越来越大,难度也就更大,串行设备就很好的解决了这一点
2,串行设备传输频率快,所以速率是很高的
A卡和N卡
A卡:AMD阵营的显卡 (no ×)
N卡:NVIDIA阵营的显卡 (yes √)
七彩虹,技嘉这些显卡是在N卡或者A卡上面做本地化开发
四,显卡,显存,显示器
显存由显卡提供,是显卡内部一块的内存,往显存中写数据,即可在显示器上面显示相应的数据,显示器在图形模式下,显存一位对应一个像素点(图形由像素点组成),0代表黑色,1代表白色。
所以你在现在显示屏幕上面看到的都是由像素点组成的结果,但是对于显示屏来说,它可不懂什么文本,图片,视频,他只负责展示像素点,那你想想本博客如此多的字符,每次都需要在内存中编写像素点那该多麻烦,于是人们便利用数学映射的思想创立了一套编码 ASCII码,用编码来对应字符
五,让显示器说点话吧
介绍了这么多我们终于知道该怎么去让显示器说话了,大概流程如下
编写相关命令->CPU执行命令与显卡通信->在显存中写入数据->显示器显示显存中的数据
显卡支持三种模式,但是我们这次做的是 命令终端的那种操作系统,所以就用文本模式了,如果你感兴趣可以选择彩色图像模式,自己去写图形界面😋
文本模式多模式:列数*行数,80*25,40*25,80*43,他们代表了整个屏幕可以容纳的字符数量
彩色字符: ASCII码是一字节大小,7位表示字符,1位表示黑白。为了使用彩色我们用一个字节表示字符,另一个字符表示属性
如果采用的是 80*25,哪一个屏(写满整个屏幕)是2000*2 = 4000字节,32KB/4000B 约等于 8屏幕
🆗 冻手写代码吧,下面代码相信不用我多说,大家也看得懂,看不懂可以看看自己之前的注释
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
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
mov byte [gs:0x00],'G'
mov byte [gs:0x01],0xA4 ;这个是代表闪烁,颜色是红色绿底,你也可以换成自己喜欢的颜色
mov byte [gs:0x02],'e'
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'n'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'i'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'u'
mov byte [gs:0x09],0xA4
mov byte [gs:0x0a],'s'
mov byte [gs:0x0b],0xA4
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
nasm -o mbr.bin 你自己的文件名
dd if = ./mbr.bin \
of=/你的路径/geniux.img \
bs=512 count=1 conv=notrunc
此次我还是把img文件在linux中编译好然后放在windows中运行的,day 1的问题暂未解决,由于不想耽误太多时间还是用windows来测试一下吧。
所谓学习1小时,代码5分钟,之所以铺垫那么久是希望大家在编写的过程中能真正了解显示屏的显示原理之后能串联起更多的知识。当我们看到自己的名字在屏幕上疯狂鬼畜闪烁,有种满满的成就感捏,🆗今天的任务就到此结束吧,明天我们来学习并操作硬盘。