吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5885|回复: 48
收起左侧

[系统底层] 从0到-1写一个操作系统-0x02-MBR支持显卡

  [复制链接]
peiwithhao 发表于 2022-12-28 23:32
本帖最后由 peiwithhao 于 2023-3-2 14:01 编辑

这里写个往期推荐,这样可以来回跳跃(狗头
0x00-环境准备
0x01-BIOS以及MBR
0x02-MBR支持显卡
0x03-MBR操作硬盘以及Loader
0x04-进入保护模式

0x00 基础知识们

今天咱们来改进下之前咱们所写的简易MBR,大伙还记得么(笑

上次咱们利用BIOS的中断来实现打印字符擦到屏幕,然后用jmp自身这个指令来实现类似while循环这种功能,所以打印字符串之后就无线循环停那儿了,今天我们把他的功能完善一下

1. 实模式

大伙还记得上一布我解释的实模式吗,解释的很短一句但是这并不能概括他所有的意义,这里我再来细细解释。
这里我先给出几个实模式下寄存器的解释,这图片是嫖的操作系统真像还原的,大伙有兴趣也可以去看看:

而这里我会着重讲解一下标志寄存器,也即flags,当然这在上表上面没有写出来,这是因为即将细讲的缘故,首先我们得知道这个flags起着什么作用。这里举个简单的例子,当我们在使用c语言判断语句时,就比如说if(i>1)时,咱们经过编译得出的汇编代码实际上就是使用i-1,然后看其得数是否大于0,若是大于0,则会进入if的代码块,若小于0则会跳过这个代码快,但是如何得知他的得数的正负呢,此时我们就可以利用flags寄存器了,这是因为在两数参与运算时,ACC累加器有个特殊的电路,其中两数相加之时会生成一系列标志位,其中就比如ZF,OF等等,这些标志位在不同的情况下有着不同的含义,而这些标志位统统一股脑存在flags寄存器中,其中CF就表示着无符号数之间相互运算是否借位/进位,而OF就表示有符号数运算是否溢出,拿我们刚刚if语句作为例子,此时咱们只需要看flags寄存器中的SF标志位(判断得数为正或负)即可决定分支走向。
以下是flags寄存器标志位的分布图:

以下是几个重要标志位的详细解释:

  • CF(Carry Flag)进位标志:用于反映运算是否产生进位或借位。如果运算结果的最高位产生一个进位或借位,则CF置1,否则置0。运算结果的最高位包括字操作的第15位和字节操作的第7位。移位指令也会将 操作数的最高位或最低位移入CF。
  • PF(Parity Flag)奇偶标志:用于反映运算结果低8位中“1”的个数。“1”的个数为偶数,则PF置1,否则置0。
  • AF(Auxiliary Carry Flag) 辅助进位标志:在字节操作时低 半字节向高半字节进位或借位,字操作时低字节向高字节进位或借位,AF置1,否则置0。
  • ZF(Zero Flag)零标志:用于判断结果是否为0。运算结果0,ZF置1,否则置0。
  • SF(Sign Flag)符号标志:用于反映运算结果的符号,运算结果为负,SF置1,否则置0。因为 有符号数采用补码的形式表示,所以SF与运算结果的最高位相同。
  • OF(Overflow Flag)溢出标志:反映 有符号数加减运算是否溢出。如果运算结果超过了8位或者16位 有符号数的表示范围,则OF置1,否则置0。
  • 控制标志:
  • TF(Trap Flag)陷阱标志:当TF被设置位1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。8086/8088中没有专门用来置位和清零TF的命令,需要用其他办法。
  • IF(Interrupt Flag)中断标志:决定CPU是否响应外部可屏蔽 中断请求。IF为1时,CPU允许响应外部的可屏蔽 中断请求。
  • DF(Direction Flag)方向标志:决定串操作指令执行时有关指针寄存器调整方向。当DF为1时,串操作指令按递减方式改变有关 存储器指针值,每次操作后使SI、DI递减。

以上便是对之前实模式的补充

2. IO接口是甚么

首先,咱们得知道个概念,什么是IO接口,实际上IO接口就是一系列端口与控制逻辑的结合,他所实现的功能就是让计算机与外设能进行通信。举个恰当的例子,你鼠标想通过点击某个按钮来触发一项操作,那cPU为什么会吊你呢,CPU只会从主存或寄存器中取东西执行,有一句老话,在计算机界没有什么是加一层解决不了的,如果有,那就加两层。事实证明也确实如此,我们通过在cpu与外设之间家一个层,也就是IO接口,以此端口来处理外设传输过来的数据,然后在调整(这里的调整包括但不限于速度的匹配,数据格式转换等)送入CPU,但是有例外就是现在大部分高速块外设采用DMA方式基本是直接传送到主存。这个IO接口也充当作了中间商的作用,如果说实在理解困难也不要紧,可以将其暂时看成你们家电脑的插版来看,你想想如果你鼠标不插上去你怎么使用呢对吧,(别给我扯蓝牙鼠标奥,一脚给你李宁踹开线)。

知道了IO接口的作用,我们现在来讨论如何使得CPU访问到IO接口呢,此时大致分为两种方法,其中之一是统一编址,在统一编址之下,我们会将主存地址分开一部分来供IO接口来使用,比如说0x000~0x7FF为咱们正常使用的物理地址,而剩下的0x800~0xFFF就全作为IO接口地址来进行访问,只要你访问的地址落于后一段,那么CPU就会认定你在使用某一IO接口。还有一种方法那就是选择独立编址,所谓独立编址就是访问主存的地址与IO接口的地址无关,CPU区分你是访问主存还是IO接口的因素是指令操作码,也就是类似于ADD,SUB等这类的汇编语句,此时就不需要从主存专门划分出一块i区域供IO接口使用了,但是其也有缺点那就是增加了指令条数。

接下来咱们讲解第二种访问方式:

  1. in指令用来从端口中读取数据,其一般形式为:
    • in al,dx
    • in ax,dx
      其中al,ax是指从端口读取数据所存放的寄存器,而dx是指IO端口号。
      这里需要注意以上用法是固定的,其源操作数必须得是dx,而目的操作数是al还是ax取决与dx端口指代的寄存器是8位还是16位。
  2. out指令用来向端口输入数据,其一般形式为:
    • out dx,al
    • out dx,ax
    • out 立即数,al
    • out 立即数,ax
      同in指令类似,只不过源操作数与目的操作数相同
      而接下来咱们所要讲述的显卡接口是使用的第一种方式,也即统一编址

3. 显示器、显卡、显存

知道了IO接口是干啥的和如何使用,今天咱们就来看看显示器啦。这里大伙不要与上一篇的打印弄混了,虽然说咱们确实是向显示器输送了一段数据,但这个效果是采用BIOS所建立的中断向量表所实现的,而BIOS的中断向量表在实模式之后的保护模式将不复存在(没错,后面还一个模式,你也可以想到之后咱们肯定不能一直使用物理地址编程了,保护模式咱们等到需要的时候再进行讲解)。所以咱们得试着利用上面所讲解的知识来使用IO进行输出字符到显示器上进行显示。
众所周知,显示器也属于外设,他要同计算机进行数据交换,那必然需要存在一个IO接口,而负责显示器与计算机的交互的IO接口大家肯定已经耳熟能详,那就是显卡,一般来说显卡需要满足显存的刷新需要,他所运算的速度是十分之高的,他甚至比咱们的CPU都高不止一点半点,但是为啥CPU没那么快呢,那是因为在快速运算的时候会产生大量的热能,而cpu那么小一块地方,若是用上显卡的运算速度,那电脑自带的散热根本不够看,直接电脑给你烧坏了,而咱们目前市面上的显卡单独拿出来一般会加深自己的散热功能以此来达到更高的算力,这也是为什么咱们看到人家买的显卡为啥长风扇一样了,这几个大风扇就是专门为显卡散热的。
说回正题,咱们知道内存、外存,但是显存是属于谁呢,实际上显存哪个都不属于,他是显卡内部自行包含的一块存储区域,此时显卡的交换可以不用只限于端口交换,也可以用显存进行数据交换,实际上用显存来实现数据交换更为广泛。
而我们能在显示器看见色彩斑斓的图片这是因为显卡可以让显示器工作在图形模式,而我们能在显示器看见那些黑底白字的图片也是因为显卡能让显示器工作在字符模式,这里我们还可以吧他们归纳在一起描述,那就是咱们的显示屏是由一个个极小的像素点来构成的,你在日常生活中看图片是否放的越大就发现图片变成一个一个正方形了呢,没错那就是一个像素块,而咱们计算机也是通过01这种bit串来表示像素快的。这里举个例子,如果说咱们的像素块是有1bit表示,那么我们的像素块就只有两种情况,要么是0,要么是1,所以也只能表现两种颜色,那么就是黑色和白色,如果说咱们想要多种多样的色彩的话,咱们的像素块就必须使用多个bit进行组合。
这里还得注意的一个点就是使用显卡进行输出的时候,咱们的字符得使用ASCII码来进行表示,所以一个字符得占用1个字节(8bit)。在这里为了方便咱们接下来的实际操作,我将显存分布放在下面进行给大家参考:

起始 结束 大小 用途
C0000 C7FFF 32KB 显示适配器BIOS
B8000 BFFFF 32KB 用于文本模式显示适配器
B0000 B7FFF 32KB 用于黑白显示适配器
A0000 AFFFF 64KB 用于彩色显示适配器

显卡支持文本、黑白、彩色显示三种模式,这里我们只需关注文本即可,因为我们需要实现的是类似于Linux的终端界面。
由上表可以知道,当地址处于0xB8000到0xBFFFF时,咱们在此输出的数据会直接落到显存之中,显存中有了数据,就相当与到了中间商手中,剩下的作为显示器的客户就可以直接拿到CPU所输出的数据啦。
显卡的文本模式也分多种,其中的差别也就是一页所包含的数据行列不同,也即可容纳的数据大小不同,在默认模式下为80×25(表示一行80个字符,共有25行),也就是一页可以打印2000个字符。

这里需要注意,在文本模式下也可以打印彩色字符,但是ASCII字符都是一字节大小,如何表示彩色字符呢,这里给出答案我们不用一字节来表示字符,咱们用两字节,咱们两字节的低8位来使用ASCII码(占7位)正常表示,而高八位则用来表示字符的属性,属性结构图如下:


这里的图片解释的很清楚,RGB大家也应该知道三原色,这里给出几种简单的组合让大家试试。

0x01 升级MBR

这里注意咱们要抛弃BIOS的输出了,这里使用IO来实现打印功能
给出简单代码演示,若有需要可到我的github上面获取完整源码。

  mov byte [gs:0x00], 'p'
  mov byte [gs:0x01], 0x94
  mov byte [gs:0x02], 'e'
  mov byte [gs:0x03], 0x94
  mov byte [gs:0x04], 'i'
  mov byte [gs:0x05], 0x94
  mov byte [gs:0x06], 'w'
  mov byte [gs:0x07], 0x94

运用上述方法,大伙记得将数据写道对应的地址才可以,因为这是统一编制,咱们写到这块内存区域就是说明咱们已经将他们输入到显存了。
接下来咱们同上篇一样,将修改好的汇编代码进行汇编然后打入咱们的虚拟磁盘

nasm -o mbr.bin mbr.S
dd if=./mbr,bin of=/你的路径/bochs/hd60M.img bs=512 count=1 conv=notrunc

下面是演示效果,这里给出两张照片是为了显示其在跳动。

0x02 总结

今天的环节依旧很简单,主要是基础知识的认识,大伙基本上可以快速上手,还等什么,赶快加入吧(狗头
本次源码依旧再github上保持更新,分支名为UMBR

传送门

免费评分

参与人数 14吾爱币 +22 热心值 +14 收起 理由
DaiCap + 1 + 1 我很赞同!
又飘小雪 + 1 + 1 用心讨论,共获提升!
k913 + 1 + 1 我很赞同!
QRQ + 1 + 1 我很赞同!
willJ + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zhyerh + 1 + 1 谢谢@Thanks!
sbham + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kingsword09 + 1 + 1 我很赞同!
heavenman + 1 + 1 用心讨论,共获提升!
逆向学习 + 1 + 1 谢谢@Thanks!
tianjianggouxia + 1 + 1 热心回复!
为之奈何? + 1 + 1 我很赞同!
catti518 + 2 + 1 我很赞同!
TES286 + 2 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| peiwithhao 发表于 2022-12-30 21:06
msn882 发表于 2022-12-30 19:56
mov ax,0x600   mov bx,0x700    int 0x10
好像这个是切换成文本模式吧? 能不能不调用int10 ,直接IO来 ...

这个代码你看错意思了,这里的代码是要实现清屏,将6写入ax,然后调用int 0x10执行BIOS中断,这个并没有用到IO知识。还有你说的切换模式这个不需要,因为他模式的区别是按地址来分的,在文章上面也有写的
 楼主| peiwithhao 发表于 2022-12-30 19:27
msn882 发表于 2022-12-30 19:01
再请问一下,B8000 32KB        文本显示适配器, 这个地址平时是空的吗? 只要在这个地址写入,显卡就会自动显 ...

这个显卡属于统一编址,并不需要再使用in out的io指令,使用这俩指令只有在他是独立编址的情景之下才会使用。只要写到这32kb,显卡就知道你要用的是文本模式然后显回显示器了
wanghui77725 发表于 2022-12-29 01:26
wzg01 发表于 2022-12-29 05:35
大佬厉害
zhangting2022 发表于 2022-12-29 06:51
牛逼牛逼牛逼牛逼
simmtech 发表于 2022-12-29 07:31
技术 含量  很 高               ,支持。
tianjianggouxia 发表于 2022-12-29 07:51
不明绝历,希望有一天我们自己的操作系统能占据相当的市场份额!理科大佬牛逼!!!
52896009 发表于 2022-12-29 08:07
看不懂的都很牛逼,,支持
bbsbbscom 发表于 2022-12-29 08:23
难道是理科大佬?
xzxiaoshan 发表于 2022-12-29 08:34
最强大佬啊
qianlan9289 发表于 2022-12-29 08:42
膜拜大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-31 01:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表