从 01 开始 从 01 开始
首页
  • 计算机简史
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • 数据库
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Node
  • Windows 使用技巧
  • 最全面的输入法教程
  • 浏览器
  • 终端软件
  • 装机
  • 笔记类软件
  • Markdown
  • 各大平台
  • 远程控制
  • RSS
  • 图片类工具
  • Office
  • 手机
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 教程简介
  • 英语学习方法论
  • 字母
  • 音标
  • 单词
  • 语法
  • 英语兔的相关视频
  • Larry 想做技术大佬的相关视频
  • 驾驶技能
  • 住房相关
  • 厨艺
  • 关于税
  • 理财
  • 睡眠
  • 皮肤
  • 口腔健康
  • 学会呼吸
  • 健身日志
  • 电影

    • 电影推荐
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 反腐
  • GFW
  • 404 内容
  • 审查与自我审查
  • 互联网
  • 2022
  • 2023
  • 2024
  • 2025
  • 关于本站
  • 关于博主
  • 网站动态
  • 公告栏
  • 友人帐
  • 从零开始搭建一个博客
  • 搭建邮件服务器
  • 本站分享
  • 文章分类
  • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 计算机简史
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • 数据库
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Node
  • Windows 使用技巧
  • 最全面的输入法教程
  • 浏览器
  • 终端软件
  • 装机
  • 笔记类软件
  • Markdown
  • 各大平台
  • 远程控制
  • RSS
  • 图片类工具
  • Office
  • 手机
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 教程简介
  • 英语学习方法论
  • 字母
  • 音标
  • 单词
  • 语法
  • 英语兔的相关视频
  • Larry 想做技术大佬的相关视频
  • 驾驶技能
  • 住房相关
  • 厨艺
  • 关于税
  • 理财
  • 睡眠
  • 皮肤
  • 口腔健康
  • 学会呼吸
  • 健身日志
  • 电影

    • 电影推荐
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 反腐
  • GFW
  • 404 内容
  • 审查与自我审查
  • 互联网
  • 2022
  • 2023
  • 2024
  • 2025
  • 关于本站
  • 关于博主
  • 网站动态
  • 公告栏
  • 友人帐
  • 从零开始搭建一个博客
  • 搭建邮件服务器
  • 本站分享
  • 文章分类
  • 文章归档
  • 计算机历史

  • 数字电路

  • 计算机组成原理

  • 操作系统

    • 我的操作系统学习笔记

    • 我的操作系统实验笔记

      • 搭建实验环境
        • 前言
        • 工具介绍
        • Ubuntu 下实验环境搭建(推荐)
        • 调试操作系统
        • Windows 下实验环境搭建(待完善,不推荐)
        • Bochs 调试技巧
        • 文件交换
        • 参考
      • 操作系统的引导
      • 系统调用
    • 操作系统网课-王道考研

  • Linux

  • 计算机网络

  • Git

  • 计算机小知识

  • 数据库

  • 计算机基础
  • 操作系统
  • 我的操作系统实验笔记
2022-10-23
目录

搭建实验环境

# 0. 搭建实验环境

工欲善其事必先利其器

‍‍

‍

# 前言

在 B 站的评论区看到,老师的配套实验是在这里做的:操作系统原理与实践_Linux - 蓝桥云课 (opens new window)

这是一个网站,可以提供远程连接虚拟机给到用户操作。同时上面有很详细的实验手册。但有这样一个问题:如果想要保存自己的环境,是要收费的(完成学生认证后 5 折);且远程还是有一点不方便,因此我决定自己搭建一套环境。当然,在网站上做也是有好处的,可以在上面看到很多同学留下的笔记等,有问题也可以在上面提。

后来其实已经有实验手册了,发现自己白写了....:HIT-OSLAB-MANUAL (opens new window)

后续我会记录实验过程,供大家参考

‍

# 工具介绍

Bochs:发音同"Box",是一款开源,使用 C++ 编写的,高度便携的 IA-32(X86)架构 PC 模拟器。简单来说,就是可以运行操作系统,并且方便调试

GCC:编译器,这里用来编译操作系统。Linux 最初的版本就是由 GCC 编译的

GDB:调试器,GCC 编译器的兄弟。类似汇编里的 debug

‍

‍

# Ubuntu 下实验环境搭建(推荐)

‍

# 准备操作系统

由于我的电脑是 Windows,可以用 VMWare 或 VirtualBox 运行 Ubuntu。我这里用 Virtual Box,免费的。然后在 VirtualBox 下安装 Ubuntu,可以参考 VirtualBox 虚拟机安装 Ubuntu16_megfli 的博客 (opens new window) 。安装花费了 2~3 个小时

‍

‍

我自己遇到的问题如下:

  1. 安装时黑屏时间过长:参考自己解决虚拟机 Ubuntu 开机黑屏 (opens new window),我尝试重启后正常了
  2. 安装时 Ubuntu 显示屏幕过小:参考关于 VirtualBox 安装 Ubuntu 时界面显示不全,没有下一步选项 (opens new window)
  3. 安装完后,我们可以设置共享目录,方便 Windows 和虚拟机共享文件:新版本 virtualbox Ubuntu16.04 设置共享文件夹 (opens new window)

‍

‍

# 安装依赖

我们不必从头开始安装 Bochs,GCC 等,有很多热心的网友已经帮我们配置好了:在终端里运行以下命令即可

$ git clone https://github.com/Wangzhike/HIT-Linux-0.11.git
$ cd HIT-Linux-0.11/prepEnv/hit-oslab-qiuyu/
$ ./setup.sh
1
2
3

这样,就帮我们装好了很多依赖了,包括 Bochs,GCC 等

如果第一个下载不了,可以试试国内镜像地址:

git clone https://gitcode.net/mirrors/Wangzhike/HIT-Linux-0.11.git
1

‍

然后我们就可以运行 Linux0.11 了:

cd ~/oslab
./run
1
2

‍

​​

‍

‍

‍

命令还提供 init 脚本进行初始化:

./run init
1

注:这样会将 Image 也删除,所以要重新 cd linux 然后 make all

‍

‍

关于本项目,更多的可以参考作者的 Github 说明文档。

‍

‍

‍

# 编译内核

在实验过程中,我们需修改操作系统的代码,然后重新编译一个新的操作系统镜像,并让 Bochs 运行,编译步骤如下:

$ cd ./linux-0.11/
$ make all
1
2

‍

‍

‍

以下说明来自实验楼:

make 命令会显示很多很多的信息,你可以尽量去看懂,也可以装作没看见。只要最后几行中没有 “error” 就说明编译成功。

make 命令会自动跳过未被修改的文件,链接时直接使用上次编译生成的目标文件,从而节约编译时间。但如果重新编译后,你的修改貌似没有生效,可以试试先 make clean​ ,再 make all​(或者一行命令:make clean && make all​。make clean​ 是删除上一次编译生成的所有中间文件和目标文件,确保是在全新的状态下编译整个工程。

‍

‍

‍

‍

# 调试操作系统

我们编写操作系统代码的时候,难免会遇到问题,此时调试能帮助我们分析问题:

‍

汇编语言级别的调试:

$ cd ~/oslab/

# 运行脚本前确定已经关闭刚刚运行的 Bochs
$ ./dbg-asm
1
2
3
4

以下说明来自实验楼:

汇编级调试的启动之后 Bochs 是黑屏,这是正常的。

可以用命令 help​ 来查看调试系统用的基本命令。更详细的信息请查阅 Bochs 使用手册。

​​​

按 q 可以退出调试

‍

‍

C 语言级别的调试

先运行

$ cd ~/oslab
$ ./dbg-c
1
2

‍

再开一个终端,运行

$ cd ~/oslab
$ ./rungdb
1
2

‍

‍

以下说明来自实验楼

注意:启动的顺序不能交换,否则 gdb 无法连接。

出现下图所示的提示,才说明连接成功

​​

​

注意:可能要等一段时间后,才能连接成功。

‍

‍

‍

# Windows 下实验环境搭建(待完善,不推荐)

不推荐理由:有很多工具在 Windows 下不能运行,例如调试工具等,不太推荐。具体可以参考实验手册,也有详细的说明了。

如果你是用 Windows,那么如果如果运行虚拟机,虚拟机里再运行 Bochs 的话,对电脑的配置比较高的。如果内存不够,那么运行虚拟机后就容易卡顿,并且虚拟机内存不够的话也容易卡顿。(内存高的话就不用担心卡顿,比如我是 32G 台式机,给虚拟机分配 8G 内存后,总的 CPU 利用率也才 71%,使用过程中基本没有卡顿)

如果自己电脑配置不高的同学,也可以通过云服务器的方式搭建实验环境(网上有教程)。

‍

‍

安装 Bochs:默认一路 Next 即可。安装完后会有两个对话框提示是否打开更新日志和介绍,关闭即可。

​​

‍

接下来打开复制以下文件到 Bochs 的安装目录(安装过程中有指定安装目录的 ↑, 其实就是除了文件 Bochs-2.1.1.exe、README、rootimage-0.11,其他文件都复制过去)

bochsout.txt
bochsrc-fd.bxrc
bochsrc-hd.bxrc
bootimage-0.11
bootimage-0.11-fd
bootimage-0.11-hd
bootimage-0.12-fd
bootimage-0.12-hd
diskb.img
gcclib-1.40.taz
hdc-0.11.img
1
2
3
4
5
6
7
8
9
10
11

​

‍

接下来,直接双击 bochsrc-hd.bxrc,就可以看到如画面,操作系统就被运行起来了

​​

​

‍

# Bochs 调试技巧

‍

调试 Bochs 的脚本,环境里已经有了:.dbg-asm 的内容:

#!/bin/sh
export OSLAB_PATH=$(dirname `which $0`)
$OSLAB_PATH/bochs/bochs-dbg -q -f $OSLAB_PATH/bochs/bochsrc.bxrc
1
2
3

我们先启动:

peterjxl@Ubuntu16:~/oslab$ ./dbg-asm 
========================================================================
                       Bochs x86 Emulator 2.3.7
               Build from CVS snapshot, on June 3, 2008
========================================================================
00000000000i[     ] reading configuration from ./bochs/bochsrc.bxrc
00000000000i[     ] installing x module as the Bochs GUI
00000000000i[     ] using log file ./bochsout.txt
Next at t=0
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
<bochs:1> 
1
2
3
4
5
6
7
8
9
10
11

运行后,Bochs 会等待我们输入调试指令(在最后一行处光标会闪烁)

Table 1. 部分 Bochs 调试指令

行为 指令 举例
在某物理地址设置断点 b addr b 0x30400
显示当前所有断点信息 info break info break
继续执行,直到遇上断点 c c
单步执行 s s
单步执行(遇到函数则跳过) n n
查看寄存器信息 info cpurfpsregcreg info cpurfpsregcreg
查看堆栈 print-stack print-stack
查看内存物理地址内容 xp /nuf addr xp /40bx 0x9013e
查看线性地址内容 x /nuf addr x /40bx 0x13e
反汇编一段内存 u start end u 0x30400 0x3040D
反汇编执行的每一条指令 trace-on trace-on
每执行一条指令就打印 CPU 信息 trace-reg trace-reg on
退出 q q

其中 "xp /40bx 0x9013e" 这样的格式可能显得有点复杂,读者可以用 "help x" 这一指令在 Bochs 中亲自看一下它代表的意义 ‍

‍

‍

我们知道 bootsect.s 默认是加载到 0x7c00,我们可以将断点打到 0x7c00,然后输入 c 指令,直接运行到断点处:

<bochs:1> b 0x7c00
<bochs:2> c
(0) Breakpoint 1, 0x00007c00 in ?? ()
Next at t=4967696
(0) [0x00007c00] 0000:7c00 (unk. ctxt): mov ax, 0x07c0            ; b8c007
<bochs:3> 
1
2
3
4
5
6

‍

‍

可以看到 Bochs 提示我们,下一条指令就是 mov ax, 0x7c00,这就是 bootsect.s 的第一条执行的指令(注意,此时还没开始执行)

entry start
start:
	mov	ax,#BOOTSEG
	mov	ds,ax
1
2
3
4

‍

我们输入 n 指令,让 Bochs 单步执行,可以看到下一条要执行的指令就是 bootsect.s 的第二条执行(第一条已经执行了)

<bochs:1> b 0x7c00
<bochs:2> c
(0) Breakpoint 1, 0x00007c00 in ?? ()
Next at t=4967696
(0) [0x00007c00] 0000:7c00 (unk. ctxt): mov ax, 0x07c0            ; b8c007
<bochs:3> n
Next at t=4967697
(0) [0x00007c03] 0000:7c03 (unk. ctxt): mov ds, ax                ; 8ed8
<bochs:4> 
1
2
3
4
5
6
7
8
9

(注:如果我们有执行到 call 的话,可以用 s 指令进去方法里)

‍

‍

‍

如果我们什么都不输入,直接按回车,默认就是执行上一步的命令

<bochs:4> 
Next at t=4967698
(0) [0x00007c05] 0000:7c05 (unk. ctxt): mov ax, 0x9000            ; b80090
<bochs:5> 
Next at t=4967699
(0) [0x00007c08] 0000:7c08 (unk. ctxt): mov es, ax                ; 8ec0
<bochs:6> 
1
2
3
4
5
6
7

‍

‍

查看寄存器:用 r 指令

<bochs:6> r
eax: 0x00009000 36864
ecx: 0x00000000 0
edx: 0x00000000 0
ebx: 0x00000000 0
esp: 0x0000ffdc 65500
ebp: 0x00000000 0
esi: 0xffff0000 -65536
edi: 0x0008fdba 589242
eip: 0x00007c08
eflags 0x00000082
id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af pf cf
1
2
3
4
5
6
7
8
9
10
11
12

‍

但看段寄存器要用 sreg 命令

<bochs:7> sreg
cs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ds:s=0x07c0, dl=0x7c00ffff, dh=0x00009300, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
es:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008b00, valid=1
gdtr:base=0x000faeb2, limit=0x30
idtr:base=0x00000000, limit=0x3ff
1
2
3
4
5
6
7
8
9
10
11

‍

info break:查看打了多少个断点

<bochs:8> info break
Num Type           Disp Enb Address
  1 pbreakpoint    keep y   0x00007c00
1
2
3

‍

打印堆栈:print-stack

<bochs:9> print-stack
Stack address size 2
 | STACK 0xffdc [0x8a60001]
 | STACK 0xffde [0x8a60000]
 | STACK 0xffe0 [0x8a60000]
 | STACK 0xffe2 [0x8a60000]
 | STACK 0xffe4 [0x8a60000]
 | STACK 0xffe6 [0x8a60000]
 | STACK 0xffe8 [0x8a60000]
 | STACK 0xffea [0x8a60000]
 | STACK 0xffec [0x8a60000]
 | STACK 0xffee [0x8a67c00]
 | STACK 0xfff0 [0x8a60000]
 | STACK 0xfff2 [0x8a60040]
 | STACK 0xfff4 [0x8a60000]
 | STACK 0xfff6 [0x8a69fc0]
 | STACK 0xfff8 [0x8a6fff6]
 | STACK 0xfffa [0x8a6a3f9]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

‍

# 文件交换

我们在实验过程中,会遇到 ubuntu 和 Linux0.11 之间的文件交换。因为在 Linux0.11 里,只有 vi 这个工具,编写代码实在是太麻烦了。我们可以在 Ubuntu 里用其他编辑器或者 IDE 编写完后,传给 Linux0.11 上运行 ‍

‍

oslab 下的​ 是 0.11 内核启动后的根文件系统镜像文件,相当于在 bochs 虚拟机里装载的硬盘。在 Ubuntu 上访问其内容的方法是:

$ cd ~/oslab/

# 启动挂载脚本
$ sudo ./mount-hdc
1
2
3
4

之后,hdc 目录下就是和 0.11 内核一模一样的文件系统了,可以读写任何文件(可能有些文件要用 sudo 才能访问)。

‍

# 进入挂载到 Ubuntu 上的目录
$ cd ~/oslab/hdc

# 查看内容
$ ls -al
1
2
3
4
5

读写完毕,不要忘了卸载这个文件系统:

$ cd ~/oslab/

# 卸载
$ sudo umount hdc
1
2
3
4

经这样处理以后,我们可以在 Ubuntu 的 hdc 目录下创建一个 xxx.c 文件,然后利用 Ubuntu 上的编辑工具(如 gedit 等)实现对 xxx.c 文件的编辑工作,在编辑保存以后。

‍

注意 1:不要在 0.11 内核运行的时候 mount 镜像文件,否则可能会损坏文件系统。同理,也不要在已经 mount 的时候运行 0.11 内核。

注意 2:在关闭 Bochs 之前,需要先在 0.11 的命令行运行 “sync”,确保所有缓存数据都存盘后,再关闭 Bochs。

‍

‍

‍

# 参考

mirrors / Wangzhike / HIT-Linux-0.11 · GitCode (opens new window)

操作系统原理与实践 - 熟悉实验环境 - 蓝桥云课 (opens new window)

Windows 下用 Bochs 编译运行 Linux-0.11_Demon 的黑与白的博客-CSDN 博客 (opens new window)

介紹 | HIT-OSLAB-MANUAL (opens new window)

上次更新: 2024/9/29 20:20:01
用户级线程
操作系统的引导

← 用户级线程 操作系统的引导→

最近更新
01
2025 年 2 月记
02-28
02
最全面的浏览器教程-完结撒花
02-16
03
这个工具可以轻松搞到你的浏览器账户密码!
02-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式