原创作品转载请注明出处  《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. 033:DTL常用过滤器(2)

    date过滤器: date过滤器:将一个日期按照指定的格式,格式化成字符串.示例代码如下: views.py: from datetime import datetime def cur_date(r ...

  2. 15:解决IntelliJ IDEA的乱码问题

    1. -Dfile-encodings=UTF-8 ,全局:

  3. 【进阶技术】一篇文章搞掂:RibbitMQ

    一.简介 一开始,消息队列源自于一个激进的工程师的思想,他希望有一种通用软件“总线”能解决程序间繁重的信息通信工作 后来出现了很多消息队列产品,但是他们互不兼容,价格昂贵 后来出现了AMQP,高级消息 ...

  4. thinkphp 级联菜单实现

    养殖场->栋舍级联菜单 //获取默认养殖场和栋舍信息 public function sbjr(){ $yzc_model=M("Yzc"); $list = $yzc_mo ...

  5. ORA-02298问题处理

    参考:http://blog.163.com/yvtong@126/blog/static/8753524720132223343722/ ORA-39083: Object type REF_CON ...

  6. Log4j appender、layout

    appender输出类型配置 layout日志信息格式 Threshold属性指定输出等级 Append属性指定是否追加内容 (1)appender输出类型配置 Log4j官方的appender给出了 ...

  7. leetcode 292. Nim游戏(python)

    你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头. 拿掉最后一块石头的人就是获胜者.你作为先手. 你们是聪明人,每一步都是最优解. 编写一个函数,来判断 ...

  8. jQuery中的serializer序列化—炒鸡好用

    jQuery.serializer()序列化 serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串. serialize()函数常用于将表单内容序列化,以便用于AJAX提 ...

  9. day08—css布局解决方案之多列布局

    转行学开发,代码100天——2018-03-24 本文将记录CSS布局之垂直布局解决方案. 常见的多列布局包括以下: 1.定宽+自适应 2.两列定宽+一列自适应 3.不定宽+自适应 4.两列不定宽+一 ...

  10. SqlServer 字段类型详解

    bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型, ...