本文介绍了抢占和上下文切换之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 一个小介绍, 我目前正在撰写一个小型(读取微小的)RTOS内核,它应该是内核中大部分内容的整体。然而,我找不到关于下面列出的几件事情的很多信息,这将是一个很大的帮助,除此之外,实际上并不是某种大学项目,而是我自己做的事情。 回答所有问题的一个更好的选择是,如果您可以参考我自由的RTOS(甚至免费的书),最好是用户空间是可抢占的(但不像linux那样复杂)。 Linux有一些我迄今为止看到的最糟糕的文档(我尝试从linux代码中找到东西,但是只有大量的定义分散在一百万个文件和功能钩子中,并且每个版本都被重命名,有时候移动...) 抢占和上下文切换有什么区别? / li> 抢先和非抢占内核之间的关键区别是什么?程序员需要什么工作才能使内核抢占? 如何创建和使用用户模式? ARM文档说,在用户模式下,切换到特权模式的任何指令都将被视为未定义的指令。 如果是这样,用户空间程序使用内核代码的唯一方法是系统调用? 那么内核如何响应或与用户空间交互? 这是否意味着启动后(在简单的系统中)将是空闲线程的唯一内核线程? 如果内核代码和数据所在的页面在切换到用户进程时被取消映射,那么在系统调用或中断时,内核代码如何执行而不映射到虚拟地址空间? 可抢占内核是否意味着内核的设计方式是在执行内核代码期间进行上下文切换是安全的?或者是否需要更多的工作? 哦,如果这里不允许这么多的问题,对不起,找不到任何东西。解决方案 As Mat写道,这可能是无理的范围。不过,我会尽量多的关注问题的总和,因为我会对一个合理范围的问题,希望这将有助于您开始研究。抢占是中断一个进程而不涉及的行为。在这种情况下,这可能意味着定时器中断将触发。该词源于抢先使用的法律概念:声明或采购的行为或权利在您或其他人之前或之前。为了您的目的,这意味着当定时器中断触发时,中断服务程序(ISR)优先于先前运行的代码。这不一定需要涉及一个内核;您可以在任何可以抢先运行的ISR中运行代码。 上下文切换是当OS代码(先前运行)更改处理器的状态时发生的情况寄存器,模式和堆栈)在一个进程或线程的上下文之间。处理器的状态可能在一个线程中处于某一行代码。它将具有寄存器中的临时数据,存储器某一特定区域的堆栈指针和其他状态信息。抢占式操作系统可以将此状态(静态内存或进程堆栈)存储起来并加载先前进程的状态。这被称为上下文切换。在抢先的内核中,中断可以在任何两个汇编指令(称为序列点)。在非抢占式内核中,正在运行的进程必须调用一个 yield()函数来允许其他线程运行。抢先内核更复杂,但提供了更好的并发错觉。非预制内核可以非常简单地使用 setjmp.h 完成,但每个线程必须定期调用 yield()或其他线程将不会运行。 当调用类似 yield()的函数时,会自动存储处理器的状态。当您想要使您的操作系统抢占时,您必须手动存储此信息。正确。但是,他们也说任何中断都将以特权模式自动运行。在ARM系统中,您可以使用 svc 指令来生成软件中断。 SVC代码(您的操作系统的一部分)将能够以特权模式运行。正确。至少这是唯一安全或正确的方法。在ARM上,SVC指令可以获得8位值。这可以用于生成256个系统调用,如收益率,启用中断,禁止中断或任何您需要的。您还可以选择创建共享内存或消息传递交互机制(如果需要)。这完全取决于您如何设计系统。如果您选择仅在所有线程创建之后才选择启动内核,那么这种方式可能更简单 - 这样就不需要担心动态分配线程。或者,您可以从空闲线程开始,稍后再添加其他线程(通过远程shell?我想您至少需要一个用户线程一直运行...) 7如果内核代码和数据所在的页面在切换到用户进程时未映射,则在系统调用或中断时,内核代码如何在虚拟地址空间中映射而不执行? 正如内核模式代码以特权模式运行,即使代码以前在用户模式下执行,内核模式代码也将从即使进程代码使用不同的地址空间,也是主堆栈指针(MSP)。我认为这意味着内核可以抢占用户代码,而不是内核本身可以被抢占。任何东西中断内核将是困难和不寻常的。这将需要更多的工作,我正在努力地看到你想要的原因。 A little intro,I am currently writing a small (read tiny) RTOS kernel, well it's supposed to be monolithic with most stuff in the kernel. However I can't find much information on a few things listed below, It would be a lot helpful and besides this, it isn't actually some kind of university project but something I'm doing at my own will.A better alternative to answering all the questions would be if you could refer to me a freely available RTOS (or even a free book) for arm preferably which implement userspace and are preemptible (but not complex like linux). Linux has some of the worst documentation I've seen till now (I did try figuring things out from linux code but there are just a tons of defines scattered through a million files and function hooks with wierd names and stuff getting renamed every version also getting moved sometimes...)What is the difference between "preemption" and "context switch" ?What are the key differences between a preemptive and nonpreemptive kernel ? What all work is required from a programmer to make the kernel preemptive ?How to create and work with user mode ?ARM docs say that in user mode, any instruction switching to a privileged mode will be treated as undefined instruction.If so, the only way for a userspace program to use kernel code is syscalls ?How does a kernel respond or interact with userspace then ?Does that mean the only kernel thread after booting (in a simple system) would be the idle thread ?If the Page where kernel code and data resides is unmapped when switching to a user process, then on a syscall or interrupt, how does the kernel code execute without being mapped in the virtual address space ?Does a 'preemptible kernel' only mean that the kernel was designed in a way that it would be safe to have context switch during execution of kernel code ? or does it require more work to be done if any ?Oh and if such multiple questions are not allowed here, sorry, couldn't find anything about that. 解决方案 As Mat wrote, this is probably unreasonably scoped. However, I'll try to devote as much attention to the sum of the questions as I would to one reasonably scoped question, in the hopes that this will help you to begin researching.Preemption is the act of interrupting a process without its involvement. In this context, that probably means a timer interrupt will fire. The word comes from a legal concept of preemption: the act or right of claiming or purchasing before or in preference to others. For your purposes, that means that when the timer interrupt fires, that the interrupt service routine (ISR) has preference over the code which was previously running. This doesn't necessarily need to involve a kernel at all; you can have code running in any ISR which will run preemptively.A context switch is what happens when the OS code (running preemptively) alters the state of the processor (the registers, mode, and stack) between one process or thread's context and another. The state of the processor may be at a certain line of code in a one thread. It will have temporary data in registers, a stack pointer at a certain region of memory, and other state information. A preemptive OS can store this state (either to static memory or onto the processes' stack) and load the state of a previous process. This is known as a context switch.In a preemptive kernel, an interrupt can fire in between any two assembly instructions (known as 'sequence points'). In a non-preemptive kernel, the running process must call a yield() function to allow the other threads to run. Preemptive kernels are more complex, but provide a better illusion of concurrency. Non-premptive kernels can be done very simply with setjmp.h, but each thread must regularly call yield() or the other threads will not run.When a function like yield() is called, the state of the processor is stored automatically. When you want to make your OS preemptive, you must store this information manually.Correct. However, they also say that any interrupt will run in privileged mode automatically. On an ARM system, you can use the svc instruction to generate a software interrupt. The SVC code (part of your OS) will then be able to run in privileged mode.Correct. At least, this is the only safe or correct way.On ARM, the SVC instruction can get an 8-bit value. This can be used to generate 256 syscalls such as yield, enable interrupts, disable interrupts, or whatever you need. You may also choose to create a shared memory or message passing interaction mechanism if you need that.That depends entirely on how you design your system. It's probably simpler if you choose to start your kernel only after all your threads have been created - that way you don't need to worry about dynamically allocating threads. Or, you can start with the idle thread and add other threads later (through a remote shell? I think you'd want at least one user thread running consistently...)Just as kernel mode code runs in privileged mode even if the code was previously executing in user mode, so will kernel mode code run from the main stack pointer (MSP) even if the process code was using a different address space.I think that means that the kernel can preempt the user code, not that the kernel itself can be preempted. It would be difficult and unusual for anything to interrupt the kernel. That would require more work, and I'm struggling to see why you'd want it. 这篇关于抢占和上下文切换之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 09-01 21:06