2021-2022-1 20212804《Linux内核原理与分析》第七周作业
一.实验
1.在MenuOS中增加命令fork
cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c
make rootfs
2.跟踪分析进程创建过程
cd ~/LinuxKernel
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
cd ~/LinuxKernel
gdb
file linux-3.18.6/vmlinux
target remote:1234
3.设置断点
b sys_clone
b do_fork
b dup_task_struct
b copy_process
b copy_thread
b ret_from_fork
二、实验分析
创建进程的大致流程
1.fork函数通过ox80中断(系统调用)来陷入内核,然后进入系统提供的相应系统调用来完成进程的创建过程。
2.fork、vfork、和clone三个系统调用都可以创建一个新的进程,而且都是通过do_fork来实现进程的创建。
3.在do_fork中首先调用copy_process为子进程复制一份进程信息。
4.调用dup_task_struct复制当前的task_struct。
5.检查进程数是否超过限制。
6.初始化自旋锁、挂起信号、CPU定时器等。
7.调用sched_fork初始化进程数据结构,并把进程状态设置为TASK_RUNNING.
8.复制所以进程信息,包括文件系统、信号处理函数、信号、内存管理等。
9.调用copy_thread初始化进程内核栈。
10.为新进程分配并设置新的pid
三.问题
运行sudo make bzImage出错
collect2: error: ld returned 1 exit status
scripts/Makefile.host:91: recipe for target ‘scripts/sign-file’ failed
make[1]: *** [scripts/sign-file] Error 1
Makefile:545: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
四.总结
可以通过fork、vfork和clone来创建一个新进程,而他们又都是通过调用do_ fork方法来实现的。do_ fork函数主要是调用copy_ process函数来为子进程复制父进程信息的。copy_ process函数调用 dup_task_struct为子进程分配新的堆栈;调用sched_ fork 初始化进程数据结构,并把进程状态设置为TASK_ RUNNING。copy_ process函数尤为重要,我们可以看到为什么fork()函数返回值为0,并且fork出的子进程是从哪里开始执行的:将子进程的ip设置为ret_ from_ fork的首地址,子进程从ret_ from_ fork开始执行。