原创作品转载请注明出处  《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

作者:严哲璟

说一下我对Linux系统的理解

1.加载Linux内核准备:在加载基本输入输出模块(BIOS)之后,从磁盘的引导扇区读入操作系统的代码文件块到内存中,之后开始整个系统的初始化.

2.main.c的start_kernel函数是整个操作系统的入口,这也与Linux是基于C语言的特性相符,start_kernel具体做的动作很多,包括死锁检测,指定多核CPU的ID,栈溢出保护,关闭中断,初始化内存页,以及一些重要模块,如mm_struct,trap_init,schedule_init,以及set(init_task)强制性手动创建一个0号进程即IDLE进程,当只有一个进程的时候,不断循环.

3.rest_init创建一个新的进程(用户进程),pid=1,进程的启动需要 sche_init模块

这些是操作系统最基本的核心,然后我们还有其他的功能,如进程管理,内存管理,文件管理.其中最重要当属进程管理.

进程管理最核心的是进程的切换和中断机制,中断有很多种,如软中断,即系统调用,陷阱,系统异常等等,还有硬中断,如IO中断

中断方式上面硬中断是通过相关的硬件中断处理器,如我们点击键盘触发相关的硬件中断,处理器进入相关的中断状态,在此略去.

而软中断主要是通过相应的系统指令(主要是int)指令去触发,软中断可以是程序本身的行为(系统调用),也可能是CPU为了保护计算机而做出的一种反应(异常).

系统调用主要分为3层:第一是相关的API,即应用程序接口,如read(),write(),getpid()等等,第二层是这些高级接口对应的中断向量表中的偏移,即syscall_table中的序号,对应一个中断服务程序.第三层是system_call保存当前上下文进入中断服务程序进行处理.处理完成之后iret,返回用户程序,在这之前,(应该说从内核态转为用户态的时候)检查进程调度标识,是否需要调度.

进程的创建和切换:通过系统调用fork(),创建一个与父进程完全一样的子进程,包括代码段完全一样,但是子进程的返回值为零,而且子进程的返回用户态的堆栈地址被改变了,其实这也很好理解,你一个子进程要做其他的事情,需要自己的用户空间和内核空间.不仅如此,当父进程执行了,子进程被调度执行的时候,子进程开始执行的地方是ret_from_fork,其下一句就是iret,而通过稍微修改在子进程的内核堆栈中保存的那些数据,iret就可以还原一个与父进程稍微不一样的子进程了.

进程的切换:关键函数是shcedule()和switch_to(),根据不同的进程优先级算法,如LRU,CLOCK,FIFO等,在就绪(3状态为就绪,阻塞,运行)的进程队列里挑选一个出来执行,这其中的关键部分是schedule(),当检测到一个进程需要调度的时候,从用户态切换到内核态执行内核代码(3G以上的区域),维护一个结构,此结构中保存当前被调度准备执行的进程在上一次被调度出去就绪或阻塞的时候执行的下一句代码,并且保存进程的用户堆栈,由于此代码是内核代码,对所有进程可见并通用,因此执行到此处都是一样的.通过switch_to,进程得以回复原来的用户堆栈的sp,以及eip,得以继续执行.之后schedule()返回,重新回到用户态,但是eip和esp都与上一个进程不一样了.

进程加载可执行文件:假设我们在运行shell进程,要执行cd /home这个命令,我们需要加载cd这个可执行文件,在linux上面,终端命令基本都被作为可执行文件,保存在/usr/bin中,在执行的时候,需要加载,并且传入一定参数.首先我们fork出一个新进程,但是在fork的新子进程中,我们需要调用exec类函数来加载一个可执行文件.加载这个可执行文件的具体过程是:调用启动加载器,加载器删除子进程现有的虚拟存储器段(后面会说)并创建一组新的代码,数据,堆,和栈,新的栈和堆被初始化为零,通过将虚拟地址空间中的页映射到可执行文件的页,新的代码和数据段被初始化为可执行文件的内容.最后加载器跳转到_start地址,最终从可执行目标文件中调用相应的main()函数,因此子进程就变成一个新的进程,其功能是可执行目标文件的功能,如上述所说,打开/home这个目录,将当前目录置为/home.C语言的编译和链接分为静态和动态链接,其中静态链接是将所有的头文件一起编译链接,动态链接分为共享库动态链接和运行时动态链接.共享库是/usr/lib中的一些动态链接库,其作用是只在加载的时候链接而不需要重新编译,这样链接非常方便,修改也可以独立修改.而运行时动态链接需要加载加载器,其本身也是一个共享库.

下面是个人理解的Linux32位的进程映像(即课件说的进程地址空间,是虚拟存储器)


内核虚拟存储器3G以上


用户栈(运行时创建),下面的这条线代表ESP,栈往下增长



共享库的存储器区域



运行时堆(malloc)往上增长


读写段,或者叫数据段,在可重定位目标文件中是data和bss字段


只读段或者是代码段(与上面的段都是从obj可执行文件中加载,下面的线是0x08048000)


总结部分:我对这门课的评价非常高,这门课让我对计算机的系统原理和系统实现有了非常好的认识,孟宁老师先从linux32位机器码说起,阐述了程序的机器级代码的实现,以及一些ASM的C汇编,让我们对机器代码有了一个比较好的认识,其次,老师讲述了进程,程序的映像以及在栈中程序的行为,之后老师再讲到进程的切换以及中断,最后课程讲授链接和加载的过程,让我们学会制作一些简单的共享库,理解了大型程序是怎么构造,以及理解其他重要的系统概念.

学完这门课之后,最大的收获是初步认识了操作系统的本质,以及当我们机器出现问题了,应该找到什么样的问题去尝试解决.

最大的遗憾是,由于时间实在太少,没能非常仔细的把全部内容熟悉,可能还有一些地方有疏漏


Linux系统理解以及Linux系统学习心得的更多相关文章

  1. 20135323符运锦期中总结----Linux系统的理解及学习心得

    一.网易云课堂 1.各章节总结 第一周:计算机是如何工作的http://www.cnblogs.com/20135323fuyunjin/p/5222787.html 第二周:操作系统是如何工作的ht ...

  2. 一点点linux系统的学习心得

    我相信你正在阅读本文的时候,可能是因为你渴望学习Linux技术.我想分享一下过去两年中我自己的一些学习经历,希望你能更顺利地成为Linuxer. 两年前在Linux系统的运行和维护方面找到了一份工作( ...

  3. LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程

    LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/c ...

  4. LINUX内核分析第三周学习总结——构造一个简单的Linux系统MenuOS

    LINUX内核分析第三周学习总结——构造一个简单的Linux系统MenuOS 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163. ...

  5. LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下)

    LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...

  6. LINUX内核分析第八周学习总结:进程的切换和系统的一般执行过程

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程切换的关 ...

  7. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  8. Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...

  9. 《Linux内核分析》期末总结及学习心得

    [洪韶武 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ] 一.学习心得 本学 ...

随机推荐

  1. Jenkins slave-agent.jnlp 无法安装为服务(install as a service)

    问题: 在部署持续集成环境,配置slave节点时遇到一个问题,slave-agent.jnlp可以正常启动运行(不能正常启动的点这里) 但是在保存为系统服务时,slave-agent.jnlp点击[i ...

  2. 20180704-Java开发环境配置

    介绍如何搭建Java开发环境推荐:在Cloud Studio中运行Java程序 Java是一种跨平台的编程语言,想要让你的计算机能够运行Java程序那么就需要安装JRE,而想要开发Java程序,那么就 ...

  3. 20180907-Java Applet基础

    Java Applet基础 applet是一种Java程序.它一般运行在支持Java的Web浏览器内.因为它有完整的Java API支持,所以applet是一个全功能的Java应用程序. 如下所示是独 ...

  4. hdu 5511 Minimum Cut-Cut——分类讨论思想+线段树合并

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5511 题意:割一些边使得无向图变成不连通的,并且恰好割了两条给定生成树上的边.满足非树边两段一定在给定生成 ...

  5. SecondModel 实现类

    package com.test.mvp.mvpdemo.mvp.v6.model; import com.test.mvp.mvpdemo.mvp.v6.SecondContract;import ...

  6. Python——GUI可视化

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class ...

  7. 第 2 章 前端基础之CSS

    一.CSS语法 CSS规则由两个主要的部分构成:选择器,以及一条或多条声明. ''' selector { property: value; property: value; ... property ...

  8. Marriage Match II 【HDU - 3081】【并查集+二分答案+最大流】

    题目链接 一开始是想不断的把边插进去,然后再去考虑我们每次都加进去边权为1的边,直到跑到第几次就没法继续跑下去的这样的思路,果不其然的T了. 然后,就是想办法咯,就想到了二分答案. 首先,我们一开始处 ...

  9. python的正则

    一.认识模块  什么是模块:一个模块就是一个包含了python定义和声明的文件,文件名就是加上.py的后缀,但其实import加载的模块分为四个通用类别 : 1.使用python编写的代码(.py文件 ...

  10. Netty之SubPage级别的内存分配

    SubPage 级别的内存分配: 通过之前的学习我们知道, 如果我们分配一个缓冲区大小远小于page, 则直接在一个page 上进行分配则会造成内存浪费, 所以需要将page 继续进行切分成多个子块进 ...