标签:故障 init进程 键盘 tfs ble 开始 访问 文件控制 占用
主要寄存器:EAX、EBX、ECX、EDX、EBP、ESI、EDI、EIP、ESP(其中ESP是堆栈栈顶寄存器,EBP是堆栈基址指证针,EIP寄存器不能直接使用和修改。调用call时会修改EIP指针。EBP和ESP总指向同一个堆栈,EBP指向栈底,ESP指向栈顶)
pushl $8 movl %esp, %ebp subl $4, %esp movl $8, (%esp)
中断(异步的):由硬件随机产生,在程序执行的任何时候可能出现,比如键盘输入。
异常(同步的): 在(特殊的或出错的)指令执行时由CPU控制单元产生,比如除0、INT指令、缺页。
在进程的内核态堆栈保存程序计数器的当前值(即eip和cs寄存器)以便处理完中断的时候能正确返回到中断点,并把与中断信号相关的一个地址放入进程序计数器, 从而进入中断的处理。
如图,A、B为中断嵌套,C为被中断进程,B也是用C进程的内核栈,B执行完一定返回A,但A执行完不一定返回C。A会判断自己是否是最后一级中断,如果是且进程允许调度则执行调度程序,如果C的优先级高,在恢复上下文。
中断控制器完成中断事件和中断向量的对应,CPU通过向量来群顶设备和对应的中断处理程序入口。Intel给中断控制器分配的中断向量号从32开始,0~31分配给异常。
中断描述符表:每个中断或异常向量在表中有相应的中断或者 异常处理程序的入口地址(包括CS、EIP、权限和类型等)。每个描述符8个字节(寻址:IDT+n*8)
当中断发生时,Linux系统会跳转到asm_do_IRQ()函数(所有中断程序的总入口函数),并且把中断号irq传进来。根据中断号,找到中断号对应的irq_desc结构(irq_desc结构为内核中中断的描述结构,内核中有一个irq_desc结构的数组irq_desc_ptrs[NR_IRQS]),然后调用irq_desc中的handle_irq函数,即中断入口函数。
1)CPU的正常运行:
中断/异常处理完后,相应的处理程序会执行一条iret汇编指令,这条汇编指令让 CPU控制单元做如下事情:
1,用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中, 那么弹出这个硬件出错码
2,检查处理程序的特权级是否等于cs中最低两位的值(这意味着进程在被中断的时候是运行在内核态还是用户态)。若是,iret终止执行;否则,转入3
3,从栈中装载ss和esp寄存器。这步意味着返回到与旧特权级相关的栈
4,检查ds、es、fs和gs段寄存器的内容,如果其中一个寄存器包含的选择符是一个段描述符,并且特权级比当前特权级高,则清除相应的寄存器。
初始化中断描述符表:调用不同函数对中断描述符表进行填充
用_set_gate中的参数生成一个中断描述符,放在第N项上。IDT实际上是经过两次初始化,第一次在start kernel之前,用ignore_int()函数填充256个idt_table表项
ignore_int()的作用:保存一部分内容在栈上,调用打印程序打印int_msg,恢复现场。
Start_kernel中的IDT表初始化:trap_init()、init_IRQ()
异常:
I/O中断处理程序:
进程描述符放在动态内存中而且和内核态的进 程栈放在一个独立的8KB的内存区中
0号进程是所有进程的父进程, 0号创建init进程,init完成相关初始化,执行相关程序。Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构: Thread_info和进程的内核堆
可运行队列:
进程切换:
schedule() --> context_switch() --> switch_to -> __switch_to()
进程切换主要有 两部分:1、切换全局页表项;2、切换内核堆栈和硬 件上下文。切换全局页表项这个切换工作由 context_switch()完成。其中switch_to和__switch_to() 主要完成第二部分。
挂载虚拟的文件系统rootfs作为初始文件系统
挂载一个真正的根文件系统替换rootfs(先生成一个挂载点,为0号进程的根目录,在挂载点上挂载文件系统)
sys_mount:扫描内核已注册文件链表,找到和它挂载类型相匹配的结构,执行相应的函数来完成文件系统挂载,如果没有,挂载失败(因此挂载之前要先注册)
已注册文件系统链表结构体:
get_sb:给文件系统创建超级块和根目录对象,超级块完成文件系统的描述。mount根据文件系统类型运行不同的get_sb
根文件挂载的过程:
populate_rootfs函数负责加载initramfs和cpio-initrd到根文件系统rootfs;对于不是以上两种情况把它放入将其释放到/initrd.image.
open执行--->INT 80 05--->查找中断异常向量表(trap_init)--->保存现场--->对指令分析参数05--->执行系统调用表--->sys_open--->进行命名查找--->得到文件控制块,检查文件类型--->根据不同类型调用不同的文件打开函数--->创建一个file结构表(文件打开表),用文件控制块填写--->返回进程(进程中也有file,有fd数组,fd指针指向刚创建的系统打开表)
文件read前要open它,以建立用户和文件的联系,打开一个文件创建一个file结构
VFS虚拟文件系统:不用考虑文件属性。各种不同的文件系统通过mount(挂载、安装)到根文件系统中。它的超级快对象中有各种文件的私有结构,实现对不同文件的兼容
每个安装的文件系统都有一个超级块结构,mount会创建一个与它相应的VFS超级块对象
本次课程学习到了Linux的基础知识,包括进程切换、中断和系统调用、驱动设备、文件系统等,受益良多。
标签:故障 init进程 键盘 tfs ble 开始 访问 文件控制 占用
原文地址:https://www.cnblogs.com/mia-blog/p/13269142.html