实验内容
-
认真阅读课本章节资料
-
在实验机上安装virtualbox,并安装ubuntu
-
安装ubuntu开发环境
-
下载bochs源码,编译并安装bochs环境
-
使用bochs自带工具bximage创建虚拟软驱
-
阅读、编译boot.asm,并反汇编阅读
-
修改bochsrc,运行调试你的第一个程序
-
重点掌握课本14页表2.1 的bochs调试指令
注意事项
-
Virtualbox及其增强包下载:Downloads – Oracle VM VirtualBox
-
Ubuntu下载:Index of /ubuntu-releases/
-
修改ubuntu源方法:Ubuntu镜像使用帮助
-
Bochs编译注意事项
可能需要安装build-essential、libx11-randr0-dev、libxrandr-dev,可在编译过程中发现
-
修改bochsrc中部分内容:
修改romimage 和vgaromimage对应的文件位置,以你的实际安装位置为准
注释掉keyboard_mapping一行
实验过程
-
在实验机上安装virtualbox,并安装ubuntu环境,32位环境
![](https://i-blog.csdnimg.cn/blog_migrate/bb766133d083a5bfe0c651732e585463.png)
-
下载bochs源码,编译并安装bochs环境
(1)首先下载bochs 2.6.9,下载完毕后复制到ubuntu中
![](https://i-blog.csdnimg.cn/blog_migrate/9bde20a9365a6c019ee246fe211613a3.png)
(2)安装必要环境
先修改ubuntu源
备份原来的源:
sudo cp /etc/apt/sources.list /etc/apt/sources_init.list
更换源:
sudo gedit /etc/apt/sources.list
将原本的内容清空,将新的源复制进去
更新源:
sudo get-apt update
复损坏的软件包,尝试卸载出错的包,重新安装正确版本的:
sudo apt-get -f install
更新软件:
sudo apt-get upgrade
之后安装必要环境:
sudo apt-get install g++
sudo apt-get install build-essential
sudo apt-get install libgtk2.0-dev
sudo apt-get install bison
sudo apt-get install libx11-dev
sudo apt-get install libxrandr-dev
sudo apt-get install libsdl1.2-dev
sudo apt-get install vgabios
sudo apt-get install bximage
(3)安装bochs
tar vxzf bochs-2.6.9.tar.gz
![](https://i-blog.csdnimg.cn/blog_migrate/cdc6f266e41d182af16630cb13af2809.png)
cd bochs-2.6.9
./configure --enable-debugger --with-sdl --enable-disasm --enable-readline LIBS='-lX11'
![](https://i-blog.csdnimg.cn/blog_migrate/afcdb0ede83777688c6dc03e3f15c76f.png)
sudo make
![](https://i-blog.csdnimg.cn/blog_migrate/219165a4d780347b08b62a14a1077257.png)
sudo make install
![](https://i-blog.csdnimg.cn/blog_migrate/64a1e61831de6929bc7857f83396a447.png)
-
使用bochs自带工具bximage创建虚拟软驱
![](https://i-blog.csdnimg.cn/blog_migrate/878d3a0db3beae10b1357d28b7bb29db.png)
创建的a.img位于Home
![](https://i-blog.csdnimg.cn/blog_migrate/69c9ffc9760e57a8b92e7b3a35fcffee.png)
-
安装nasm,阅读、编译boot.asm,并反汇编阅读
(1)安装nasm
![](https://i-blog.csdnimg.cn/blog_migrate/6769bd85deac7ae394159d44ea157705.png)
(2)阅读,编译boot.asm
nasm boot.asm -o boot.bin
![](https://i-blog.csdnimg.cn/blog_migrate/8c9da40b8725005d1eefecbed2d8b9d8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ba72d96d3b9ff7e95700e27c76a7818f.png)
(3)反汇编阅读
ndisasm -o 0x7C00 boot.bin >> disboot.asm
![](https://i-blog.csdnimg.cn/blog_migrate/0eeefb145e817136504a595e6346494d.png)
-
写引导盘
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
![](https://i-blog.csdnimg.cn/blog_migrate/92b1e1a0ac48438dd0cc77e33009b034.png)
-
修改bochsrc,运行并调试你的第一个程序
(1)修改bochsrc
修改vgaromimage和romomage对应的文件位置,注意是bochs安装后的位置,而不是tar解压的bochs文件夹中的文件
注释掉keyboard_mapping一行
增加display_library:sdl
![](https://i-blog.csdnimg.cn/blog_migrate/76fafef50dfaaff92e72e58f481f9589.png)
修改后相当于规定了启动软盘是a.img
(2)运行
要将a.img、boot.asm、boot.bin、bochsrc几个文件放在同一个文件夹下,cd到该文件夹下
bochs -f bochsrc
![](https://i-blog.csdnimg.cn/blog_migrate/83498aadce3ba8ff2923a39e561eefc1.png)
然后输入6开始simulation
输入c,continue
![](https://i-blog.csdnimg.cn/blog_migrate/b585719f462a7cb3babb9b263b348a02.png)
完成!
![](https://i-blog.csdnimg.cn/blog_migrate/722ddbdf837cd2a36a271c700a7d318d.png)
-
实验练习
(1)删除0xAA55,观察程序效果,找出原因
修改后的boot.asm
![](https://i-blog.csdnimg.cn/blog_migrate/08ffb0b32b165a50b9e0b8faf66555b0.png)
nasm编译为b2.bin
bximage创建新的软盘a2.img
修改bochsrc中a.img为a2.img
写引导盘:dd if=b2.bin of=a2.img bs=512 count=1 conv=notrunc
bochs运行
![](https://i-blog.csdnimg.cn/blog_migrate/6ae9f5bdfd240bed2298c6c9bb64e969.png)
发现输入c后无法运行,直接退出,也没有显示“Hello, OS world!”
因为位于1扇区的512字节且最后字节为aa55的程序为引导程序,a.img为引导盘,aa55即为标志,删除了该标志后相当于没有了引导程序,所以无法运行直接退出
(2)修改程序中输出为一个包含自己名字的字符串,调试程序
只需要根据想要输出的字符串修改BootMessage,接着根据BootMessage的长度修改cx即可
修改后的boot.asm:
![](https://i-blog.csdnimg.cn/blog_migrate/e9913424abdb1a3f4cecf15d951ccd96.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/bf24002bfea2332cfe5cf2c61dbc671c.png)
(3)把生成的可执行文件反汇编,看看输出的内容是怎样的,并在虚拟机启动过程设置断点进行调试,在实验报告中截图
使用ndisasm -o 0x7C00 boot.bin >> disboot.asm命令进行反汇编,得到disboot.asm:
![](https://i-blog.csdnimg.cn/blog_migrate/d785ebda0a5cec025079c857a57f85af.png)
对写入了原始boot.asm编译产生的boot.bin的a.img用bochs调试
b 0x7a00设置断点
C 运行到断点
![](https://i-blog.csdnimg.cn/blog_migrate/df4e4fcd40e2689694f60e63b67c0ec1.png)
info cpu查看cpu寄存器
![](https://i-blog.csdnimg.cn/blog_migrate/e2732dbfddc84a39cb46ccf2294ca0cc.png)
n 单步运行(遇到函数会跳过)
![](https://i-blog.csdnimg.cn/blog_migrate/b213b4414638b6eef5b003f90e8e7021.png)
s 单步运行(会跳入函数)
![](https://i-blog.csdnimg.cn/blog_migrate/9cfd38d1b6600d8a6caca680eac1020c.png)
(4)为什么要jmp $,如何改造程序,让这个输出过程执行100次
jmp $在这里的作用是做一个无限循环,让CPU停在此处,不能再往下运行。假如没有这个无限循环,CPU就会按着CS:IP一路往下执行,能执行的执行,不能执行的则crash,而我们不想看到这样的情况。
想要让这个输出过程执行100次,可以在call DispStr前加上一句mov cx, 100,在后面加上一句loop $-2,即可实现100次循环
(5)为什么要对段寄存器进行赋值
段寄存器是为对内存的分段管理而设置的。在进行内存分段时,段的部分信息将被写入段寄存器中以保存当前内存的分段模式。即使是最简单的操作系统,也是一个程序,也需要占用内存来运行,所以给段寄存器赋值是不可避免的。
(6)如何在该程序中调用系统中断
将程序打印的字符串以用户输入的形式来赋值,比如C语言就是使用scanf函数来获取,这样就可以调用系统中断,等待键盘输入。
总结
实验是上学期做的,现在跟着之前的实验报告写到博客上。这个博客只是给不会做的同学指导一下步骤,没有什么高深的见解和创新。
祝各位同学实验顺利呀~