Architecture 抢占和上下文切换的区别

Architecture 抢占和上下文切换的区别,architecture,kernel,arm,rtos,Architecture,Kernel,Arm,Rtos,一点介绍 我目前正在编写一个小型(read tiny)RTOS内核,它应该是单片的,包含内核中的大部分内容。然而,我在下面列出的几件事情上找不到太多的信息,这将是非常有帮助的,除此之外,这实际上不是某种大学项目,而是我自己自愿做的事情 如果您能向我推荐一本arm的免费RTO(甚至是一本免费的书),这是回答所有问题的更好的选择,最好是实现用户空间并可抢占(但不像linux那样复杂)。到目前为止,Linux有一些我见过的最糟糕的文档(我确实尝试过从Linux代码中找出一些东西,但只有大量的定义散布在

一点介绍

我目前正在编写一个小型(read tiny)RTOS内核,它应该是单片的,包含内核中的大部分内容。然而,我在下面列出的几件事情上找不到太多的信息,这将是非常有帮助的,除此之外,这实际上不是某种大学项目,而是我自己自愿做的事情

如果您能向我推荐一本arm的免费RTO(甚至是一本免费的书),这是回答所有问题的更好的选择,最好是实现用户空间并可抢占(但不像linux那样复杂)。到目前为止,Linux有一些我见过的最糟糕的文档(我确实尝试过从Linux代码中找出一些东西,但只有大量的定义散布在一百万个文件和函数挂钩中,其中包含wierd名称和被重命名的内容,每个版本有时也会被移动…)

  • “抢占”和“上下文切换”之间有什么区别

  • 抢占式和非抢占式内核之间的关键区别是什么?程序员需要做哪些工作才能使内核先发制人

  • 如何创建和使用用户模式

    ARM文档表示,在用户模式下,任何切换到特权模式的指令都将被视为未定义指令

  • 如果是这样,用户空间程序使用内核代码的唯一方法是系统调用

  • 那么内核如何响应或与用户空间交互呢

  • 这是否意味着引导后(在简单系统中)唯一的内核线程将是空闲线程

  • 如果在切换到用户进程时内核代码和数据所在的页面未映射,那么在系统调用或中断时,内核代码如何执行而不映射到虚拟地址空间

  • “可抢占内核”是否仅仅意味着内核的设计方式是在内核代码执行期间进行上下文切换是安全的?或者需要做更多的工作吗


  • 哦,如果这里不允许这样多的问题,很抱歉,我找不到任何相关信息。

    正如Mat所写,这可能是不合理的范围。然而,我会尽可能多地关注这些问题的总和,就像关注一个范围合理的问题一样,希望这能帮助你们开始研究

    1“抢占”和“上下文切换”之间有什么区别

    先发制人是指在不涉及过程的情况下中断过程的行为。在这种情况下,这可能意味着将触发计时器中断。这个词来自一个法律概念:在他人之前或优先于他人主张或购买的行为或权利。出于您的目的,这意味着当定时器中断触发时,中断服务例程(ISR)优先于先前运行的代码。这根本不需要涉及内核;您可以让代码在任何将抢先运行的ISR中运行

    上下文切换是当操作系统代码(以抢占方式运行)在一个进程或线程的上下文和另一个进程或线程的上下文之间改变处理器状态(寄存器、模式和堆栈)时发生的切换。处理器的状态可能在一个线程中的某一行代码处。它将在寄存器中包含临时数据、内存特定区域的堆栈指针以及其他状态信息。抢占式操作系统可以存储此状态(到静态内存或进程堆栈),并加载前一个进程的状态。这称为上下文切换

    2抢占式和非抢占式内核之间的主要区别是什么?程序员需要做哪些工作才能使内核先发制人

    在抢占式内核中,中断可以在任意两条汇编指令之间触发(称为“序列点”)。在非抢占式内核中,运行的进程必须调用
    yield()
    函数以允许其他线程运行。抢占式内核更复杂,但提供了更好的并发性假象。使用
    setjmp.h
    可以非常简单地完成非前置内核,但是每个线程必须定期调用
    yield()
    ,否则其他线程将无法运行

    当调用像
    yield()
    这样的函数时,处理器的状态会自动存储。当你想让你的操作系统先发制人时,你必须手动存储这些信息

    3如何创建和使用用户模式

    ARM文档表示,在用户模式下,任何切换到特权模式的指令都将被视为未定义指令

    对。然而,他们也说任何中断都会自动在特权模式下运行。在ARM系统上,您可以使用
    svc
    指令生成软件中断。SVC代码(操作系统的一部分)将能够在特权模式下运行

    4如果是这样,用户空间程序使用内核代码的唯一方法是系统调用

    对。至少,这是唯一安全或正确的方法

    5那么内核如何响应用户空间或与用户空间交互

    在ARM上,SVC指令可以获得8位值。这可用于生成256个系统调用,如yield、enable interrupts、disable interrupts或您需要的任何东西。如果需要,您还可以选择创建共享内存或消息传递交互机制

    6这是否意味着引导后(在一个简单的系统中)唯一的内核线程将是空闲线程

    这完全取决于你如何设计你的系统。如果您选择在创建完所有线程后才启动内核,可能会更简单——这样您就不必担心动态分配线程了。或者,您可以从空闲线程开始,然后添加其他线程(通过远程shell?我认为您希望至少有一个用户线程一致地运行…)