正如Mat所写,这可能是一个范围过于宽泛的问题。但我会尽可能关注所有问题的总和,就像对一个范围合理的问题一样,希望这可以帮助你开始研究。
1 “抢占”与“上下文切换”的区别是什么?
抢占是指在不涉及进程参与的情况下中断一个进程的行为。在这个上下文中,这可能意味着定时器中断将触发。该词源于法律概念中的preemption: 优先或优先于他人声明或购买的行为或权利。 对于您的目的而言,这意味着当定时器中断触发时,中断服务例程(ISR)比之前运行的代码具有优先权。这不一定需要涉及内核;您可以在任何ISR中运行代码以实现抢占式运行。
当操作系统代码(以抢占方式运行)在一个进程或线程的上下文与另一个进程或线程的上下文之间更改处理器的状态(寄存器,模式和堆栈)时,就会发生上下文切换。处理器的状态可能是在一个线程的某个代码行。它将在寄存器中具有临时数据,在内存的某个区域具有堆栈指针和其他状态信息。抢占式操作系统可以将该状态(存储到静态内存或进程的堆栈上)并加载以前进程的状态,这称为上下文切换。
2 抢占式内核和非抢占式内核的主要区别是什么?程序员需要做哪些工作才能使内核具有抢占式特性?
在抢占式内核中,中断可以在任意两个汇编指令之间触发(称为“序列点”)。在非抢占式内核中,正在运行的进程必须调用
yield()
函数才能让其他线程运行。抢占式内核更复杂,但提供更好的并发Illusion。使用
setjmp.h
可以非常简单地实现非抢占式内核,但是每个线程必须定期调用
yield()
,否则其他线程将无法运行。
当调用像
yield()
这样的函数时,处理器状态会自动存储。要使操作系统具有抢占性,必须手动存储此信息。
ARM文档表示,在用户模式下,任何切换到特权模式的指令都将被视为未定义指令。然而,他们也说,任何中断都会自动以特权模式运行。在ARM系统上,您可以使用
svc
指令生成软件中断。然后,SVC代码(您的操作系统的一部分)将能够以特权模式运行。
正确。至少,这是唯一的安全或正确的方法。
在ARM上,SVC指令可以获得8位值。这可以用于生成256个系统调用,例如yield、启用中断、禁用中断或任何您需要的内容。如果需要,您还可以选择创建共享内存或消息传递交互机制。
是的,这意味着在启动后(在简单系统中),唯一的内核线程将是空闲线程吗?
这完全取决于您设计系统的方式。如果您选择在创建所有线程后才启动内核,那么这可能更简单 - 这样您就不需要担心动态分配线程。或者,您可以从空闲线程开始,稍后再添加其他线程(通过远程 shell 吗?我认为您至少需要一个用户线程一直运行...)
7 如果内核代码和数据所在的页面在切换到用户进程时未映射,则在系统调用或中断时,内核代码如何在未映射到虚拟地址空间的情况下执行?
就像内核模式代码在特权模式下运行一样,即使该代码先前在用户模式下执行,内核模式代码也将从主堆栈指针 (MSP) 运行,即使进程代码使用了不同的地址空间。
8 '可抢占内核' 是否仅意味着内核被设计成在内核代码执行期间进行上下文切换是安全的?还是需要做更多的工作?
我认为这意味着内核可以抢占用户代码,而不是内核本身可以被抢占。任何东西要打断内核都很困难和不寻常。这需要更多的工作,我很难想象为什么您会需要这样做。