课程学习总结报告

 open函数的执行过程

  1. open执行去C库里面,找到Int80 05指令封装。80为中断向量号,05为系统调用号
  2. 从idtr寄存器中读取中断向量表的基地址,找到IDT。
  3.  trap-init调用set_system_gate等函数对中断向量表中的每一项进行初始化,并将指令所在地址的cs、eip、DPL以及门类型和中断向量号进行绑定。
  4. 根据中断向量号128找到第128项,其中包括cs和eip,再根据gdtr、cd、eip找到所要执行指令的地址,再进行系统调用。
  5. 进入系统调用,保存现场,对指令进行分析得到系统调用号05根据系统调用号,找到系统调用表中的sysopen的入口,即sysopen的函数指针。
  6. sysopen对文件进行查找,得到文件控制块和文件类型。
  7. 根据文件类型调用相应系统的文件打开函数,并在系统文件打开表中创建一个file,根据文件控制块向其中填充file_operation以及偏移量等项
  8. 返回到进程,进入进程文件打开表,其中有一个fd数组,将fd数组未使用的最低索引指向系统文件打开表中的相应项,然后将fd数组的下标返回给open。
  9. 确定与中断或者异常关联的向量i(0~255)
  10. 读idtr寄存器指向的IDT表中的第i项
  11. 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符
  12. 确定中断是由授权的发生源发出的。
  13. 判断是否发生特权级变化。
  14. 若发生了特权级变化,即从用户态进入了内核态,则保存进程的ss和esp。若未发生直接跳过
  15. 保存eflags、cs、eip
  16. 若为异常,保存硬件出错码error_code,若中断则跳过
  17. 加载IDT相应项的cs、eip
  18. 进入相对应的异常处理函数,检查栈中是否有error_code,若无则将0压入栈
  19. 将对应的C处理函数压入栈,并跳转到error_code函数,将数据按照pt_regs的结构压入栈内,调用相应的C处理函数,进行异常处理,并将这个位置写入fs
  20. 异常处理返回
  21. 进入interrupt数组,将中断向量号入栈,并调用common_interrupt函数。
  22. 按照pt_regs结构保存,。
  23. 调用do_IRQ函数,根据中断向量号i找到irq_desc数组的第i项,并调用handle_level_irq对irqaction链表进行扫描,找到中断源,并执行相对应的action
  24. 中断处理返回

中断和异常处理流程

硬件处理:

  1. 确定与中断或者异常关联的向量i(0~255)
  2. 读idtr寄存器指向的IDT表中的第i项
  3. 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符
  4. 确定中断是由授权的发生源发出的。
  5. 判断是否发生特权级变化。
  6. 若发生了特权级变化,即从用户态进入了内核态,则保存进程的ss和esp。若未发生直接跳过
  7. 保存eflags、cs、eip
  8. 若为异常,保存硬件出错码error_code,若中断则跳过
  9. 加载IDT相应项的cs、eip

异常处理:

  1. 进入相对应的异常处理函数,检查栈中是否有error_code,若无则将0压入栈
  2. 将对应的C处理函数压入栈,并跳转到error_code函数,将数据按照pt_regs的结构压入栈内,调用相应的C处理函数,进行异常处理,并将这个位置写入fs
  3. 异常处理返回

中断处理:

  1. 进入interrupt数组,将中断向量号入栈,并调用common_interrupt函数。
  2. 按照pt_regs结构保存,。
  3. 调用do_IRQ函数,根据中断向量号i找到irq_desc数组的第i项,并调用handle_level_irq对irqaction链表进行扫描,找到中断源,并执行相对应的action
  4. 中断处理返回

中断或者异常返回:

  1. 用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中, 那么弹出这个硬件出错码。
  2. 检查被中断进程在被中断的时候是内核态还是用户态)若内核态,iret终止执行;否则,转入3。
  3. 从栈中装载ss和esp寄存器。这步意味着返 回到与旧特权级相关的栈.

定时中断源初始化以及中断发生时的过程

  1. 调用time_init() 对定时中断源初始化
  2. 再time_init()中的choose_time_init(),而choose_time_init()被宏定义为hpet_time_init()
  3. 在hpet_time_init()中判断有无HPET高精度时钟源,若无,则执行4,若有则执行5。
  4. 调用setup_pit_timer(),完成global_clock_event=&pit_clockevent,并返回hpet_time_init()
  5. 调用time_init_hook()设置时钟中断处理程序
  6. 当发生时钟中断时,相当于调用了timer_interrupt()函数,而其中主要函数为do_timer_interrupt_hook().
  7. 在执行其中的

 

8.而经过各种绑定event_handler相当于tick_handle_periodic

9.在执行其中的do_timer和update_process_times,update_process_times完成对进程时间片的管理,do_timer完成对jiffies变量的更新以及do_timer中的update_times完成对墙上时间的更新。

  根文件系统挂载

1.首先运行BootLoader,并让其给Linux传参,主要参数有root和init。

 

2.内核通过start_kernel对参数进行处理,其中start_arch()进行参数读取,vfs_caches_init()调用mnt_init()进行初始化,mnt_init()中的init_rootfs()注册rootfs文件系统,init_mount_tree()中的do_kernel_mount()将rootfs挂载到根目录。

3.第一阶段先执行 initrd 文件系统,进行检查初始化硬件设备,并安装注册设备模块。

4.检测Initrd格式,若为cpio则执行5,若为image-initrd格式,则执行6

5.课程学习总结报告_第1张图片

 

 6.

课程学习总结报告_第2张图片

调度的时机

课程学习总结报告_第3张图片

 

 课程学习总结报告_第4张图片

 

 

定时器周期中断处理函数的作用

课程学习总结报告_第5张图片

 

进程:

处于用户态的进程,当申请内存时,只会打一张欠条,当开始使用这块内存时,产生缺页异常,cpu给其分配地址空间。

处于内核态的进程,申请地址时会,立刻得到。

课程学习总结报告_第6张图片

 

课程学习总结报告_第7张图片

 

你可能感兴趣的:(课程学习总结报告)