open函数的执行过程
- open执行去C库里面,找到Int80 05指令封装。80为中断向量号,05为系统调用号
- 从idtr寄存器中读取中断向量表的基地址,找到IDT。
- trap-init调用set_system_gate等函数对中断向量表中的每一项进行初始化,并将指令所在地址的cs、eip、DPL以及门类型和中断向量号进行绑定。
- 根据中断向量号128找到第128项,其中包括cs和eip,再根据gdtr、cd、eip找到所要执行指令的地址,再进行系统调用。
- 进入系统调用,保存现场,对指令进行分析得到系统调用号05根据系统调用号,找到系统调用表中的sysopen的入口,即sysopen的函数指针。
- sysopen对文件进行查找,得到文件控制块和文件类型。
- 根据文件类型调用相应系统的文件打开函数,并在系统文件打开表中创建一个file,根据文件控制块向其中填充file_operation以及偏移量等项
- 返回到进程,进入进程文件打开表,其中有一个fd数组,将fd数组未使用的最低索引指向系统文件打开表中的相应项,然后将fd数组的下标返回给open。
- 确定与中断或者异常关联的向量i(0~255)
- 读idtr寄存器指向的IDT表中的第i项
- 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符
- 确定中断是由授权的发生源发出的。
- 判断是否发生特权级变化。
- 若发生了特权级变化,即从用户态进入了内核态,则保存进程的ss和esp。若未发生直接跳过
- 保存eflags、cs、eip
- 若为异常,保存硬件出错码error_code,若中断则跳过
- 加载IDT相应项的cs、eip
- 进入相对应的异常处理函数,检查栈中是否有error_code,若无则将0压入栈
- 将对应的C处理函数压入栈,并跳转到error_code函数,将数据按照pt_regs的结构压入栈内,调用相应的C处理函数,进行异常处理,并将这个位置写入fs
- 异常处理返回
- 进入interrupt数组,将中断向量号入栈,并调用common_interrupt函数。
- 按照pt_regs结构保存,。
- 调用do_IRQ函数,根据中断向量号i找到irq_desc数组的第i项,并调用handle_level_irq对irqaction链表进行扫描,找到中断源,并执行相对应的action
- 中断处理返回
中断和异常处理流程
硬件处理:
- 确定与中断或者异常关联的向量i(0~255)
- 读idtr寄存器指向的IDT表中的第i项
- 从gdtr寄存器获得GDT的基地址,并在GDT中查找, 以读取IDT表项中的段选择符所标识的段描述符
- 确定中断是由授权的发生源发出的。
- 判断是否发生特权级变化。
- 若发生了特权级变化,即从用户态进入了内核态,则保存进程的ss和esp。若未发生直接跳过
- 保存eflags、cs、eip
- 若为异常,保存硬件出错码error_code,若中断则跳过
- 加载IDT相应项的cs、eip
异常处理:
- 进入相对应的异常处理函数,检查栈中是否有error_code,若无则将0压入栈
- 将对应的C处理函数压入栈,并跳转到error_code函数,将数据按照pt_regs的结构压入栈内,调用相应的C处理函数,进行异常处理,并将这个位置写入fs
- 异常处理返回
中断处理:
- 进入interrupt数组,将中断向量号入栈,并调用common_interrupt函数。
- 按照pt_regs结构保存,。
- 调用do_IRQ函数,根据中断向量号i找到irq_desc数组的第i项,并调用handle_level_irq对irqaction链表进行扫描,找到中断源,并执行相对应的action
- 中断处理返回
中断或者异常返回:
- 用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中, 那么弹出这个硬件出错码。
- 检查被中断进程在被中断的时候是内核态还是用户态)若内核态,iret终止执行;否则,转入3。
- 从栈中装载ss和esp寄存器。这步意味着返 回到与旧特权级相关的栈.
定时中断源初始化以及中断发生时的过程
- 调用time_init() 对定时中断源初始化
- 再time_init()中的choose_time_init(),而choose_time_init()被宏定义为hpet_time_init()
- 在hpet_time_init()中判断有无HPET高精度时钟源,若无,则执行4,若有则执行5。
- 调用setup_pit_timer(),完成global_clock_event=&pit_clockevent,并返回hpet_time_init()
- 调用time_init_hook()设置时钟中断处理程序
- 当发生时钟中断时,相当于调用了timer_interrupt()函数,而其中主要函数为do_timer_interrupt_hook().
- 在执行其中的

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.
6.

调度的时机


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

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


课程学习总结报告
原文:https://www.cnblogs.com/lsq647sfs/p/13268887.html