1. 什么是用户态和内核态?两者有何区别?什么是中断和系统调用?两者有何区别?计算机在运行时,是如何确定当前处于用户态还是内核态的?
用户态:运用非特权指令,在Linux中特权级为3级,Ring3,最低。不能访问内核态的地址空间包括代码和数据
内核态:能够运用特权和非特权指令(除了访管指令),在Linux中特权级为0级,最高。能访问
例子:
如:用户运行一个程序,该程序创建的进程开始时运行自己的代码,处于用户态。如果要执行文件操作、网络数据发送等操作必须通过write、send等系统调用,这些系统调用会调用内核的代码。进程会切换到Ring0,从而进入内核地址空间去执行内核代码来完成相应的操作。内核态的进程执行完后又会切换到Ring3
可以理解为广义上中断包括系统调用,狭义上分为中断和异常,其中异常又可以分为
Trap:访管指令【此为系统调用】 能中断
Fault:page default
Abort:溢出
当然有些时候可以把系统调用从异常中分离开来单独算作一类
其中对
1:系统调用:由于在程序中使用了请求系统服务的系统调用而引发的过程,通常是有意的
而其他两类通常是无意的。
2:其他两类访问中断符号表后即可进行对应的中断处理程序,而系统调用还需要访问系统调用表
用户态和内核态的特权级不同,因此可以通过特全级判断当前处于用户态还是内核态。
cpu只有通过“门结构”才能由低特权级转移到高特权级
2. 计算机开始运行阶段就有中断吗?XV6 的中断管理是如何初始化的?XV6 是如何实现内 核态到用户态的转变的?XV6 中的硬件中断是如何开关的?实际的计算机里,中断有哪几种?
问题一:
有中断
在xv6中中断为cli和sti
其中汇编语言有BIOS自带的cli和sti,另外在x86.h中有
static inline void
cli(void)
{
asm volatile("cli");
}
static inline void
sti(void)
{
asm volatile("sti");
}
可以在汇编层面调用cli和sti,相当于给.c其他文件提供一个封装的接口函数
问题二:
首先中断需要初始化中断描述符表等初始化操作,所以一开始还没有进行需要关闭中断,在bootasm.S:关闭中断
代码为: cli # BIOS enabled interrupts; disable
之后在main,c初始化一系列中断机制
main(void)
{ kvmalloc(); // kernel page table内核页表
mpinit(); // collect info about this machine
lapicinit();
seginit(); // set up segments
cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
picinit(); // interrupt controller 初始化中断控制器
ioapicinit(); // another interrupt controller初始化中断控制器
consoleinit(); // I/O devices & their interruptsIO中断
uartinit(); // serial port设备端口中断
pinit();