Xv6内核分析(三.10)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月20日16:30:27 评论 472

main函数之tvinit

1. 中断描述符

中断描述符表idt共有256个项目,每个条目8字节,根据每个条目的类型不同,共有3种不同的门描述符如下:

Xv6内核分析(三.10)

在xv6中的设置idt代码如下:

Xv6内核分析(三.10)

注意,这个idt中断描述符表示被所有的cpu共享的。从代码中可以看出,所有的IDT中断选择子的RPL都是0,这表示所有的中断都是在内核级别执行的。另外,IDT中的DPL可以理解成当使用此IDT项时,CPL的最低级别。

xv6中使用SETGATE设置idt表项,SETGATE的具体内容如下:

Xv6内核分析(三.10)

从图中可以看出,主要设置的就是门的类型、CS选择子、中断处理函数的地址(由于代码段的基址都设置的为0,所以偏移量就是实际代码所在的地址)、DPL等级。

idt表示xv6中的中断描述符表,共256项:

Xv6内核分析(三.10)

2. 中断向量表

vectors[i]是在vector.S中定义的,表示对应向量号的中断处理函数地址:

Xv6内核分析(三.10)

以vector0为例,vector0的符号地址如下:

 

Xv6内核分析(三.10)

可以看出,vector0就是0号中断向量的处理函数的地址,第一个push是压入空的cpu错误码,因为有的中断向量处理器会产生错误码,有的不会,为了保证这两种情况下,栈中的数据个数都是一样,对于没有cpu错误号产生的中断向量,压入一个0值假装是错误号:

Xv6内核分析(三.10)

比如8号中断是会产生cpu错误码的,所以只push了中断号:

Xv6内核分析(三.10)

第二个压入的是当前中断向量号,然后调用alltraps。alltraps定义在trapasm.S中:

Xv6内核分析(三.10)

首先压入其他的寄存器形成一个完整的中断帧,具体细节可见xv6-book第三章,然后设置内核的数据段寄存器,接着调用trap函数,trap函数的参数的中断帧地址,所以把esp压栈。当trap函数结束后,恢复栈指针。完整中断帧如下:

Xv6内核分析(三.10)

当中断函数处理完后,调用trapret:

Xv6内核分析(三.10)

trapret首先弹出一些寄存器,然后调整栈指针到保存eip值的地方,这样执行iret指令后,处理器就回返回到原来被打断的代码处继续执行。

3. 系统调用软中断

回到代码中,首先设置了默认的256个中断描述符,然后单独设置了系统调用中断T_SYSCALL,在xv6下,系统调用的中断号是64,系统调用中断描述符被设置为一条陷阱门,DPL设置为用户级别,这样就可以从用户空间调用int指令产生软中断了:

Xv6内核分析(三.10)

下面几个函数是跟文件系统相关的,在分析文件系统时在来分析:

Xv6内核分析(三.10)

4. 中断处理流程图

Xv6内核分析(三.10)

gewenbin
  • 本文由 发表于 2020年12月20日16:30:27
  • 转载请务必保留本文链接:http://www.databusworld.cn/9376.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: