Bochs 项目源码分析与注释
Understanding the source code of bochs
作者:喻强
MAY 2006
Bochs 项目源码分析与注释 MAY 2006
Understanding the source code of bochs
1
Bochs 项目源码分析与注释 MAY 2006
写在前面
今天,虚拟机及虚拟化技术在计算机领域扮演越来越重要的角色,从 CPU 模拟器到服
务器虚拟化管理软件,从商业化的成熟软件到开发源码的自由软件项目。形形色色的虚拟机
程序光名字就让人目不暇接。它们实现的功能也不尽相同: JAVA 虚拟机实现了代码的跨平
台运行,Virtual PC 提供了一台虚拟的 PC 机供人们使用,VMware ESX server 则将一台功能
强大的服务器划分称为若干网络虚拟主机。还有一些实际上可以被称为模拟器的虚拟机则仿
真了某种 CPU 及系统的功能。
本文讲述的 Bochs 即为一个 x86 CPU 的模拟器,它是一个用 C++语言写成的高移植性
的开源IA-32 架构的PC 模拟器,可以在很多的流行操作系统上运行。它模拟了Intel x86 CPU,
常见 IO 设备以及一个 BIOS。 当前, Bochs 可以编译为模拟 386,486,Pentium,Pentium
Pro 或 AMD64 CPU,包括可选的 MMX,SSE,SSE2 和 3DNow!指令集。Bochs 中可以运行
的操作系统包括 Linux,DOS,Windows。Bochs 由 Kevin Lawton 在 1994 年开始编写。它最
初是作为商业产品开发的,但到了 2000 年 3 月,Mandrakesoft 公司买下了 Bochs,使之成
为遵循 GNU LGPL 的开源软件。2001 年 3 月,Kevin 帮助一些开发者把 Bochs 移到了
sourceforge.net 网站。
Bochs 可以使用不同的模式编译,有些还在开发之中。典型的应用就是提供了完整的
x86 PC 模拟器,包括 x86 CPU、硬件设备以及存储器。因为是一个开源的项目,在互联网
上得到了世界各地的程序爱好者的支持,不断的对其进行功能完善并修改存在的错误,在
2006 年 1 月 29 日,Bochs 的最新版本 2.2.6 版已经发行。
经过为期几个月的源码阅读,我把自己理解的一些东西整理出来,并结合相关知识点
给出了简要的分析,这些代码基本上覆盖了 Bochs 工程的主体线索。当然,整个 Bochs 工程
由 300 多个源文件组成,代码约 20 万行,不可能全部列出,因此,只对重要的数据和结构
作了注释。通过对源码的研究和学习,能够更为深入的理解 x86 CPU 及 PC 系统的工作原理。
你可以看到硬件对每条指令的执行是怎样用软件精确的再现出来,存储器地址究竟是如何映
射的,你也会学到怎么去编程驱动一个 ATA 设备或显卡……所有的隐藏在硬件中的东西被
Bochs 暴露无遗。
了解嵌入式系统的读者一定知道 SkyEye,这是清华大学开发的 ARM 平台模拟器,目
前很多功能已经实现,该项目得到了嵌入式 Linux 开发爱好者的支持和极力推崇。当我知道
了这个项目的时候,我觉得这是一条很好的路,作为致力于底层程序设计的软件人员,应该
Understanding the source code of bochs
Bochs 项目源码分析与注释 MAY 2006
踏实的掌握每一个细节,理解每一个具体概念,而不应当只停留在调用某个现成的函数的水
平上。
希望这篇源码分析报告能够给从事 x86 体系上系统程序或设备驱动程序设计的人们一
点参考和帮助。时常听说学习 Linux 的最好方法就是去阅读源代码,所以希望我的工作能够
起到抛砖引玉的作用,让更多的人来掌握和运用这个学习方法。
由于水平有限,文中出现的错误敬请指正!
2006.5 于南京工业大学
Understanding the source code of bochs
Bochs 项目源码分析与注释 MAY 2006
Table of Content
Chapter 1 x86 体系结构与 PC 系统概要 .....................................1
1.1 x86 CPU 结构...............................................................................................................1
1.1.1 冯诺依曼架构和 CISC 指令集......................................................................1
1.1.2 CPU 结构........................................................................................................1
1.1.3 CPU 工作模式................................................................................................2
1.2 x86 体系结构概览........................................................................................................3
1.3 PC 系统.........................................................................................................................5
1.3.1 PC 系统概述...................................................................................................5
2.3.2 总线拓扑.........................................................................................................6
2.3.3 存储器与 I/O 编址 .........................................................................................6
2.3.4 关于系统的启动与引导.................................................................................8
Chapter 2 Bochs 工程概述 ....................................................... 11
2.1 开源项目 Bochs 介绍.................................................................................................11
2.2 版本 2.2.1 源码组织..................................................................................................11
2.3 工程类结构.................................................................................................................12
2.4 主体框架结构分析.....................................................................................................13
2.4.1 Bochs 工程中的重要类................................................................................13
(1) VM 控制台界面类 .............................................................................................13
(2) CPU 模拟............................................................................................................14
(3) Memory 模拟......................................................................................................14
(4).I/O device 模拟...................................................................................................15
2.4.2 入口函数 main()及 Win32 Gui 初始化........................................................15
2.5 Bochs 的工作方式......................................................................................................18
Chapter 3 CPU 类的源码分析 ...................................................20
3.1 CPU 类概述................................................................................................................20
3.1.1 CPU 逻辑结构框图......................................................................................20
3.1.2 类 BX_CPU_C 成员归纳.............................................................................20
3.2 类 BX_CPU_C 源码分析..........................................................................................21
3.2.1 CPU 特性声明..............................................................................................21
3.2.2 类 bxInstruction_c 成员分析........................................................................22
3.2.3 类 BX_CPU_C 源码注释.............................................................................22
3.3 通用寄存器.................................................................................................................29
3.3.1 数据结构与注释...........................................................................................29
3.3.2 通用寄存器归纳...........................................................................................30
3.4 段寄存器、全局寄存器 GDI 和 IDT ........................................................................31
3.4.1 数据结构与注释...........................................................................................31
3.4.2 段寄存器结构分析.......................................................................................33
3.5 CPU 状态字 EFLAGS................................................................................................35
3.5.1 数据结构与注释...........................................................................................35
Understanding the source code of bochs
Bochs 项目源码分析与注释 MAY 2006
3.5.2 源码分析.......................................................................................................39
3.6 函数 CPU_LOOP()结构分析.....................................................................................40
3.6.1 CPU_LOOP()函数总体结构........................................................................40
3.6.2 函数 CPU_LOOP()源码注释.......................................................................41
3.7 函数 handleAsyncEvent()分析...................................................................................44
3.7.1 函数 handleAsyncEvent()知识准备 .............................................................44
3.7.2 函数 handleAsyncEvent()结构分析 .............................................................46
3.7.3 函数 handleAsyncEvent()源码注释 .............................................................47
3.8 取指与执行.................................................................................................................50
3.8.1 Intel IA-32 指令结构....................................................................................50
3.8.2 类 bxInstruction_c 的数据成员....................................................................53
3.8.3 取指译码函数 FetchDecode()分析 ..............................................................55
3.8.4 模拟指令的执行...........................................................................................59
Chapter 4 CPU 中断处理任务管理............................................60
4.1 IA-32 体系结构中断知识准备 ..................................................................................60
4.1.1 中断和异常概述...........................................................................................60
4.1.2 异常和中断向量...........................................................................................60
4.1.3 中断和异常来源...........................................................................................61
4.1.4 与中断处理相关的数据结构.......................................................................62
4.1.5 异常和中断的处理方法...............................................................................64
4.2 Bochs 对中断的模拟..................................................................................................68
4.2.1 概述...............................................................................................................68
4.2.2 主要函数的源码注释...................................................................................69
4.3 虚拟机的任务管理.....................................................................................................82
4.3.1 IA-32 任务管理知识准备 ...........................................................................82
4.3.2 函数 task_switch()源码注释 ........................................................................89
Chapter 5 存储器源码分析........................................................104
5.1 IA-32 体系的存储器结构 ........................................................................................104
5.2 Bochs 对存储器的模拟............................................................................................105
5.3 存储器类 BX_MEM_C 部分源码分析 ...................................................................107
5.3.1 相关数据结构与类定义.............................................................................107
5.3.2 相关函数分析.............................................................................................108
5.3 模拟分页机制...........................................................................................................115
5.3.1 分页 (Paging)概述.....................................................................................115
5.3.2 页目录与页表.............................................................................................116
5.3.3 线形地址转换.............................................................................................117
5.3.4 实现分页机制的源码分析.........................................................................120
Chapter 6 系统板与外设模拟 ..................................................136
6.1 Bochs 系统板描述类 bx_pc_system_c ...................................................................136
6.1.1 类 bx_pc_system_c 功能概述 ....................................................................136
6.1.2 PC system 定时器管理...............................................................................136
Understanding the source code of bochs
Bochs 项目源码分析与注释 MAY 2006
6.1.3 类 bx_pc_system_c 源码分析与注释 ........................................................138
6.2 设备集合类 bx_devices_c........................................................................................146
6.2.1 类 bx_devices_c 成员变量分析 .................................................................146
6.2.2 类 bx_devices_c 成员函数分析与注释 .....................................................149
6.2.3 设备的初始化.............................................................................................150
6.2.4 设备复位.....................................................................................................154
6.2.5 设备访问(读写)的处理.........................................................................155
6.2.6 已注册的 I/O handlers 和 IRQ 清单 ..........................................................159
6.3 定时器(PIT)类分析.............................................................................................166
6.3.1 类 bx_pit_c 概述.........................................................................................166
6.3.2 类 bx_pit_c 源码注释.................................................................................166
6.3.3 关于类 bx_virt_timer_c ..............................................................................173
6.4 IDE 设备...................................................................................................................173
6.4.1 磁盘控制器 controller_t .............................................................................173
6.4.2 IDE 驱动器描述类 bx_hard_drive_c .........................................................174
6.4.3 读写磁盘映象.............................................................................................175
6.4.4 ATA/IDE 控制器(通道)和设备初始化.................................................176
6.4.5 ATA 控制器的寄存器读写 ........................................................................184
6.4.6 CD ROM 设备 ............................................................................................193
6.5 PCI 子系统 ...............................................................................................................203
6.5.1 PCI 概述 .....................................................................................................203
6.5.2 PCI 主桥描述类 bx_pci_c 分析.................................................................209
6.6 VGA 设备模拟.........................................................................................................215
6.6.1 模拟 VGA 的类 ..........................................................................................215
6.6.2 VGA 在 svga_timer 中的更新 ...................................................................216
Appendix ...................................................................................217
Appendix A.Bochs 配置文本说明 ....................................................................................217
Appendix B.ATA 和 ATAPI 编程介绍 .............................................................................225
Appendix C.Sound Blaster 16 编程...................................................................................230
Appendix D.VESA 编程介绍............................................................................................240
Appendix E.Bochs 上运行的操作系统示范.....................................................................261
Understanding the source code of bochs
Bochs 项目源码分析与注释 MAY 2006
Chapter 1 x86 体系结构与 PC 系统概要
Bochs 不仅仅模拟了 x86 CPU,还包括一整套 PC 系统的各种部件。因此在对 Bochs
进行研究之前,需要分析 x86 体系结构和 PC 系统。
1.1 x86 CPU 结构
1.1.1 冯诺依曼架构和 CISC 指令集
从系统结构上,计算机主要可以分为冯·诺伊曼结构和哈佛结构。冯·诺伊曼结构,也
称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指
令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度
相同,Intel 公司 x86 就是使用了这个结构。当然还有其他的,如 MIPS 公司的 MIPS 处理器。
哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。中央处理器首先到程序
指令存储器中读取程序指令内容,解码后得到数据地址,再到相应的数据存储器中读取数据,
并进行下一步的操作(通常是执行)。程序指令存储和数据存储分开,可以使指令和数据有
不同的数据宽度。哈佛结构的微处理器通常具有较高的执行效率。其程序指令和数据指令分
开组织和存储的,执行时可以预先读取下一条指令。使用哈佛结构的中央处理器和微控制器
有 Motorola 公司的 MC68 系列和 ARM 公司的 ARM9、ARM11 等。
从指令集划分,计算机可以分为复杂指令集计算机(CISC)和精简指令集计算机(RISC)。
从命名上就可以看出,CISC 包含了一套复杂的指令集。往往一条指令就可以完成一套复杂
的操作,而在 RISC 中,这些操作需要几条指令才能完成。CISC 和 RISC 各有利弊,一直称
为计算机结构讨论的热门话题,CISC 功能强大但译码器复杂,RISC 简洁但需要更多的指令
完成相同的操作。最终结论是 CISC 和 RISC 应该互相借鉴优点,而不应该在划分界线上争
论,事实上处理器的发展也正是沿这个趋势进行的。
1.1.2 CPU 结构
从物理结构上看,x86 CPU 结构比较复杂的,概括的说包括运算器,控制器以及辅助设
Understanding the source code of bochs
1