<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.jackslab.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn">
		<id>http://wiki.jackslab.org/index.php?action=history&amp;feed=atom&amp;title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0</id>
		<title>MIPS Linux 上下文切换分析笔记 - 版本历史</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.jackslab.org/index.php?action=history&amp;feed=atom&amp;title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0"/>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;action=history"/>
		<updated>2026-05-21T09:32:02Z</updated>
		<subtitle>本wiki的该页面的版本历史</subtitle>
		<generator>MediaWiki 1.19.2</generator>

	<entry>
		<id>http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18627&amp;oldid=prev</id>
		<title>2025年12月10日 (三) 06:23 Comcat</title>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18627&amp;oldid=prev"/>
				<updated>2025-12-10T06:23:03Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←上一版本&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;2025年12月10日 (三) 06:23的版本&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第78行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第78行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;当一个进程 A 因为中断被打断时，中断处理程序会使用 A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A 的内核栈，因此中断应该尽可能快的结束。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;当一个进程 A 因为中断被打断时，中断处理程序会使用 A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A 的内核栈，因此中断应该尽可能快的结束。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;如果 do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;如果 do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Comcat</name></author>	</entry>

	<entry>
		<id>http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18626&amp;oldid=prev</id>
		<title>2025年12月10日 (三) 06:22 Comcat</title>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18626&amp;oldid=prev"/>
				<updated>2025-12-10T06:22:46Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←上一版本&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;2025年12月10日 (三) 06:22的版本&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第77行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第77行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Linux 设计中，中断处理时不能睡眠，这个内核中有很多保护措施，一旦检测到内核会异常&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Linux 设计中，中断处理时不能睡眠，这个内核中有很多保护措施，一旦检测到内核会异常&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;当一个进程 A 因为中断被打断时，中断处理程序会使用 A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;的内核栈，因此中断应该尽可能快的结束。如果 &lt;/del&gt;do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;当一个进程 A 因为中断被打断时，中断处理程序会使用 A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;的内核栈，因此中断应该尽可能快的结束。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;如果 &lt;/ins&gt;do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如其是在睡眠时被时钟中断打断，并 schedule 的话，假如选中了进程 A，并 switch_to 过去，时钟中断返回后则又是位于原中断睡眠时的状态，抛开其扰乱了与其无关的进程A的运行不说，这里的问题就是：该如何唤醒之呢？？&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如其是在睡眠时被时钟中断打断，并 schedule 的话，假如选中了进程 A，并 switch_to 过去，时钟中断返回后则又是位于原中断睡眠时的状态，抛开其扰乱了与其无关的进程A的运行不说，这里的问题就是：该如何唤醒之呢？？&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Comcat</name></author>	</entry>

	<entry>
		<id>http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18616&amp;oldid=prev</id>
		<title>2025年12月10日 (三) 03:35 Comcat</title>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=18616&amp;oldid=prev"/>
				<updated>2025-12-10T03:35:46Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←上一版本&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;2025年12月10日 (三) 03:35的版本&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第84行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第84行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Comcat</name></author>	</entry>

	<entry>
		<id>http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=3071&amp;oldid=prev</id>
		<title>2014年11月10日 (一) 23:47 Comcat</title>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=3071&amp;oldid=prev"/>
				<updated>2014-11-10T23:47:56Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←上一版本&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;2014年11月10日 (一) 23:47的版本&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;1. 内核栈切换 &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(MIPS)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;1. 内核栈切换&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;调度切换至一个进程时，根据 task_struct-&amp;gt;thread_info 的值设置 *&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;kernelsp（当前正在运行进程之内核栈栈底），其值为 thread_info + THREAD_SIZE - 32（MIPS 下，使用 set_saved_sp 宏）。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;调度切换至一个进程时，根据 task_struct-&amp;gt;thread_info 的值设置 *&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;kernelsp（当前正在运行进程之内核栈栈底），其值为：&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;#160; thread_info + THREAD_SIZE - 32（MIPS 下，使用 set_saved_sp 宏）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;;;2. 异常、中断寄存器的保存 (MIPS)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;使 用SAVE_SOME 保存上下文时，如发现从用户态切入核心态，则首先用 get_saved_sp 宏，将*kernelsp 置入sp。然后在内核栈上分配 PT_SIZE（=sizeof(struct pt_regs)） 大小的空间，作为上下文的保存空间。保存时所有数据精心组织，最后就是一个 struct pt_regs 结构。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;;;2. 异常、中断寄存器的保存&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;若是用户态 --&amp;gt; 内核态，则 k0 = sp, sp = &lt;/del&gt;*kernelsp &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;- PT_SIZE，store k0, PT_R29&lt;/del&gt;(&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;sp&lt;/del&gt;)&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;，保存其它寄存器。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;使用 SAVE_SOME 保存上下文时，如发现从用户态切入核心态，则首先用 get_saved_sp 宏，将 &lt;/ins&gt;*kernelsp &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;置入sp。然后在内核栈上分配 PT_SIZE=sizeof&lt;/ins&gt;(&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;struct pt_regs&lt;/ins&gt;)&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;） 大小的空间，作为上下文的保存空间。保存时所有数据精心组织，最后就是一个 struct pt_regs 结构&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;若是内核态 &lt;/del&gt;--&amp;gt; &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;内核态，直接 &lt;/del&gt;k0 = sp, sp = &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;sp &lt;/del&gt;- PT_SIZE，store k0, PT_R29(sp)&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;，然后保存其它寄存器。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;若是用户态 &lt;/ins&gt;--&amp;gt; &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;内核态，则 &lt;/ins&gt;k0 = sp, sp = &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;*kernelsp &lt;/ins&gt;- PT_SIZE，store k0, PT_R29(sp)&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;，保存其它寄存器&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;若是内核态 --&amp;gt; 内核态，直接 k0 = sp, sp = sp - PT_SIZE，store k0, PT_R29(sp)，然后保存其它寄存器&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;;;3. 任务切换上下文的保存 (MIPS)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;时钟中断后使用 SAVE_SOME 在内核栈/用户栈（取决于当时所在模式）上保存 $0, $2, $3, $4~$7, $8~$9(64bit), $25, $28, $29, $31, STATUS, CAUSE, &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;EPC。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;;;3. 任务切换上下文的保存&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;时钟中断后使用 SAVE_SOME 在内核栈/用户栈（取决于当时所在模式）上保存 $0, $2, $3, $4~$7, $8~$9(64bit), $25, $28, $29, $31, STATUS, CAUSE, &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;EPC&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;后在 switch_to 中保存正在运行任务的上下文：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;后在 switch_to 中保存正在运行任务的上下文：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;保 存 &lt;/del&gt;STATUS，使用 cpu_save_nonscratch 保存$16~$23, $29(sp), $30，以及 $31, 有FPU还要 fpu_save_double 保存FPU的寄存器。所有都保存于thread_struct 结构中，该结构为 task_struct &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;的一部分。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;保存 &lt;/ins&gt;STATUS，使用 cpu_save_nonscratch 保存 $16~$23, $29(sp), $30，以及 $31, 有FPU还要 fpu_save_double 保存FPU的寄存器。所有都保存于thread_struct 结构中，该结构为 task_struct &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;的一部分&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;这些保存的是 switch_to 前后的上下文&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;这些保存的是 switch_to 前后的上下文&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第26行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第30行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;然后将将要运行的任务上下文加载：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;然后将将要运行的任务上下文加载：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;source lan=bash&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;$28 &amp;lt;---- &amp;amp;thread_info&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;$28 &amp;lt;---- &amp;amp;thread_info&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;cpu_restore_nonscratch 恢复 $16~$23, $29(sp), $30&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;cpu_restore_nonscratch 恢复 $16~$23, $29(sp), $30&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;*(kernelsp) &amp;lt;---- &amp;amp;thread_info + THREAD_SIZE - 32&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;*(kernelsp) &amp;lt;---- &amp;amp;thread_info + THREAD_SIZE - 32&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;恢复 thread_struct 中保存的 STATUS（bit 0, bit 8~15 用当前STATUS值替换）&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;恢复 thread_struct 中保存的 STATUS（bit 0, bit 8~15 用当前STATUS值替换）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/source&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;现在恢复时也在 switch_to &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;前后，神不知鬼不觉的替换了，所有操作都是由switch_to调用叶函数resume完成。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;现在恢复时也在 switch_to &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;前后，神不知鬼不觉的替换了，所有操作都是由switch_to调用叶函数resume完成&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;do_IRQ 返回后，sp恢复（减多少，对称的加多少，因此与初值无关，最终指向新进程的 pt_regs 结构）ref_from_irq 则时钟中断返回（当时被中断时的环境），然后 eret 跳回到用户态（或者被时钟中断的核心态）继续运行。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;do_IRQ 返回后，sp恢复（减多少，对称的加多少，因此与初值无关，最终指向新进程的 pt_regs 结构）ref_from_irq 则时钟中断返回（当时被中断时的环境），然后 eret 跳回到用户态（或者被时钟中断的核心态）继续运行。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;4. switch_to 为何不需保存$0~$15 $24~$27 &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(MIPS)&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;4. switch_to 为何不需保存 $0~$15 $24~$27&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如内核要从进程A切换到进程B，流程大概是这样：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如内核要从进程A切换到进程B，流程大概是这样：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;pre&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;进程A --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to(resume) --&amp;gt; schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;进程A --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to(resume) --&amp;gt; schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/pre&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;switch_to 保存于 A task_struct-&amp;gt;thread_struct 中的状态是整个调用链中的 switch_to 宏附近的处理器状态&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;switch_to 保存于 A task_struct-&amp;gt;thread_struct 中的状态是整个调用链中的 switch_to 宏附近的处理器状态&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第46行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第56行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;因此将 sp 指向保存于 B task_struct-&amp;gt;thread_struct 中的 sp 时，实际上就相当于恢复到当时进程B在switch_to前后的状态：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;因此将 sp 指向保存于 B task_struct-&amp;gt;thread_struct 中的 sp 时，实际上就相当于恢复到当时进程B在switch_to前后的状态：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;进程B --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;#160; &lt;/ins&gt;进程B --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;switch_to 是一个宏，其中调用了，位于 arch/mips/kernel/r4k_switch.S 中的一个叶函数（不改变静态寄存器的值，不用压栈、出栈）resume，因此进入 resume 前，ABI 规定的一些非静态寄存器的值就再也不用了，故这些非静态值无需保存。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;switch_to 是一个宏，其中调用了，位于 arch/mips/kernel/r4k_switch.S 中的一个叶函数（不改变静态寄存器的值，不用压栈、出栈）resume，因此进入 resume 前，ABI 规定的一些非静态寄存器的值就再也不用了，故这些非静态值无需保存。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;至于静态寄存器的值，函数用之前都会保存于栈上，最后恢复之，子函数调用不会改变其值。因此静态寄存器保存的是当时运行状态的一部分。如这种情况：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;至于静态寄存器的值，函数用之前都会保存于栈上，最后恢复之，子函数调用不会改变其值。因此静态寄存器保存的是当时运行状态的一部分。如这种情况：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;schedule 中编译器用 s0 保存一个重要的状态变量，因此进入schedule首先保存s0的值，使用 s0 参与运算，switch_to 后，又要根据 s0 判断进一步的动作。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;#160; &lt;/ins&gt;schedule 中编译器用 s0 保存一个重要的状态变量，因此进入schedule首先保存s0的值，使用 s0 参与运算，switch_to 后，又要根据 s0 判断进一步的动作。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;这个时候就要将 s0 恢复为进程B当时在此点的值。总之注意，switch_to 后所有操作延续的是进程B的：&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;这个时候就要将 s0 恢复为进程B当时在此点的值。总之注意，switch_to 后所有操作延续的是进程B的：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;#160; &lt;/ins&gt;schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;5. 中断处理时可否睡眠问题&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;;5. 中断处理时可否睡眠问题&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Linux &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;设计中，中断处理时不能睡眠，这个内核中有很多保护措施，一旦检测到内核会异常。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Linux &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;设计中，中断处理时不能睡眠，这个内核中有很多保护措施，一旦检测到内核会异常&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;当 一个进程A因为中断被打断时，中断处理程序会使用 &lt;/del&gt;A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A 的内核栈，因此中断应该尽可能快的结束。如果 do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;当一个进程 A 因为中断被打断时，中断处理程序会使用 &lt;/ins&gt;A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A 的内核栈，因此中断应该尽可能快的结束。如果 do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如其是在睡眠时被时钟中断打断，并 schedule 的话，假如选中了进程 A，并 switch_to 过去，时钟中断返回后则又是位于原中断睡眠时的状态，抛开其扰乱了与其无关的进程A的运行不说，这里的问题就是：该如何唤醒之呢？？&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;假如其是在睡眠时被时钟中断打断，并 schedule 的话，假如选中了进程 A，并 switch_to 过去，时钟中断返回后则又是位于原中断睡眠时的状态，抛开其扰乱了与其无关的进程A的运行不说，这里的问题就是：该如何唤醒之呢？？&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Comcat</name></author>	</entry>

	<entry>
		<id>http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=3070&amp;oldid=prev</id>
		<title>Comcat：以“;;1. 内核栈切换 (MIPS)  调度切换至一个进程时，根据 task_struct-&gt;thread_info 的值设置 *kernelsp（当前正在运行进程之内核栈栈底）...”为内容创建页面</title>
		<link rel="alternate" type="text/html" href="http://wiki.jackslab.org/index.php?title=MIPS_Linux_%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2%E5%88%86%E6%9E%90%E7%AC%94%E8%AE%B0&amp;diff=3070&amp;oldid=prev"/>
				<updated>2014-11-10T23:44:27Z</updated>
		
		<summary type="html">&lt;p&gt;以“;;1. 内核栈切换 (MIPS)  调度切换至一个进程时，根据 task_struct-&amp;gt;thread_info 的值设置 *kernelsp（当前正在运行进程之内核栈栈底）...”为内容创建页面&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;;;1. 内核栈切换 (MIPS)&lt;br /&gt;
&lt;br /&gt;
调度切换至一个进程时，根据 task_struct-&amp;gt;thread_info 的值设置 *kernelsp（当前正在运行进程之内核栈栈底），其值为 thread_info + THREAD_SIZE - 32（MIPS 下，使用 set_saved_sp 宏）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;;2. 异常、中断寄存器的保存 (MIPS)&lt;br /&gt;
&lt;br /&gt;
使 用SAVE_SOME 保存上下文时，如发现从用户态切入核心态，则首先用 get_saved_sp 宏，将*kernelsp 置入sp。然后在内核栈上分配 PT_SIZE（=sizeof(struct pt_regs)） 大小的空间，作为上下文的保存空间。保存时所有数据精心组织，最后就是一个 struct pt_regs 结构。&lt;br /&gt;
&lt;br /&gt;
若是用户态 --&amp;gt; 内核态，则 k0 = sp, sp = *kernelsp - PT_SIZE，store k0, PT_R29(sp)，保存其它寄存器。&lt;br /&gt;
&lt;br /&gt;
若是内核态 --&amp;gt; 内核态，直接 k0 = sp, sp = sp - PT_SIZE，store k0, PT_R29(sp)，然后保存其它寄存器。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;;3. 任务切换上下文的保存 (MIPS)&lt;br /&gt;
&lt;br /&gt;
时钟中断后使用 SAVE_SOME 在内核栈/用户栈（取决于当时所在模式）上保存 $0, $2, $3, $4~$7, $8~$9(64bit), $25, $28, $29, $31, STATUS, CAUSE, EPC。&lt;br /&gt;
&lt;br /&gt;
后在 switch_to 中保存正在运行任务的上下文：&lt;br /&gt;
&lt;br /&gt;
保 存 STATUS，使用 cpu_save_nonscratch 保存$16~$23, $29(sp), $30，以及 $31, 有FPU还要 fpu_save_double 保存FPU的寄存器。所有都保存于thread_struct 结构中，该结构为 task_struct 的一部分。&lt;br /&gt;
&lt;br /&gt;
这些保存的是 switch_to 前后的上下文&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
然后将将要运行的任务上下文加载：&lt;br /&gt;
&lt;br /&gt;
$28 &amp;lt;---- &amp;amp;thread_info&lt;br /&gt;
cpu_restore_nonscratch 恢复 $16~$23, $29(sp), $30&lt;br /&gt;
*(kernelsp) &amp;lt;---- &amp;amp;thread_info + THREAD_SIZE - 32&lt;br /&gt;
恢复 thread_struct 中保存的 STATUS（bit 0, bit 8~15 用当前STATUS值替换）&lt;br /&gt;
&lt;br /&gt;
现在恢复时也在 switch_to 前后，神不知鬼不觉的替换了，所有操作都是由switch_to调用叶函数resume完成。&lt;br /&gt;
&lt;br /&gt;
do_IRQ 返回后，sp恢复（减多少，对称的加多少，因此与初值无关，最终指向新进程的 pt_regs 结构）ref_from_irq 则时钟中断返回（当时被中断时的环境），然后 eret 跳回到用户态（或者被时钟中断的核心态）继续运行。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;;4. switch_to 为何不需保存$0~$15 $24~$27 (MIPS)&lt;br /&gt;
&lt;br /&gt;
假如内核要从进程A切换到进程B，流程大概是这样：&lt;br /&gt;
&lt;br /&gt;
进程A --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to(resume) --&amp;gt; schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B&lt;br /&gt;
&lt;br /&gt;
switch_to 保存于 A task_struct-&amp;gt;thread_struct 中的状态是整个调用链中的 switch_to 宏附近的处理器状态&lt;br /&gt;
&lt;br /&gt;
因此将 sp 指向保存于 B task_struct-&amp;gt;thread_struct 中的 sp 时，实际上就相当于恢复到当时进程B在switch_to前后的状态：&lt;br /&gt;
&lt;br /&gt;
进程B --&amp;gt; 时钟中断 --&amp;gt; schedule --&amp;gt; switch_to &lt;br /&gt;
&lt;br /&gt;
switch_to 是一个宏，其中调用了，位于 arch/mips/kernel/r4k_switch.S 中的一个叶函数（不改变静态寄存器的值，不用压栈、出栈）resume，因此进入 resume 前，ABI 规定的一些非静态寄存器的值就再也不用了，故这些非静态值无需保存。&lt;br /&gt;
&lt;br /&gt;
至于静态寄存器的值，函数用之前都会保存于栈上，最后恢复之，子函数调用不会改变其值。因此静态寄存器保存的是当时运行状态的一部分。如这种情况：&lt;br /&gt;
&lt;br /&gt;
schedule 中编译器用 s0 保存一个重要的状态变量，因此进入schedule首先保存s0的值，使用 s0 参与运算，switch_to 后，又要根据 s0 判断进一步的动作。&lt;br /&gt;
&lt;br /&gt;
这个时候就要将 s0 恢复为进程B当时在此点的值。总之注意，switch_to 后所有操作延续的是进程B的：&lt;br /&gt;
&lt;br /&gt;
schedule 返回 --&amp;gt; ret_from_irq --&amp;gt; 进程B &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;;5. 中断处理时可否睡眠问题&lt;br /&gt;
&lt;br /&gt;
Linux 设计中，中断处理时不能睡眠，这个内核中有很多保护措施，一旦检测到内核会异常。&lt;br /&gt;
&lt;br /&gt;
当 一个进程A因为中断被打断时，中断处理程序会使用 A 的内核栈来保存上下文，因为是“抢”的 A 的CPU，而且用了 A 的内核栈，因此中断应该尽可能快的结束。如果 do_IRQ 时又被时钟中断打断，则继续在 A 的内核栈上保存中断上下文，如果发生调度，则 schedule 进 switch_to，又会在 A 的 task_struct-&amp;gt;thread_struct 里保存此时时种中断的上下文。&lt;br /&gt;
&lt;br /&gt;
假如其是在睡眠时被时钟中断打断，并 schedule 的话，假如选中了进程 A，并 switch_to 过去，时钟中断返回后则又是位于原中断睡眠时的状态，抛开其扰乱了与其无关的进程A的运行不说，这里的问题就是：该如何唤醒之呢？？&lt;br /&gt;
&lt;br /&gt;
另外，和该中断共享中断号的中断也会受到影响。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Comcat</name></author>	</entry>

	</feed>