课程学习总结报告(代码片段)

happyyouli happyyouli     2022-12-06     797

关键词:

一、linux系统概念模型

1. 概述

linux系统是一个多用户多任务的分时操作系统,函数调用是操作系统的三大法宝之一,使得编程极为灵活。由于CPU的运行速度远远大于外设,所以中断机制的使用解决了CPU等待外设的情况。系统调用是一种特殊的中断,封装了对系统的一些底层的操作,保证了系统的安全性。在中断返回时可能发生进程切换,内核线程也可以主动发起进程切换

本篇博文是对整个Linux操作系统分析课程的整体回顾,下面对上述焦点问题分别详细阐述

2. 函数调用

函数调用过程概述

  • 首先调用者的call函数将它的下一条指令地址保存在栈顶,将eip(rip)设置为被调用函数的起始地址

  • 建立被调用者函数的堆栈框架、执行被调用者函数体、拆除被调用者函数框架

  • ret指令将调用者的下一条指令地址恢复到eip(rip)

函数调用中的硬件操作

例如对于函数调用:call 0x12345

/*32位*/
pushl %eip (*) 
movl $0x12345, %eip (*) 

/*64位*/
pushq %rip (*)
movq $0x12345, %rip (*) 

函数返回:ret

 /*32位*/
 popl %eip (*)
 
 /*64位*/
 popq %rip (*)

上面的指令均为伪指令,这个动作由硬件一次性完成,这是由于EIP寄存器不能被直接修改和使用

函数调用中的软件操作

例如对于函数:

int main() 
	return f(8)+1;

在32位系统中,汇编为:

main:  
	pushl %ebp
	movl %esp, %ebp
	subl $4, %esp
	movl $8, (%esp)
	call f
	addl $1, %eax
	movl  %ebp,%esp
	popl  %ebp
	ret

在64位系统中,汇编为:

main:
	pushq %rbp
	movq %rsp, %rbp
	movl $8, %edi
	call f
	addl $1, %eax
	popq %rbp
	ret

我们对比32位系统和64位系统的函数调用:

  1. 共同点:

    • 都在调用之前保存了原来的栈,为新函数开辟了新的栈空间

    • 调用返回时都恢复了原来的栈空间

    • 函数的返回值都在eax(rax)寄存器中保存

  2. 区别:

    • 参数传递上存在差别,32位系统将参数存在新栈的栈底

3. 中断和异常

中断和异常的区别与联系:

中断是异步的,由硬件随机产生,在程序执行的任何时候可能出现

异常是同步的,在特殊的或出错的指令执行时由CPU控制单元 产生

我们用“中断信号”来通称这两种类型的中断

中断上下文

中断上下文不同于进程上下文,中断上下文只包含了很有限的几个寄存器,建立和终止这个上下文所需要的时间很少。中断程序只能使用被中断进程的内核栈作为自己的运行栈

中断和异常的硬件级处理

  • 当CPU正常运行时,执行一条指令后,cs和eip包含了下一条将要执行的指令的逻辑地址
  • 在执行这条指令之前,CPU会检查在运行前一条指令时是否发生了一个中断或者异常。
  • 如果发生了中断或异常:
    • 确定中断向量号i,读idtr寄存器指向的IDT表中的第i项
    • 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符
    • 确定中断是由授权的发生源发出的,只允许从低特权级陷入高特权级,反之不可以
    • 如果是由用户态陷入内核态,用与新特权级相关的栈段和栈指针装载ss和esp寄存器,在新的栈中保存ss和esp以前的值
    • 如果发生的是故障,用引起异常的指令地址修改cs 和eip寄存器的值,以使得这条指令在异常处理结束后能被再次执行
    • 在栈中保存eflags、cs、eip;如果异常产生一个硬件出错码,则将它保存在栈中
    • 装载cs和eip寄存器,其值分别是IDT表中第i项描述符的段选择符和偏移量
  • 中断返回:
    • 用保存在栈中的值装载cs、eip和eflags寄存器
    • 检查中断时是在内核态还是用户态,如果在内核态,则终止;如果在用户态,从栈中装载ss和esp寄存器

中断和异常的软件级处理

异常处理:

  • 按照pt_regs结构定义的堆栈数据格式完成相应的入栈操作,进一步完成现场的保存

  • 把堆栈地址中的do_handler_name()函数的地址装入edi寄存器中,并在这个位置写入fs值,使栈结构进一步与pt_regs结构完全一致

  • 最后执行call *%edi指令

中断处理:

可以用下面的汇编代码来总结:

SAVE_ALL
movl %esp,%eax
call do_IRQ jmp
$ret_from_intr

4. 系统调用

系统调用是陷阱这种软中断方式主动从用户态进入内核态的

传统的系统调用:

int $0x80 指令会触发系统调用,CPU压栈?些关键寄存器,根据eax寄存器传递的系统调用号调用对应的内核处理函数,接着内核负责保存现场,系统调用内核函数处理完后恢复现场,后通过iret出栈哪些CPU压栈的关键寄存器。

快速系统调用:

sysenter和syscall都借助CPU内部的MSR寄存器来查找系统调用处理入口,其余操作与传统系统调用相同

系统调用的参数传递:

32位x86和64位的x86都是通过寄存器来传递。注意:在普通的函数调用中,32位x86使用压栈来传递参数,而64位x86仍然使用寄存器传递参数

5. 进程管理

进程创建

0号进程初始化是通过硬件编码,其他进程的初始化都是通过do_fork复制父进程的方式初始化

1号进程为是kernel_init,是所有用户进程的祖先;2号进程时kthreadd,是所有内核线程的祖先,1、2号进程都是复制0号进程得到的

父进程通过fork系统调用进入内核_do_fork函数,主要完成了:

  • 调用copy_process()复制父进程
  • 分配子进程的内核堆栈并对内核堆栈和thread等进程关键山下文进行初始化
  • 调用wake_up_new_task将子进程加入就绪队列等待调度执行

进程切换

进程调度时机: Linux内核通过schedule函数实现进程调度,分别为中断返回前和内核线程主动调用schedule

进程上下文:

  • 用户地址空间:包括程序代码、数据、用户堆栈等

  • 控制信息:进程描述符、内核堆栈等

  • 进程的CPU上下文,相关寄存器的值

当调用schedule函数时其中的switch_to做了关键的进程上下文切换。将当前进程X的内核堆栈切换到进程调度算法选出来的next进程的内核堆栈,并完成了进程上下文所需的EIP等寄存器状态切换

二、Linux模型的举例

我们举一个在linux命令行输入vim,并按下回车的例子:

我们在键盘输入回车键系统能有反应,说明发生了中断,该中断处理程序处理了键盘的输入信号

中断返回的时候,父进程fork系统调用进入内核_do_fork函数

调用copy_process()复制父进程

分配子进程的内核堆栈并对内核堆栈和thread等进程关键山下文进行初始化

调用wake_up_new_task将子进程加入就绪队列等待调度执行

Linux内核通过schedule函数实现进程调度

schedule函数中的switch_to做了关键的进程上下文切换,将之前进程的内核堆栈以及相关寄存器切换到vim进程上来,这样我们就看到进入了vim程序的界面

三、对课程的心得体会

本课程两位老师通过理论和实验双管齐下,对linux系统的原理进行了深刻的阐述,使得本人对Linux操作系统自有的特性有了一定的认识,不再像之前只是操作系统这个笼统的概念。

改进意见:增加一些个在实际工程中使用Linux的实验,这样可以让同学们在应用中从不同的角度理解Linux系统

课程学习总结报告(代码片段)

课程学习总结报告Linux之进程  概述:进程是Linux进行资源分配和调度的基本单位,进程也被看做是程序的一次执行过程,当持久化在磁盘上的二进制代码被载入内存时,Linux操作系统为其分配了用户栈和内核栈,同时使用task_s... 查看详情

课程学习总结报告(代码片段)

一、基础知识1、Liunx汇编主要寄存器:EAX、EBX、ECX、EDX、EBP、ESI、EDI、EIP、ESP(其中ESP是堆栈栈顶寄存器,EBP是堆栈基址指证针,EIP寄存器不能直接使用和修改。调用call时会修改EIP指针。EBP和ESP总指向同一个堆栈,EBP指向栈底... 查看详情

《密码安全新技术》课程总结报告(代码片段)

《密码安全新技术》课程总结报告课程学习内容总结第一次课网络(Web)安全与内容安全本次讲座的学习内容主要为两方面:1.Web应用安全SQL注入HavijPangolin1.反射型XSS2.存储型XSSApache解析漏洞Nginx解析漏洞2.隐私安全用户轨迹:移动... 查看详情

课程学习总结报告(代码片段)

@目录Linux概念模型Linux系统启动用户态和内核态进程管理和调度文件管理例子讲解例子LED灯心得体会与改进建议Linux概念模型在Linux系统分析这门课中,我们主要学习了中断,系统调用,程序加载执行,进程管理,文件系统,计时... 查看详情

课程学习总结报告(代码片段)

一、Linux系统模型  其中最重要的部分是内核,向上为系统调用和应用程序提供支持,向下对硬件资源和驱动程序进行管理。 二、传统I/O操作读写流程  1.用户进程向CPU发起read系统调用读取数据,由用户态切换为内... 查看详情

课程学习总结报告(代码片段)

Linux内核主要由以下几个功能:进程管理、文件系统、IO体系结构和设备驱动程序、内存管理等。一.进程管理在Linux中,进程是系统资源分配的基本单位,也是使用CPU运行的基本调度单位。它实现了对进程的控制和调度。进程管... 查看详情

课程学习总结报告(代码片段)

目录一、linux系统概念模型1.概述2.函数调用函数调用过程概述函数调用中的硬件操作函数调用中的软件操作3.中断和异常中断和异常的区别与联系:中断上下文中断和异常的硬件级处理中断和异常的软件级处理4.系统调用5.进程管... 查看详情

课程学习总结报告(代码片段)

从存储程序计算机到冯诺依曼体系结构存储程序计算机的主要思想是将程序存放在计算机存储器中,然后按存储器中的存储程序的首地址执行程序的第一条指令,以后就按照该程序中编写好的指令执行,直至程序执行结束。冯诺... 查看详情

第九周课程总结&实验报告(代码片段)

第九周课程总结&实验报告(七)实验任务详情:要求:(1)总票数1000张;(2)10个窗口同时开始卖票;(3)卖票过程延时1秒钟;(4)不能出现一票多卖或卖出负数号票的情况。实验代码:packageproject7;classMyThreadimplementsRunna... 查看详情

第九周课程总结&实验报告(代码片段)

实验内容:源代码:主类:packageexercise;publicclassTrainStationTicketSalesimplementsRunnableprivateintticket=1000;publicvoidrun()for(inti=0;i<1000;i++)this.sale();ticket--;publicsynchronizedvoidsale()if(ticket>=0)tryThread.sleep(100);catch(InterruptedExceptione)e.printStackTrace();... 查看详情

第九周课程总结&实验报告(代码片段)

课程总结1、继承Thread类创建线程:Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法... 查看详情

第八周课程总结&实验报告(代码片段)

实验报告六编写一个类,在其main()方法中创建一个一维数组,在try字句中访问数组元素,使其产生ArrayIndexOutOfBoundsException异常。在catch子句里捕获此异常对象,并且打印“数组越界”信息,加一个finally子句,打印一条信息以证明... 查看详情

第八周课程总结&实验报告(代码片段)

第八周课程总结&实验报告(六)一、实验目的(1)理解异常的基本概念;(2)掌握异常处理方法及熟悉常见异常的捕获方法。二、实验要求(1)练习捕获异常、声明异常、抛出异常的方法、熟悉try和catch子句的使用(2)掌... 查看详情

第七周课程总结及实验报告(代码片段)

(一)设计一个类层次,定义一个抽象类--形状,其中包括有求形状的面积的抽象方法。继承该抽象类定义三角型、矩形、圆。分别创建一个三角形、矩形、圆存对象,将各类图形的面积输出。注:三角形面积s=sqrt(p(p-a)(p-b)*(p-c))其... 查看详情

第七周课程总结&实验报告(代码片段)

第七周课程总结&实验报告(五)实验四类的继承实验目的理解抽象类与接口的使用;了解包的作用,掌握包的设计方法。实验要求掌握使用抽象类的方法。掌握使用系统接口的技术和创建自定义接口的方法。了解Java系统包的... 查看详情

第八周课程总结&实验报告(代码片段)

第八周课程总结&实验报告(六)实验六 Java异常实验目的理解异常的基本概念;掌握异常处理方法及熟悉常见异常的捕获方法。实验要求练习捕获异常、声明异常、抛出异常的方法、熟悉try和catch子句的使用。掌握自定义... 查看详情

第七周课程总结&实验报告(代码片段)

第七周课程总结一、接口的实际应用接口在实际中更多的作用是用来制定标准的。抽象类和接口的的关系No.区别点抽象类接口1定义包含一个抽象方法的类抽象方法和全局常量的集合2组成构造方法、抽象方法、普通方法、常量、... 查看详情

第七周课程总结及实验报告(代码片段)

实验报告(一)抽象类的使用1.设计一个类层次,定义一个抽象类--形状,其中包括有求形状的面积的抽象方法。继承该抽象类定义三角型、矩形、圆。分别创建一个三角形、矩形、圆存对象,将各类图形的面积输出。注:三角... 查看详情