HUST-OS课设
本文最后更新于:2022年2月10日 下午
HUST-操作系统课程设计
任务一
主要参考
《Orange’S:一个操作系统的实现》电子版,老师给的是旧版,内容差太多了,离谱。
环境配置:Ubuntu+NASM+Bochs+freedos
VMware安装Ubuntu虚拟机:
官网下载即可。
安装NASM:
1 |
|
Bochs环境安装与测试:
跟之前的实验差不多。
1.安装Bochs:
方法一:不推荐,安装的bochs没有功能选项的显示
1
sudo apt-get install vgabios bochs bochs-x bximage
方法二:官网下载压缩包,下载链接:Bochs x86 ,接下来的过程可能会出各种各样的问题,有些问题在下面的遇到问题中有描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//解压
tar xvf bochs-2.7.tar.gz
//进入解压目录
cd bochs-2.7
//执行,下面的命令需要gcc环境,若没有,则apt安装,建议用下面的详细版
./configure --enable-debugger --enable-disasm
//详细版的,出现的问题少一些
./configure --with-x11 --with-wx --enable-debugger --enable-disasm --enable-all-optimizations --enable-readline --enable-long-phy-address --enable-ltdl-install --enable-idle-hack --enable-plugins --enable-a20-pin --enable-x86-64 --enable-smp --enable-cpu-level=6 --enable-large-ramfile --enable-repeat-speedups --enable-fast-function-calls --enable-handlers-chaining --enable-trace-linking --enable-configurable-msrs --enable-show-ips --enable-debugger-gui --enable-iodebug --enable-logging --enable-assert-checks --enable-fpu --enable-vmx=2 --enable-svm --enable-3dnow --enable-alignment-check --enable-monitor-mwait --enable-avx --enable-evex --enable-x86-debugger --enable-pci --enable-usb --enable-voodoo
//缺少什么包就去安装
make
sudo make install
//执行,检测是否安装成功
bochs
2.创建boot.asm
1 |
|
- 3.使用nasm编译asm文件
1 |
|
4.执行命令
bximage
,生成一个虚拟软盘5.将bin文件写入img中
1 |
|
- 6.编写bochs的配置文件
bochsrc
,文件内容如下:
1 |
|
7.执行
bochs -f bochsrc
,将弹出黑色窗口,之后输入6
,选择功能6,再输入c
,此时执行引导程序,结果如下:
Bochs中配置freedos:
freedos主要用于提供保护模式下的程序的运行环境,用于运行COM文件。参考链接:Fan Lu’s Blog (fanlumaster.github.io)
1.下载freedos压缩包,直接执行命令
wget http://bochs.sourceforge.net/guestos/freedos-img.tar.gz
,下载完成后解压即可。2.进入解压的freedos目录,可以看到存在几个img文件,将其中的
a.img
改名为freedos.img
,并复制到你的工作目录下(就是你写asm的目录)3.使用
bximage
新建一个软盘,名字叫pm.img
4.编写bochsrc配置文件,文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22megs:128
#模拟器的内存
#下面这两个路径需要自己去看一下对应路径下是否真的有这两个文件,防止路径出错
romimage:file=/usr/os/bochs-2.7/bios/BIOS-bochs-latest
#这个是BIOS-bochs-latest的路径,可能不一样
vgaromimage:file=/usr/os/bochs-2.7/bios/VGABIOS-lgpl-latest
#注意,这是a
floppya:1_44=freedos.img,status=inserted
#注意,这是b。。有人会愚蠢的分不清。。
floppyb:1_44=pm.img,status=inserted
#这个是启动软盘,在当前目录下,如果不在当前目录,需要指明路径
boot:a
#表示从软盘启动
log:bochsout.txt
#日志输出文件
mouse: enabled=0
#disable the mouse5.启动bochs,命令还是
bochs -f bochsrc
,依然是选择功能6,弹出黑色窗口,然后输入c,这时候我们可以发现,他运行了freedos.img
的引导程序,黑色窗口中进入了A:\>
的命令行,注意此时,我们的pm.img
是空的,没有向其中写入程序,接着在A:\>
的命令行中执行命令format.exe b:
,来格式化B盘。
6.接下来尝试在pm.img中写入程序,并且该程序可从实模式转到保护模式,在保护模式下,打印一个字符,
pmtest1.asm
代码如下(参考书源代码),具体代码实现含义在书中有解释,可仔细阅读,pm.inc
为直接复制光盘中的源代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92; ==========================================
; pmtest1.asm
; 编译方法:nasm pmtest1.asm -o pmtest1.com
; ==========================================
%include "pm.inc" ; 常量, 宏, 以及一些说明
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段, 32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
; 初始化 32 位代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah
; 为加载 GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
; 加载 GDTR
lgdt [GdtPtr]
; 关中断
cli
; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al
; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax
; 真正进入保护模式
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处
; END of [SECTION .s16]
[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)
mov edi, (80 * 10 + 0) * 2 ; 屏幕第 10 行, 第 0 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'z'
mov [gs:edi], ax
; 到此停止
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]7.使用命令
nasm pmtest1.asm -o pmtest1.com
,将asm文件编译成com程序。8.将
pmtest1.com
文件复制到pm.img上,若是首次复制,则需先创建一个目录:1
sudo mkdir /mnt/floppy
随后执行以下命令:
1
2
3sudo mount -o loop pm.img /mnt/floppy
sudo cp pmtest1.com /mnt/floppy/
sudo umount /mnt/floppy再次启动bochs,并进入到freedos中,在
A:\>
命令行中执行B:\pmtest1.com
,此时pmtest1.com
,程序便运行起来了,完成了GDT表的初始化,实模式转换到保护模式,在保护模式下输出字符z
,执行结果如下:
至此,基本环境算是打起来了,中间遇到了太多的问题,花了一整天的时间😭😭
遇到的问题
参考:bochs配置安装 ,只记录了这几个,中间问题太多不想写了。
Message: dlopen failed for module ‘x’: file not found
原因:没有安装bochs-x
解决方法:apt-get install bochs-x
./configure --enable-debugger --enable-disasm
执行出错
原因:缺少相应的包
解决方法:sudo apt-get install build-essential
make出错
解决方法:下面三句几乎将所有需要的都安装了
1 |
|
- make install出错
解决方法:vim .bochsrc
,删除第955行
GDT
在IA32下,CPU有两种工作模式,实模式和保护模式,当启动计算后,刚开始是实模式,随后经过某种机制,进入到保护模式。
Intel8086是16位的CPU,有16位的寄存器,16位的数据总线以及20位的地址总线,所以有1MB的寻址能力,在寻址时,分别用两个16位寄存器保存段基址和段偏移,物理地址=段基址*16+段偏移
,以此来达到1MB的寻址空间。
从80386开始,Intel的CPU的地址线变为32位,寻址空间变为4GB,但是依然使用的是16位寄存器,显然使用段基址加段偏移的方法,是无法达到4GB的寻址空间的。此时我们改变了段的含义,在保护模式下,段基地址依然使用16位寄存器来保存,只不过这里的段基地址并不对应具体段在内存中的基地址,而是作为一个索引,指向了某个数据结构中的一个表项(数据项),这个表项的内容详细定义了这个端的起始地址,界限,属性等内容,这个数据结构就叫做GDT(Global Descriptor Table
,全局描述表,其实就是我们所说的段表),GDT中的每一个表项叫做一个Descriptor(描述符),存储量某个段的信息,一个描述符就对应一个段,可以使数据段,代码段等等。
所以,GDT的作用就是用来提供段式存储机制,这种机制是通过段寄存器(他存储的地址指向段表中某个段的描述符)和GDT中的描述符共同提供的。
每个描述的内部结构:
比如看下面的代码就是GDT的内容,里面有3个描述符,表示3个段(第一个描述符是空描述符,实际只存储了两个段,CODE段和VIDEO段,每个描述符里记录了这个段的段基址,段界限和属性)
1 |
|
现在我们知道了,每个段的基地址等信息保存在GDT表中,那么我们怎么知道我们当前段的描述符在GDT表中的位置呢,这时候,就用到了一个叫做选择子数据结构,来告诉我们段描述符在GDT表中的位置,如下:
1 |
|
这两个变量就分别保存了code段和video段在GDT表中的偏移,根据这两个选择子,就可以找到段在GDT中的描述符。(具体到底怎么用,我很懵逼)。
总之,我们得到逻辑地址后,首先将段地址作为索引,找到该段在GDT表中的描述符,然后得知该段在内存中的真实的段基地址,然后再根据偏移地址,就可以找到物理地址了。
chapter3/b/pmtest2.asm尝试
代码复制粘贴就行了😆😆😆
bochsrc中的路径需要改成自己的,Makefile中遇到了问题:
解决方法:参考sudo mount -o loop pm.img /mnt/floppy/mount 错误解决办法
之后make
,然后进入bochs和freedos,运行B:\pm.img
,成功~:
本文作者: ziyikee
本文链接: https://ziyikee.fun/2022/01/28/HUST-OS%E8%AF%BE%E8%AE%BE/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!