2021

您所在的位置:网站首页 zzx连接器 2021

2021

2024-01-24 16:40| 来源: 网络整理| 查看: 265

分析 Linux 内核创建一个新进程的过程 一、阅读理解 task_struct 数据结构1、进程描述符2、进程状态 二、使用 gdb 跟踪分析一个 fork 系统调用内核处理函数 sys_clone1、MenuOS中添加fork并测试2、跟踪调试 三、分析 fork 函数对应的系统调用处理过程四、Linux内核编译过程中遇到的问题1、添加自定义系统调用2、make bzImage出错3、开机时不能进入4、总结

一、阅读理解 task_struct 数据结构 1、进程描述符

task_struct具有非常庞大的数据结构,400多行代码。包括对进程链表的管理,控制台,文件系统描述,文件描述符,内存管理描述,信号描述等,其结构示意图如下图所示: 在这里插入图片描述

2、进程状态

当使用fork()创建一个新的进程时,进程的状态是TASK_RUNNING(就绪态),新进程被调度运行时,就切换到TASK_RUNNING(运行态)。对于一个正在运行的进程,调用用户库函数exit()会陷入内核执行该内核函数do_exit(),也就是终止进程,就会进入TASK_ZOMBIE状态(僵尸进程)。一个正在运行的进程在等待特定的事件和资源时会进入阻塞态。阻塞态也分两种:TASK_INTERRUPTIBLE和TASK_UNINTERRUPTLBLE。TASK_INTERRUPTIBLE可以被信号和wake_up唤醒的,当信号到来时,进程会被设置为TASK_RUNNING(就绪态),而TASK_UNINTERRUPTLBLE只能被wake-up()唤醒。进程状态转化图如下图所示: 在这里插入图片描述

二、使用 gdb 跟踪分析一个 fork 系统调用内核处理函数 sys_clone 1、MenuOS中添加fork并测试

如下图所示,以下为MenuOS运行fork的效果,可以看到父进程和子进程都有信息输出: 在这里插入图片描述

2、跟踪调试

按照之前的方法对内核进行调试,分别在sys_clone,do_fork,dup_task_struct,copy_process,copy_thread,ret_from_fork这几处设置断点,如下图所示: 在这里插入图片描述 以下是跟踪的过程: 在这里插入图片描述 在这里插入图片描述 设置完断点后执行fork,能够发现只输出了一个命令描述,后面没有执行,停在了sys_clone这里,如果继续执行会停在do_fork的位置,之后是copy_process、dup_task_struct,ret_from_fork。

三、分析 fork 函数对应的系统调用处理过程 do_fork()函数主要完成了调用copy_process()复制父进程信息、获得pid、调用wake_up_new_task将子进程加入调度器队列等待获得分配CPU资源运行、通过clone_flags标志做一些辅助工作,其中copy_process()是创建一个进程内容的主要代码。copy_process 主要完成了调用 dup_task_struct 复制当前的 task_struct、信息检查、初始化、把进程状态设置为 TASK_RUNNING、复制所有进程信息、调用 copy_thread 初始化子进程内核栈、设置子进程pid。dup_task_struct 只是为子进程创建一个内核栈,copy_thread 才真正完成赋值。 总结来说,进程的创建过程大致是复制进程描述符、一一复制其他进程资源、分配子进程的内核堆栈并对内核堆栈关键信息进行初始化。 四、Linux内核编译过程中遇到的问题

Linux内核编译时,虚拟机的Linux内核版本为5.0.0-23-generic,下载的Linux内核版本为5.14.16。

1、添加自定义系统调用

问题: arch/x86/entry/syscall_64.o:(.rodata+0xa78):对‘__x64_sys_zzx’未定义的引用

问题原因: 添加系统调用时出错

解决方案: 三处修改方式分别如下: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

2、make bzImage出错

问题: make bzImage过程中出现如下错误: Killed Makefile:1183: recipe for target ‘vmlinux’ failed

问题原因: 在编译过程中,交换分区不够

解决方案: 可以通过扩大交换分区swap解决,可参考

https://blog.csdn.net/ssrmygod/article/details/70157716

3、开机时不能进入

问题: 开机重复显示以下内容,无法启动:

[ OK ] Started User Manager for UID 121... Stopping User Manager for UID 121...

问题原因: 进行内核编译时把/dev/sda1主分区占满,导致空间不够

解决方案: 无法开机时对/dev/sda1进行扩容,可参考

https://blog.csdn.net/huanghai381/article/details/50033775

4、总结

Linux内核编译过程中还出现了一些其他的小问题,但是因为还没有养成记录错误的习惯,也就没能记录下来供其他人参阅。总之,Linux内核编译本身不难,但是细节很多,耗时也很长,追求做完作业本身并没有很大的价值,真正的意义在于如何解决问题,以后遇到困难时是否还能够坚持下去。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3