MIT 6.828 Operating System Engineering
此类中使用两组工具:x86模拟器,QEMU,用于运行内核; 和编译器工具链,包括汇编器,链接器,C编译器和调试器,用于编译和测试内核
安装QEMU
QEMU是一款现代化的快速PC模拟器
- 克隆IAP 6.828 QEMU git存储库
git clone https://github.com/geofft/qemu.git -b 6.828-1.7.0
- 在Linux上,可能需要安装SDL开发库以便获得图形VGA窗口,在Ubuntu下使用如下命令安装
sudo apt-get install libsdl1.2-dev
- 安装
sudo apt-get install python2.7 python2.7-dev
,而且不支持python3以上1
2Python 2.4 or later is required.
Note that Python 3 or later is not yet supported.
依旧有错误1
2
3
4
5ERROR: pixman not present. Your options:
(1) Preferred: Install the pixman devel package (any recent
distro should have packages as Xorg needs pixman too).
(2) Fetch the pixman submodule, using:
git submodule update --init pixman
于是,用apt-cache查找了关于pixman的依赖包apt-cache search pixman
- 选择安装libpixman-1-dev的那个包,
sudo apt-get install libpixman-1-dev
配置qemu代码
./configure --disable-kvm --python=python2.7 [--prefix=PFX] [--target-list="i386-softmmu x86_64-softmmu"]
,prefix
参数指定QEMU安装目录; 若没有该参数,默认安装到 /usr/local。target-list
参数指定QEMU模拟的CPU架构。执行成功后,会显示一系列参数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Install prefix /usr/local
BIOS directory /usr/local/share/qemu
binary directory /usr/local/bin
library directory /usr/local/lib
libexec directory /usr/local/libexec
include directory /usr/local/include
config directory /usr/local/etc
local state directory /usr/local/var
Manual directory /usr/local/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /home/xzy/qemu
C compiler cc
Host C compiler cc
C++ compiler c++
...make && make install
依旧有错误1
2
3
4
5
6util/qemu-sockets.c:33:18: error: ‘on’ defined but not used [-Werror=unused-const-variable=]
static const int on=1, off=0;
^~
cc1: all warnings being treated as errors
/home/xzy/qemu/rules.mak:25: recipe for target 'util/qemu-sockets.o' failed
make: *** [util/qemu-sockets.o] Error 1
修改util/qemu-sockets.c
,删除on定义
依旧出现了问题1
2
3
4
5
6
7
8
9
10
11
12
13
14vl.c: In function ‘main’:
vl.c:2778:5: error: ‘g_mem_set_vtable’ is deprecated [-Werror=deprecated-declarations]
g_mem_set_vtable(&mem_trace);
^
In file included from /usr/include/glib-2.0/glib/glist.h:32:0,
from /usr/include/glib-2.0/glib/ghash.h:33,
from /usr/include/glib-2.0/glib.h:50,
from vl.c:59:
/usr/include/glib-2.0/glib/gmem.h:357:7: note: declared here
void g_mem_set_vtable (GMemVTable *vtable);
^
cc1: all warnings being treated as errors
rules.mak:57: recipe for target 'vl.o' failed
make: *** [vl.o] Error 1
其实解决起来很简单,在Makefile文件最后加上一行QEMU_CFLAGS+=-w
就可以
BUG真多1
2
3
4
5
6
7
8
9
10
11/home/xzy/qemu/hw/i386/pc.c:894:18: error: ‘parallel_irq’ defined but not used [-Werror=unused-const-variable=]
static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
^~~~~~~~~~~~
/home/xzy/qemu/hw/i386/pc.c:893:18: error: ‘parallel_io’ defined but not used [-Werror=unused-const-variable=]
static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
^~~~~~~~~~~
cc1: all warnings being treated as errors
/home/xzy/qemu/rules.mak:25: recipe for target 'hw/i386/pc.o' failed
make[1]: *** [hw/i386/pc.o] Error 1
Makefile:144: recipe for target 'subdir-i386-softmmu' failed
make: *** [subdir-i386-softmmu] Error 2
简单粗暴就是注释掉
安装的时候,还碰到了权限的问题,使用sudo su
而不是su
能进入root
在执行qemu-system-i386
之后就能将xv6源码编译后,放入qemu执行
但这一步,意味着MIT官方的QEMU已经安装好
载入xv6
先要下载lab代码
在进入lab文件夹进行编译之间,如果GCC版本是7.0
以上一定要给虚拟机GCC版本降级,不然会出现奇奇怪怪的错误,我已经被这个给搞狂躁了!!!具体方法1
2root@ubuntu:~# sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
update-alternatives: using /usr/bin/gcc-4.8 to provide /usr/bin/gcc (gcc) in auto mode
降级好后,下载源码并进行编译(进入lab目录,执行make
),就如原文所说,需要安装gcc-multilib
,使用命令sudo apt-get install gcc-4.8-multilib
完成上面的步骤后,会得到一个obj/kern/kernel.img
作为模拟PC“虚拟硬盘”的内容提供。此硬盘映像包含我们的引导加载程序obj/boot/boot
和我们的内核obj/kernel
编译完内核源码,我们就可以把它运行在QEMU上啦!首先在lab目录下面,输入make qemu
,此时qemu就开始自动加载我们的操作系统内核映像文件
成功!!
GDB
Ctrl-c
:暂停机器并按当前指令进入GDB。如果QEMU有多个虚拟CPU,则会暂停所有虚拟CPUc(或continue)
:继续执行直到下一个断点或Ctrl-csi(或stepi)
:执行一条机器指令b function
或b file:line
(或 breakpoint):在给定的函数或行上设置断点b *addr
(或breakpoint):在EIP地址处设置断点set print pretty
:启用数组和结构的漂亮打印info registers
:打印通用寄存器,eip
eflags
和段选择器x/Nx addr
:显示从虚拟地址addr开始的N个字的十六进制转储。如果省略N,则默认为1x/Ni addr
:显示从addr开始的N个汇编指令。使用$eip
作为addr将在当前指令指针处显示指令symbol-file file
:(Lab 3+)切换到符号文件文件。当GDB附加到QEMU时,它没有虚拟机中的进程边界的概念,因此我们必须告诉它使用哪些符号。默认情况下,我们将GDB配置为使用内核符号文件obj/kern/kernel
。如果机器正在运行用户代码,例如hello.c
,则可以使用符号文件obj/user/hello
切换到hello符号文件
QEMU将每个虚拟CPU表示为GDB中的线程,因此您可以使用GDB的所有线程相关命令来查看或操作QEMU的虚拟CPU
thread n
:GDB一次关注一个线程(即CPU)。此命令将焦点切换到线程n,从零开始编号。info threads
:列出所有线程(即CPU),包括它们的状态(活动或暂停)以及它们所处的功能。
lab源码
实验要用的材料都已经上传源码,其中包括lab
、qemu
、homework
等实验源码和答案