Foxdisk04-启动原理1

我不记得是哪个小品了,赵本山用他的标准铁岭普通话说:“我不想知道它怎么来的,我只想知道它是怎么没的。”

对编程而言,“怎么来的”实际上非常重要,不能不了解。Foxdisk的启动过程,在“如何安装1”中已经有了说明,本篇会尽量的把相关的背景知识介绍清楚。

有几个关键词:BBS、Legacy BIOS、UEFI、MBR。

BBS

英特尔、Phoenix和康柏公司在1996年联合发布了BIOS引导规约(BIOS Boot Specification),简称BBS(图2)。尽管十几年已经过去了,但是这个规约中的大多数内容至今仍被使用着。本文中使用的很多术语和数据结构都来自这个规约。

Foxdisk04-BBS spec

 图1 BIOS Boot Spec

BBS将引导设备划分为以下三种类型: 继续阅读

发表在 BIOS/UEFI | 留下评论

Foxdisk03-如何安装2

整个Foxdisk3.01的代码,是将安装程序和主程序混在一起编译的。安装程序负责将代码拷贝到指定的硬盘区域,包括MBR代码、Foxdisk的启动代码、Foxdisk的资源、Foxdisk的code段和数据段。在“如何安装1”中叙述的foxdisk在硬盘中的映像,都是由它来实现的。

混编的好处是,安装程序能够很容易的定位主程序各种段(code、data、stack等等)的位置,方便安装。另外,很多函数可以共用。坏处是,安装程序也要占据不少的空间。我之前为了方便C和汇编混合,设定了编译模式为small,也即Code段必须在64K内,Stack和Data段加起来在64K之内。我在设计初期没有考虑好,代码写到后半段就感到很痛苦—许多想实现的功能因为代码的限制,没法去实现。

现在的编译器早就取消了这样的限制,以技术而言,BorlandC++3.1已经是石器时代的产品。以我现在常用的Vs2015,从来不用去考虑类似这样的问题,可以专注在程序本身的实现。计算机软件的发展非常快,一不小心我也变成了老古董了。

回到正题。与安装相关的文件有Setup.c、Setup.h、iSetup.c和iSetup.h,与主程序共用了磁盘访问、图像显示等函数。外设的访问,在后面专门写几个章节进行介绍,用汇编去访问外设,我估计现在除了开发驱动或者OS的程序员,很少会有人去关注它们了。

从Setup.c的main()函数开始跟踪,了解安装过程。

main函数做了两件事情: 卸载和软件安装。卸载的过程故意设计得复杂,通过判断命令行以及热键,确定用户需要完全卸载,然后再将相应的扇区覆盖。这几天我重读代码,觉得这里的设计很有问题,有可能导致卸载后无法进入操作系统了。

软件安装通过两个函数实现,firstSetup()和updateSetup()。前一个函数是首次安装,后一个是针对已经安装的软件进行参数更改或者代码升级。main()最后的汇编代码:

asm mov ax,3

asm int 0x10

其作用为回到文本模式。程序是在DOS环境下,并使用图形模式安装的,如果没有回到文本模式,DOS的命令行无法执行。

通篇代码中,有大量嵌入汇编的地方。这种写法不是很好,程序可读性比较差,我主要是习惯了汇编来实现一些小功能,不自觉的就用上了。后续出现内嵌汇编的地方,都会给出解释。

firSetup()中,将安装主程序的步骤分为了四个,代码中给出了很详细的说明,很容易读懂。此函数中所调用的图形函数和磁盘访问函数,其功能都比较单一,通过函数说明可以了解其作用。

我尽量不去调用C的库函数,以防止代码量的增加。因此,很多经典的函数,比如memset、memcpy等,只能重新自己实现。另外一个原因,Foxdisk的主程序中,是没有操作系统的,那些库函数也没法运行。我参考的代码来自于linux2.6,不愧是千锤百炼的代码,非常精简高效。

firSetup()中频繁使用的汇编代码:

asm xor ax,ax

asm int 0x16

这段代码的功能是等待按键,类似于C语言中的getchar()或者pause()。

updateSetup()的实现代码在iSetup.c中,其实现方式类似于firSetup(),就不一一解释了。

这两个函数都打开了时钟中断,实现一些需要定时的功能。篇幅所限,不再详细说明,在后续章节中针对时钟中断做一个详细说明。

发表在 BIOS/UEFI | 留下评论

Foxdisk02-如何安装1

Foxdisk是基于BIOS中断或者直接访问硬件的,在设计的时候,第一个需要考虑的问题就是软件如何运行。这个问题很有趣,也是我在早期开发一个小的OS时试图搞清楚的最初的问题。

作为介于BIOS和操作系统间的一个小程序,我考虑了两种让Foxdisk运行的方法。其一是依靠硬件,将Foxdisk的引导代码放在PCI ROM或者以Option ROM的形式直接嵌入到BIOS中;另外一种是类似GRUB的方式,修改硬盘的MBR,实现Foxdisk的引导。我们首先从PC的启动过程谈起。

1)     PC启动的过程

Foxdisk02-PC_boot

图1 计算机启动过程

这是我理解的计算机的启动过程,显示了计算机从开机到进入操作系统的工作顺序。在上述的几个阶段,都可以抢得控制权,实现我们自己的代码。分别为:

阶段①:Call Rom,此阶段Option ROM可以抢得计算机的控制权。

阶段②:int19h,Option ROM软件可通过修改int 19h抢得控制权。另外,所有通过模拟可引导设备的Option ROM以使得BIOS能够引导其软件的方法均归于此阶段。

阶段③:LoadMBR,通过直接修改硬盘上的MBR区域抢得控制权。

阶段④:Load OS,在操作系统引导的时候抢得控制权。

阶段⑤:在操作系统层面安装软件。

阶段①~④均称为底层阶段,软件一般直接与计算机硬件打交道,或者通过BIOS中断访问硬件。阶段⑤称为上层阶段,软件借助于操作系统提供的各种API工作。

关于Option ROM的介绍,可以参考文档《BIOS Boot Specification》version 1.01。这是发布于1996年的文档,由intel、Phoenix和Compaq联合制定的规范。多年来,BIOS的启动过程也没有太大的变化,直到UEFI的出现。

具体的内容我不在博客中介绍,文档中介绍得很清楚。只要记住两点即可:第一,BIOS允许外设有自己的代码,用来实现一些特殊的功能,比如网卡的Option ROM、PCI设备的Option ROM;第二,只要依据一定的规范来写代码,BIOS会将控制权转移给Option ROM,这时整个计算机的控制权都在手中,理论上做什么都可以。

继续阅读

发表在 BIOS/UEFI | 留下评论

Foxdisk01-缘起

Foxdisk01-bootpic

“没有任何一个题目是彻底完成了的。总还会有些是哪个可做;在经过充分的研究和洞察以后,我们可以将任何解题方法加以改进;而且无论如何,我们总可以深化我们对答案的理解。”

–《怎样解题:数学思维的新方法》

用一段话来总结我自己的这个小项目,我以为上面的这段话很精准。从2006年1.00版开始,到2008年的冬天完成3.01版,直到现在,我也不觉得这个项目完成了。只是因为各种原因,没有动力再去更新它了,曾经写在计划中的4.0版,列出了许多我很有兴趣的功能,不大可能再去实现了。

继续阅读

发表在 BIOS/UEFI | 标签为 | 留下评论

GVT对显示引擎的虚拟(2)

引用注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog/

  • 1. GVT对显示中断的模拟
ISR

中断能打断普通线程的执行

显示引擎定义的中断大部分都是通用型的,不同设备厂商开发的不同代产品在工作的时候,都会不断产生这些中断。比如同步中断(v-sync和h-sync)、vblank中断、扫描中断,这些中断和终端显示器对帧囊(FrameBuffer)的处理相关,在数据处理过程中不断地实时产生;以及插拔检测(hot plug detection)中断,当显示器插入或拔出Port的时候产生。显示引擎也可能会定义一些私有类型的中断,因不同的显卡设备而异,比如一些错误检测中断,其实是硬件和软件驱动之间的一种简单的通信机制。

GVT虚拟的显示设备只实现了最基本的功能,所以模拟通用型中断就足够了。实际上,GVT现在的代码只模拟了vblank和flip done两种中断,发现已经能够满足系统驱动和大部分应用软件的需求了。当然这是不够的,已经发现了一些应用软件,依赖于线扫描中断和垂直同步中断,不久的将来,GVT会陆续加入对它们的支持。理想的情况是GVT把所有的通用型显示中断都模拟好,我们不能假设形形色色的应用软件永远不会使用某种通用型中断。 继续阅读

发表在 虚拟化 | 标签为 , , | 一条评论

GVT对显示引擎的虚拟(1)

引用注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog/

server-virtualization

这是一幅描绘了平台虚拟化的示意图

GVT是Intel针对集成显卡(IGD)设备实现的虚拟化方案,最近已经被成功地Upstream到了Linux内核4.10中了。所以用户只要拥有一份最新的Linux内核代码或镜像文件,就可以尝试这个很酷的显卡虚拟化功能。但GVT只是一个核心模块,剥离了和具体的系统虚拟化方案的耦合性,所以要想通过GVT来虚拟化你的显卡,还必须结合特定虚拟化平台下的适配模块。GVT本身是平台无关的,它通过一套公共的接口来抽象各种虚拟化平台的功能。

KVMGT是一起被Upstream的另一个模块,它就是在KVM(Kernel Virtual Machine)平台下GVT的适配模块。虚拟软件比如QEMU在KVM平台上,可以通过KVMGT暴露的用户层接口,来创建和维护GVT的虚拟GPU实例。将来,GVT在XEN和其它虚拟化平台下的适配模块,也将会被Upstream到Linux内核中去,不过这需要一些时间和持续的努力。 继续阅读

发表在 虚拟化 | 标签为 , , | 留下评论

Foxdisk00-源代码编译

为了便于之后博文的行文方便,我把代码放在了下载区:[download id=”9″]。

编译器使用的是Borland C++3.1,C编译器和汇编编译器都在其中。代码中包含三个汇编文件:Loaser.asm、iMath.asm、iTimeInt.asm,必须用Tasm编译。微软的masm语法要求稍微有些不同,因此foxdisk3.01的代码没有办法直接用微软早期的DOS下编译器编译。

编译步骤很简单:

1)      安装BorlandC++3.1;

2)      进入代码文件主目录,设置Path目录;(参考我的bcccmd.bat)

3)      etrhz.exe hztable.h Global.c Setup.c iSetup.c;

4)      ehz24.exe /k hzk24k.h _HZ24STR.c;

5)      运行make;

上述步骤执行后,会自动生成foxdisk.exe。在dos下安装的时候,需要调用资源文件ifox.bmp,包含在\Rleease文件夹中。

继续阅读

发表在 BIOS/UEFI | 标签为 | 留下评论

为自己定一个小目标

我的童年有很长的时间是在外婆家度过的,那个时候,外婆的爸爸妈妈还健在—我们的方言里称呼为“老外公、老外婆”。老外婆家离外婆家大概只有3公里左右,路两旁全是一拢拢农田和纵横交错的沟渠。进村子前,有几片不大的树林点缀在村子入口,松树、茶树、香樟树,还有一些我叫不出名字的树。春夏之交的时候,栀子花开了,空气中就飘着淡淡的栀子花甜香。

老外公和老外婆已经去世多年,我已经很难记得他们的样子;去拜见他们的场景记忆也慢慢开始模糊,唯有那飘在道路旁边的栀子花香味,始终不散。把这些回忆记录下来,是我很喜欢的事情。从小养成了的这种记录习惯,我的电脑里面有各种心情记录、管理记录,以及技术开发记录。这是比较私密的个人信息,作为技术宅男,我不是很喜欢把它们发布到QQ空间以外的地方。

改变这种想法从一位很好的朋友开始。

15年7月,参加了一次集体翻译的活动,第一次见到张佩。实际上对他慕名已久,公司产品开发中有时候需要驱动开发的知识,他的大作《竹林蹊径》是案边常用参考书。

张佩说话声音洪亮、语速很快、思考很快、写代码也很快,学习新技术奇快无比,我非常佩服。我是性格比较内向的人,不知道为什么,和他却一见如故,很快就像多年的好友一样无话不谈了。

那时我准备将我的foxdisk移植到uefi上,实现自己想要的一些功能。张佩很有兴趣,我就把自己的foxdisk 3.0的代码和文档给了他,请他指正。之后我有几次上海出差,每次都会抽一些时间去见他,他建议我把平常的一些技术学习的历程用博客写下来。 继续阅读

发表在 BIOS/UEFI | 标签为 | 留下评论

浅论Intel GPU虚拟化实现方案GVT

引用注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog/

v0.3 (未完成版,慎勿转载)

kvmgt

KVMGT未upstream前的架构图

在最近的Linux内核4.10的发布中,Intel的GPU虚拟化方案(GVT)完成了代码上传,从此成为Linux内核的一部分。GVT在4.10的发布文档中,作为主要的新特性之一而被发布者隆重地介绍。在过去的两年中,我作为一名开发者,参与到了GVT的开发过程中。对此重大里程碑事件深感欣慰。将陆续写作一些文章,对Inte的GPU驱动和虚拟化实现,进行由粗入细的介绍。

我近来对于一些计算机术语,产生了一点个人趣味上的偏好,细节在此不能备述,容后专文细讲。这里就两个用惯的术语,要在文章中,做很大的习惯上的改变,读者可能会觉得很不适应。无法,我确定了要这样做,只能请读者忍耐。

术语新译
Context:境(一般译作:上下文)
Execution Context:执行境
Hardware Context: 硬境
Logic Context:拟境
buffer:囊(一般译作:缓冲区)
Ring buffer:环形囊

继续阅读

发表在 虚拟化 | 标签为 , , , | 2条评论

网络内核调试的春天

今天试了两个虚拟机,virtualbox和vmware player,看能不能支持网络调试。结果非常满意,两个虚拟机软件默认配置的虚拟网卡,都能用于建立网络内核调试连接,我三下两除二地,就把内核调试给建立了。vmware中的网卡设备是82574L Gigabit NIC,设备ID是8086/10D3。VirtualBox中的网卡设备是Pro/1000 MT(即颇为经典的E1000系列),设备ID是8086/100E。检查Windows网络内核调试所支持的NIC列表,发现这两块网卡,都在被支持的列表中。链接:Supported NIC for network kernel debug。

不同的虚拟机软件配置其虚拟网卡的方式不尽相同,我比较喜欢VirtualBox,它直接提供了一个可选列表框让用户选择,默认是Pro/1000 MT。VMWare Player则没有类似的接口,但我查看了网上的一些资料,用户也可以通过直接修改配置文件的方式,配置虚拟网卡的类型。 继续阅读

发表在 软件调试 | 标签为 | 留下评论