课堂练习3.2:进程的创建

本文介绍了Linux0.11中的进程创建过程,涉及fork和execve系统调用,以及对进程控制块、全局描述符表(GDT)和任务状态段(TSS)的分析。通过实际操作演示了如何在内核中实现特定功能,如显示父子进程信息和执行文件名等。
该文章已生成可运行项目,

955e7e84268f4e148b2fe0e8b23c82bf.png

3-3

进程是操作系统中一个非常重要的概念。程序的运行是通过进程来完成的。在层次结构的操作系统中,进程不仅是系统分配资源的基本单位,而且是 CPU 调度的基本单位。进程管理是操作系统最重要的功能之一。通过本实训将会学习到:Linux 0.11 的进程的创建方法。

b7b5460e9ce74cfcbf67047d4e659830.png

 

第1关进程创建前后TR寄存器值的分析

任务描述

本关任务回答问题:

  1. 0 号进程的 fork 系统调用(main.c:147)中的陷入指令的地址是多少?
  2. 0 号进程执行 fork 系统调用之前,TR 寄存器的值为多少?
  3. 0 号进程刚执行完 fork 系统调用时,TR 寄存器的值为多少?

相关知识

为了完成本关任务,你需要掌握: 1.系统调用的处理过程; 2.TR 寄存器的作用; 3.在 0 号进程执行 fork 系统调用时,所用陷入指令的地址是多少; 4.0 号进程刚执行完 fork 系统调用是在什么时候; 5.在 bochsdbg 调试模式下,如何判断当前进程是几号进程; 6.在 bochsdbg 中如何查看寄存器的值; 7.在 bochsdbg 中如何反汇编; 8.在 bochsdbg 中如何单步执行。

准备阶段

本实训需要设置内核版本 1 为调试分析的对象,用 gdb 调试内核,内核版本 1 的压缩文件存放在/data/workspace/myshixun/exp1中。

实验过程及答案

实验过程

ls /data/workspace/myshixun/exp1
cp /data/workspace/myshixun/exp1/1.tgz ~/os

94131b9c442641aca067c450afc62e04.png

cd os/linux-0.11-lab
tar -zxvf ../1.tgz 1

de0ebd3263cc4230a9de53bf430dcc0c.png

rm -rf cur
ln -s 1 cur
ls

f12d91d64d9c4b5db1cbd88daf504c59.png

cd 1/linux
make

ee35757477f1428b93032742a723085e.png

cd ../..
./rungdb

23f0bde27ee344dd940cda4d4cb7acf8.png

另开一个终端

cd os/linux-0.11-lab
./mygdb

164f5c0adaf1445daea419b6f8c24e68.png

50554739327a474c94b74bc89d7f41a0.png51a3d58da61647fe9ab6fac3a7b7cb45.png72e761b8fafe4d6db47d04b90f31030c.png893a34ba0a8f4384b90fce530d15dcf6.pngc9f180f512ea4202809c9520b487f0b5.pngb4802cbd51ad4975b140cf2b56ce2631.pngbdfc61e7acf8490a9574bcdecd586b6b.png4999c09780d24269a0aaa62c0d3c2b1d.png

答案

b2f249373c5640638872ad9500b4e5df.png

 

第2关1 号进程创建前后的GDT和PCB分析

任务描述

本关任务回答问题:

  1. 0 号进程的进程控制块的起始地址是多少?0 号进程的 TSS 的地址是多少?
  2. 在 1 号进程创建前,task 数组的前 2 项是多少?GDT 的 4~7 号描述符是多少?其中存储的段起始地址分别是多少?
  3. 在 1 号进程创建后,task 数组的前 2 项是多少?GDT 的 4~7 号描述符是(64位)多少?其中存储的段起始地址分别是多少?
  4. 1 号进程的进程控制块的起始地址是多少?1 号进程的 TSS 的地址是多少?1 号进程执行的第一条语句的地址是多少?
  5. 1 号进程的核心栈栈底的位置是多少?该位置距离 1 号进程的进程控制块的起始位置有多远(字节数)?

相关知识

为了完成本关任务,你需要掌握: 1.系统调用的处理过程; 2.TR 寄存器的作用; 3.如何查看任何一个现有进程的进程控制块; 4. 1 号进程所执行的第一条语句的地址; 5. 0 号进程执行 fork 系统调用时的陷入指令地址; 6.如何单步执行一条指令直到其运行结束(step over); 7.进程的核心栈与进程控制块之间的位置关系。

准备阶段

本实训需要设置内核版本 1 为调试分析的对象,用 gdb 调试内核,内核版本 1 的压缩文件存放在/data/workspace/myshixun/exp1中。

实验过程及答案 

实验过程

因为是和第一个是同时做的,所以不需要重新配置环境,如果重启释放环境,配置环境过程见下

ls /data/workspace/myshixun/exp1
cp /data/workspace/myshixun/exp1/1.tgz ~/os

94131b9c442641aca067c450afc62e04.png

cd os/linux-0.11-lab
tar -zxvf ../1.tgz 1

de0ebd3263cc4230a9de53bf430dcc0c.png

rm -rf cur
ln -s 1 cur
ls

f12d91d64d9c4b5db1cbd88daf504c59.png

cd 1/linux
make

ee35757477f1428b93032742a723085e.png

cd ../..
./rungdb

23f0bde27ee344dd940cda4d4cb7acf8.png

另开一个终端

cd os/linux-0.11-lab
./mygdb

164f5c0adaf1445daea419b6f8c24e68.png

0a0de6ef66e446ebb2e8a1777b7d9e9e.png86bd723c3e424b6a862e5e5a5ad4c3aa.png1e65623181d54200bbe4afdb1daa207c.png4d31630afa094baa827b732235c661f3.pnga7c6bc826ec94b78bdf66ccb802dfecb.pngafb97d2fa36a4b148b6cb8700e5d5b85.png

答案

ffe6b5a7e86e4441a257322373088379.png

3-4

本实训分析 Linux 0.11 的进程创建过程,并练习相关系统调用的使用方法。

b4abd6bf29b54a11a67fe3d39d5c2d93.png

 

第1关系统调用fork和execve的跟踪分析

任务描述

本关任务:修改版本 0 内核,使每次进程创建时都输出父子进程的进程号,使每次执行可执行文件时,都输出可执行文件的名字和当前进程号。

相关知识

为了完成本关任务,你需要掌握: 1.系统调用的处理过程; 2.如何使每次进程创建时都输出父子进程的进程号; 3.如何使每次执行可执行文件时都输出可执行文件的名字和当前进程号。

准备阶段

本实训需要设置内核版本 0 为调试分析的对象,修改完毕之后请确认cur指向链接是否正确,系统能否正常使用。

实验过程及答案

实验过程

打开桌面上的vscode3cd71b96ed97476d802a459829a35677.pngb20a3c6c7f3141ab8a95b44767f620c3.png8abe44f186c842b1b8907e2ba2f30dec.png7320fcfc3504428d87c9dd2369b1d0d3.png60901ca2ad8d49e69119c0b23d197c50.pngdc0627e695d045559a225dbfb0998557.png添加如下代码cbd48ab1f22f4e2fbac23567bb449069.png7406cf805080401c811c32321633e878.png5d796cfb42f64b4ea729d0f07ce51c22.png添加如下代码83af695d3f8f4dd3ac5b55f0d8007c02.png
cd os/linux-0.11-lab/0/linux
70acdbef6c774570bb40f85baccc0f5e.png

 

cd ../..
./run
39d4a5c8115c412987030e00b0711b2c.png

 

 

 

第2关构建一个最小的可用操作系统

任务描述

本关任务:修改版本 0 内核和硬盘达到以下目标。

  1. 硬盘中的文件越少越好,且所有的文件都在根目录下;
  2. 用该内核和硬盘能够正常启动系统,没有错误提示,且依然能够运行ls、cat、rm 和 sync 命令。
  3. 系统启动后,自动执行命令setls -l /

相关知识

为了完成本关任务,你需要掌握: 1.如何修改硬盘镜像文件中的内容; 2.在修改了硬盘后,启动时报错怎么办; 3.系统启动时会执行哪些可执行文件。

实验过程及答案

实验过程

先把第一关改过的部分删掉,可能会影响评测

db8f7843107341c28e69ffd5deb67c03.png41d69cc0618b4274a959b03223e2c2bb.png3028e7d7b94148d39bfe3a3af904f7a3.png712c121778504bfc8029651722b9e9da.png017ef07c469d4eaf9df996e578c45b00.png2335247dfed447b4aacc0fa6e95110bb.png933e53de0f9f463ba56cfc5d2ae5bdd0.png

打开vscode

b8ac559276bf431692eacb03cad1b9cd.png77988d02688b460fb482269ef2a6aee9.pngbddea87bb1dc49d0b67630831838b929.png改成和我一样

0f2dcc0697c3412892282141b5f6f493.png6f97f9ff4dc94db6a75ca1dbe4f855e2.png15508a8594ec49a69cde79b508723c48.pnge2b10671300e475b8f7c101dd67e66ac.png

50cd837c52f4471a99cb50e705b640d3.png2754fb2f69b64b86840d58302246e4df.pngc30bd9796d764136b302dd4ef592dc01.png

评测即可成功

 

本文章已经生成可运行项目
Linux系统中,进程创建主要涉及到`fork`和`execve`这两个关键的系统调用。下面对它们在进程创建时的跟踪分析进行详细阐述。 ### `fork`系统调用 `fork`系统调用用于创建一个新的进程,这个新进程是调用进程(父进程)的一个副本。新进程(子进程)会获得父进程的数据段、堆、栈等的副本,但它们是相互独立的。 #### 跟踪分析 可以使用`strace`工具来跟踪`fork`系统调用。`strace`可以监控进程的系统调用和信号。以下是一个简单的示例: ```bash strace -e fork ./your_program ``` 这个命令会跟踪`./your_program`程序执行过程中所有的`fork`系统调用,并将调用的详细信息输出到终端。输出信息通常包括系统调用的名称、参数和返回值。例如: ```plaintext fork() = 1234 ``` 这里`1234`是新创建进程进程ID(PID)。 ### `execve`系统调用 `execve`系统调用用于在当前进程的上下文中执行一个新的程序。它会用新程序的代码段、数据段、堆和栈替换当前进程的相应部分。 #### 跟踪分析 同样可以使用`strace`工具来跟踪`execve`系统调用: ```bash strace -e execve ./your_program ``` 这个命令会跟踪`./your_program`程序执行过程中所有的`execve`系统调用。输出信息会显示`execve`的参数,包括要执行的程序路径、传递给程序的参数和环境变量。例如: ```plaintext execve("/bin/ls", ["ls", "-l"], [/* 20 vars */]) = 0 ``` 这里表示执行`/bin/ls`程序,传递的参数是`-l`,并且有20个环境变量。 ### 综合分析 在进程创建过程中,通常先调用`fork`创建一个子进程,然后子进程调用`execve`来执行新的程序。可以使用`strace`同时跟踪这两个系统调用: ```bash strace -e fork,execve ./your_program ``` 这样可以观察到进程创建和程序执行的完整过程。例如,输出可能如下: ```plaintext fork() = 1234 [pid 1234] execve("/bin/ls", ["ls", "-l"], [/* 20 vars */]) = 0 ``` 这表明父进程调用`fork`创建了子进程(PID为1234),然后子进程调用`execve`执行了`/bin/ls`程序。 ### 代码示例 以下是一个简单的C语言程序,演示了`fork`和`execve`的使用: ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("fork"); return 1; } else if (pid == 0) { // 子进程 char *args[] = {"ls", "-l", NULL}; char *envp[] = {NULL}; execve("/bin/ls", args, envp); perror("execve"); return 1; } else { // 父进程 wait(NULL); printf("Child process finished.\n"); } return 0; } ``` 编译并运行这个程序,同时使用`strace`进行跟踪: ```bash gcc -o test test.c strace -e fork,execve ./test ```
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ItsNorth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值