操作系统LAB0

操作系统lab0


作者:王赛宇


操作系统

我这里用的是Ubuntu 20.04 LTS,这个不强求吧,从16.0420.04应该都没问题。这边是双系统,因为早就装好了,所以就不装虚拟机了。

C语言

sudo apt-get install gcc

这个不多谈了,直接给个文件吧

test.c

#define GLOBAL_NUM 10
#include<stdio.h>
int glo_var;
void funcA(){
    printf("funA:");
    int a[GLOBAL_NUM];
    for(int i=0;i<GLOBAL_NUM;i++)
        a[i] = i;
}
int main(){
    funcA();
    return 0;
}

Makefile

sudo apt-get install makefile

Makefile其实非常像是一个脚本文件,你可以在makefile文件中书写一些脚本,然后再使用make命令去执行他们,比如下面的makefile。

test: test.o
	gcc -g -o test test.o
test.o: test.c
	gcc -g -c -o test.o test.c

clean: 
	rm -rf ./test.o ./test

可以说这个makefile已经包含了一些必要的makefile知识了(其实简单使用makefile不需要啥知识。。),首先我们可以在控制台中输入make来执行该脚本。输入make时,会执行第一条指令,也就是test: test.o,这句话的意思是,要执行test,执行test需要依赖于test.o,于是就会先执行test.o对应的部分,于是执行了:gcc -g -c -o test.o test.c,生成了test.o,生成test.o后满足了test的条件,于是执行:gcc -g -o test test.o ,生成了test,也就是可执行文件。

如果想要重新生成,就可以使用make clean语句,make clean实质上是调用了自己已经在Makefile中定义好的脚本:rm -rf ./test。同理,我们也可以使用make test.o来单独生成test.o文件。

执行效果:

# wangsy @ wangsaiyu in ~/Study/HomeWork/os/LAB1_release_v1.0/docs [10:47:55] 
$ make
gcc -g -c -o test.o test.c
gcc -g -o test test.o
# wangsy @ wangsaiyu in ~/Study/HomeWork/os/LAB1_release_v1.0/docs [10:47:58] 
$ ls
Makefile  README.md  test  test.c  test.o

可以看到,执行make后,脚本为我们执行了两条语句

gcc -g -c -o test.o test.c
gcc -g -o test test.o

使用查看当前文件夹命令ls,看到编译的test.o以及test可执行文件已经生成完毕。

再使用:

# wangsy @ wangsaiyu in ~/Study/HomeWork/os/LAB1_release_v1.0/docs [10:47:59] 
$ make clean
rm -rf ./test.o ./test

# wangsy @ wangsaiyu in ~/Study/HomeWork/os/LAB1_release_v1.0/docs [10:50:06] 
$ ls
Makefile  README.md  test.c

clean时,执行我们预定义好的脚本进行删除,使用ls语句检查,发现已经删除完毕。

gdb

sudo apt-get install gdb

gdb是一款调试工具,我们就不多bb,直接看怎么用吧,我们刚才生成了一个叫做test的可执行文件,我们使用gdb test来制定对test进行调试,打开时界面如下:

# wangsy @ wangsaiyu in ~/Study/HomeWork/os/LAB1_release_v1.0/docs [10:51:46] 
$ gdb test
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...
(gdb) 
(gdb) 

list指令查看代码

我们首先使用list指令来查看我们调试的代码:

(gdb) list
1	#define GLOBAL_NUM 10
2	#include<stdio.h>
3	int glo_var;
4	void funcA(){
5	    printf("funA:");
6	    int a[GLOBAL_NUM];
7	    for(int i=0;i<GLOBAL_NUM;i++)
8	        a[i] = i;
9	}
10	int main(){
(gdb) 

这里一次只会显示十行,如果你还想继续看那就继续list。

break指令设置断点

如果不设置断点,那么程序就会直接跑完,那我们就无法调试了,所以调试之前是需要设置断点的。我们可以使用break指令来设置断点,在这个程序中,我们想看一下a[i] = i的这一句话反复发生时,i, a[i]的变化,所以我们将断点打在第8行,为此,输入下面的语句:

(gdb) break 8
Breakpoint 1 at 0x119e: file test.c, line 8.

同时,我们也可以根据函数名设置断点,比如我们想在进入mian()函数时停留,那就输入:

(gdb) break main
Breakpoint 2 at 0x11cb: file test.c, line 10.

当然,还有很多其他打断点的方法,大家可以自行了解,这里讲太多反而不好理解。

info查看一些信息

这里我们只查看设置过的断点,我们使用info break方法,来看一下我们设置了哪些断点:

(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000000119e in funcA at test.c:8
2       breakpoint     keep y   0x00000000000011cb in main at test.c:10

那么这里也非常明显了,我们在第8行设置过一个断点,在第10行的main函数处也设置过断点。

delete删除断点

我们仔细一想,进了main()函数后就直接进funcA了,那在main函数处设置断点好像也没啥用,那就把这个断点删了吧,就用下面的语句:

(gdb) delete 2
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000000119e in funcA at test.c:8

这里删除的时候,我们使用断电的编号作为索引进行删除。

run 运行程序

断点终于打好了,接下来我们想看看这些变量在程序跑起来的时候究竟是怎么变的,于是我们使用run指令:

(gdb) run
Starting program: /home/wangsy/Study/HomeWork/os/LAB1_release_v1.0/docs/test 

Breakpoint 1, funcA () at test.c:8
8	        a[i] = i;

程序会在遇到断点时停下,停下后,我们就可以进行一些操作了

print 查看变量

这里第一次执行到a[i] = i,这个时候我们想看一下这时候的i和a[i]分别是多少。

(gdb) print i
$1 = 0
(gdb) print a[i]
$2 = -9306

我们发现,这时候已经进入了循环,所以i已经被初始化为0,但是程序遇到断点时,a[i] = i的语句还没有执行,所以a[i]a[0]现在仍然是一个任意值。这警醒我们定义局部变量记得初始化。。。

continue继续执行

我们刚才看了一下第一次执行a[i] = i的时候a[i],i分别是什么值,接下来想看一下a[i],i在第二次是多少,这个时候我们就需要让程序继续执行:

(gdb) continue
Continuing.

Breakpoint 1, funcA () at test.c:8
8	        a[i] = i;
(gdb) print i
$3 = 1
(gdb) print a[i]
$4 = 32767
(gdb) print a[0]
$5 = 0

可以看到,这里我们使用continue指令让程序继续执行,程序再次执行到断点时停住了,这时候调用print方法,查看i = 1, a[i] = a[1] = 32767, a[0] = 0,这说明,第一次查看的那个语句赋值已经完成了,而且经过一轮循环后,i增加了1,但是当前的语句还是没有执行的,所以看到的a[i]还是一个随机数。

quit 拜拜了

可以看到这里要循环10次,但是我们看了两次就已经悟出了道理了,所以剩下八次就没必要一直看了,这里使用quit方法就可以退出gdb了:

(gdb) quit
A debugging session is active.

	Inferior 1 [process 4957] will be killed.

Quit anyway? (y or n) y

当然,这里的程序还在执行,gdb询问我们,如果现在退出,会杀死正在进行的进程,我们是否同意,我们当然同意,输入y,然后按回车就可以了。

qemu

sudo apt-get install qemu-system qemu

安装完成后输入qemu,然后再按TAB键自动补全,即可出现:

# wangsy @ wangsaiyu in ~ [11:18:00] C:127
$ qemu-nbd
qemu-img                  qemu-system-microblaze    qemu-system-riscv64     
qemu-io                   qemu-system-microblazeel  qemu-system-s390x       
qemu-make-debian-root     qemu-system-mips          qemu-system-sh4         
qemu-nbd                  qemu-system-mips64        qemu-system-sh4eb       
qemu-pr-helper            qemu-system-mips64el      qemu-system-sparc       
qemu-system-aarch64       qemu-system-mipsel        qemu-system-sparc64     
qemu-system-alpha         qemu-system-moxie         qemu-system-tricore     
qemu-system-arm           qemu-system-nios2         qemu-system-unicore32   
qemu-system-cris          qemu-system-or1k          qemu-system-x86_64      
qemu-system-hppa          qemu-system-ppc           qemu-system-xtensa      
qemu-system-i386          qemu-system-ppc64         qemu-system-xtensaeb    
qemu-system-lm32          qemu-system-ppc64le                               
qemu-system-m68k          qemu-system-riscv32                               

我们要模拟的架构应该是qemu-system-x86_64吧,那就进入到学长给的LAB0_TEST中,输入:qemu-system-x86_64 -hda ucore.img -parallel stdio

就可以打开虚拟机了。

其他部分我们就不讲了,那些看指导书就ok。

其他想说的

下个git学着用用吧,很好用的

sudo apt-get install git

这个最好配合着GitHub或者Gitee或者Coding之类的平台来用。非常适合一个小组以合作的形式来进行推进。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 I 基础知识9 1 MINIX操作系统简介11 1.1 MINIX与UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2 探索MINIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.3 编辑器:vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.4 编译器:CC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.5 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2 Intel 8086体系结构19 2.1 8086 CPU结构. . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.2 运算器与指令部件. . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 寄存器组. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.4 主存. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.5 堆栈. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.6 系统启动. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.7 二进制文件结构. . . . . . . . . . . . . . . . . . . . . . . . . . 25 3 ACK 8086汇编语言27 3.1 寻址. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.2 数据移动指令. . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.3 常量、标号、数据与全局变量. . . . . . . . . . . . . . . . . . 29 3.4 运算指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5 标志位操纵指令. . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.6 串操作指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.7 跳转、分支与循环. . . . . . . . . . . . . . . . . . . . . . . . 33 3.8 堆栈与子程序. . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5 6 目录 4 实习:Hello World 37 4.1 Hello World程序. . . . . . . . . . . . . . . . . . . . . . . . . 37 4.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 II 汇编语言进阶41 5 C与汇编联合开发43 5.1 函数调用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 5.2 全局与局部变量. . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.3 编译与连接. . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 6 中断与I/O 49 6.1 中断. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2 输入输出设备. . . . . . . . . . . . . . . . . . . . . . . . . . . 51 6.3 编写中断处理程序. . . . . . . . . . . . . . . . . . . . . . . . 51 6.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 7 实习:小游戏55 7.1 make工具. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 III 操作系统内核59 8 进程切换61 8.1 进程模型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 8.2 进程的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 8.3 进程切换. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 8.4 中断嵌套. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 8.5 MiniOS中的进程切换. . . . . . . . . . . . . . . . . . . . . . . 68 8.6 操作系统实现原则. . . . . . . . . . . . . . . . . . . . . . . . 69 9 进程通信71 9.1 信号量. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 9.2 消息机制. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.3 消息机制的实现. . . . . . . . . . . . . . . . . . . . . . . . . . 76 9.4 调试消息内核. . . . . . . . . . . . . . . . . . . . . . . . . . . 78 目录7 10 实习:操作系统内核83 10.1 引导操作系统. . . . . . . . . . . . . . . . . . . . . . . . . . . 83 10.2 微内核与层次式操作系统结构. . . . . . . . . . . . . . . . . . 83 10.3 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 IV 轻量操作系统实现87 11 设备驱动程序89 11.1 设备驱动程序原理. . . . . . . . . . . . . . . . . . . . . . . . 89 11.2 键盘设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 11.3 屏幕设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 11.4 死锁的产生与预防. . . . . . . . . . . . . . . . . . . . . . . . 93 12 存储管理95 12.1 存储管理与系统调用服务进程. . . . . . . . . . . . . . . . . . 95 12.2 进程映像的创建与终止. . . . . . . . . . . . . . . . . . . . . . 97 12.3 替换进程映像. . . . . . . . . . . . . . . . . . . . . . . . . . . 98 13 文件系统101 13.1 文件与目录. . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 13.2 文件与目录管理. . . . . . . . . . . . . . . . . . . . . . . . . . 103 13.3 文件描述符. . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 14 实习:迷你操作系统109 14.1 一个简易的Shell . . . . . . . . . . . . . . . . . . . . . . . . . . 109 14.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 附录111 A vi常用命令113 B 虚拟机与外部的文件交换117

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值