标签:
20135109 高艺桐
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、博客地址汇总
第一周学习笔记计算机是如何工作的
第二周学习笔记深入理解计算机
第三周学习笔记构造一个简单的Linux内核的MenuOS
第四周学习笔记扒开系统调用的三层皮(上)
第五周学习笔记扒开系统调用的三成皮(下)
第六周学习笔记进程的描述和进程的创建
第七周学习笔记可执行程序的装载
第八周学习笔记进程的切换和系统的一般执行过程
二、知识点总结
(一)计算机是如何工作的
(二)深入理解计算机
(三)构造一个简单的Linux内核的MenuOS
arch/x86目录下的代码是我们最重点关注的
fs/文件系统
init/内核启动相关的代码
start_kernel函数相当于C语言的main函数
kernel/Linux内核的核心代码
mm/内存管理代码
init_task 即手工创建的PCB,0号进程即最终的Idle进程
trap_init 初始化中断,设置中断门,系统陷阱门
init_process Linux系统的第一个用户态进程,根目录下的init程序(作为1号进程)由kernel_init创建
rest_init 0号进程,一直存在的进程,创建1号进程
qemu命令是模拟内核启动虚拟机,启动Linux内核需要三个参数(kernel、initrd、root所在的分区和目录),执行的第一个文件是init。
(四)扒开系统调用的三层皮(上)
中段处理的过程:首先保存cs:eip的值;保存当前堆栈段、栈顶、标志寄存器;加载系统调用或者系统调用的中段服务历程入口。之后执行内核代码、完成中断服务、发生进程调度
使用库函数API和C代码中嵌入汇编代码触发同一个系统调用
(五) 扒开系统调用的三成皮(下)
(1)save_all保存现场
(1)make rootfs:自动编译,生成根文件系统,自动启动
(2)(gdb)list 查看代码
(3)(gdb)s 单步调试进入函数体(4)(gdb)n 单步调试不进入函数体
(六)进程的描述和进程的创建
(1)使用系统调用clone、fork、vfork均可创建一个新进程,但都是通过调用do_fork来实现进程的创建
(2)复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈
(3)修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread
(4)p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
(5)p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
(七)可执行程序的装载
(1)创建新进程
(2)新进程调用execve()系统调用执行指定的ELF文件
(3)调用内核的入口函数sys_execve(),sys_execve()服务例程修改当前进程的执行上下文
ELF格式中主要有3种可执行文件:可重定位文件.o,可执行文件,共享目标文件
ELF可执行文件会被默认映射到0x8048000这个地址
命令行参数和环境变量是如何进入新程序的堆栈的
Shell程序-->execve-->sys_execve,然后在初始化新程序堆栈时拷贝进去。
先函数调用参数传递,再系统调用参数传递
当前程序执行到execve系统调用时陷入内核态,在内核中用execve加载可执行文件,把当前进程的可执行文件覆盖掉,execve系统调用返回到新的可执行程序的起点
动态链接库的装载过程是一个图的遍历过程,ELF格式中的.interp和.dynamic需要依赖动态链接器来解析,entry返回到用户态时不是返回到可执行程序规定的起点,返回到动态链接器的程序入口
(八)进程的切换和系统的一般执行过程
进程调度的时机:
(1)需要切换的信息:用户地址空间、控制信息、硬件上下文(中断也要保存上下文)等
(2)schedule()中的context_switch中的switch_to切换寄存器和堆栈的状态、eip的位置
(3)thread.sp内核堆栈的栈底;thread.ip当前进程的eip
(4)next进程的第一条指令:next_ip一般是$1f,对于新创建的子进程是ret_from_fork
Linux系统执行过程中的几个特殊情况
(1)内核线程通过中断处理过程中(用户态进程与内核线程间的切换以及内核进程和内核进程间的切换)没有权限的变化,cs段没有发生变化
(2)内核线程主动调度schedule(),只有进程上下文的切换,没有发生中断上下文的切换
(3)创建子进程的系统调用,子进程返回时的执行起点为ret_form_fork(next_ip=ret_form_fork)
三、心得体会
通过八周的Linux内核分析课程的学习,我对Linux内核是如何工作的学习到了很多知识。每个星期按时的听课件做习题写博客成为了我逐渐养成的习惯。起初我对老师讲的一些专业的词汇还很迷茫,到现在我可以用自己的话解释那些专业术语;从动态的演示堆栈的变化到现在我可以熟练的在脑中形成一个变化图;从对代码的陌生到可以熟练的做出实验部分,包括克隆、追踪、设置断点等基本的操作;从对一些比较抽象概念的懵懂到听老师通过比喻变得更加清晰化,知道了他们彼此之间的联系与区别。
学习对Linux内核的分析的学习,我更加的了解了计算机的工作的原理,对进程的切换、系统的调用都有很深入的理解。通过老师设置的测试+互评+自评的学习模式,我更好的学习到了别人的长处,也在这八周内不断的完善自己。
最后感谢孟宁老师的细心讲解,让我对Linux内核的工作原理有了深入的学习。
标签:
原文地址:http://www.cnblogs.com/gyt0520/p/5434186.html