Browse Source

Merge branch 'main' of github.com:sunym1993/flash-linux0.11-talk into main

pull/68/head
sunyiming 3 years ago
parent
commit
101a1d95ec
  1. 3
      .gitignore
  2. 97
      Intel 手册中文版/卷一:基本架构.md
  3. 6
      Intel 手册中文版/卷三:系统编程指南.md
  4. 43
      README.md
  5. BIN
      file1615.pdf
  6. BIN
      一些非必要的资料/x86汇编语言-从实模式到保护模式.pdf
  7. BIN
      一些非必要的资料/x86汇编语言_从实模式到保护模式(完整扫描版).pdf
  8. 149
      读者分享/Interrupt Table as Implemented by System BIOS
  9. 2
      读者分享/README.md
  10. BIN
      读者分享/file1615.pdf
  11. 69
      读者分享/linux调度算法解析 23回补充资料.md

3
.gitignore

@ -1 +1,2 @@
.idea/
.idea/
.DS_Store

97
Intel 手册中文版/卷一:基本架构.md

@ -532,12 +532,43 @@ CS , DS , SS 和 ES 这四个段寄存器与 Intel 8086 and Intel 286 处理器
@翻译人:符宇舟Alex
## 4.3 POINTER DATA TYPES
@翻译人:Colinxu2020
指针是指向内存中一个位置的地址。
在非64位模式下,该架构定义了两种类型的指针:近指针和远指针。一个近指针是一个段内的32位(或16位)偏移(也称为有效地址)。
近指针用于平坦的内存模型中的所有内存引用,或者用于分段内存模型中的引用,其中被访问段的基址是隐含的。
远指针是一个逻辑地址,由一个16位段选择器和一个32位(或16位)偏移量组成。远指针用于分段内存模型中的内存引用,其中被访问段的身份必须明确指定。
带有32位偏移量的近指针和远指针如图4-4所示
图4-4
### 4.3.1 Pointer Data Types in 64-Bit Mode
在64位模式(IA-32e 模式的一个子模式)中,一个近指针是64位。这等同于一个有效的地址。
64位模式下的远指针可以是三种形式之一。
- 16位段选择器,16位偏移,如果操作数是32位的话
- 16位段选择器,32位偏移,如果操作数是32位的话
- 如果操作数为64位,16位段选择器,64位偏移量
见图4-5
图4-5
## 4.4 BIT FIELD DATA TYPE
[@翻译人:Hola39e](https://github.com/Hola39e)
位域数据类型(见图4-6)是一个连续的比特序列。它可以从内存中任何字节的任何位开始,最多可以包含32位。
Figure 4-6 here
Figure 4-6 here
## 4.5 STRING DATA TYPES
[@翻译人:Hola39e](https://github.com/Hola39e)
@ -547,20 +578,22 @@ CS , DS , SS 和 ES 这四个段寄存器与 Intel 8086 and Intel 286 处理器
[@翻译人:Hola39e](https://github.com/Hola39e)
Intel64和IA-32架构定义与操作一组64位和128位包装(Packed)数据类型,中文又称数据向量,用于单指令多数据流(SIMD)操作。这些打包数据类型的由基本的数据类型(打包对齐的字节、字、双字和四字组成),以及用于进行矢量运算(Packed)指令操作的整数,浮点数基本类型的数值说明。
### 4.6.1 64-Bit SIMD Packed Data Types
[@翻译人:Hola39e](https://github.com/Hola39e)
64位包装(Packed)SIMD数据结构是在Intel MXX指令集中加入到IA-32中去的。它们在MXX寄存器中被操作。基本的64位包装数据类型是打包对齐起来的字节、字以及双字(见图4-7)。当执行SIMD操作时,这些数据结构会被解释成
进行矢量运算(Packed)指令操作的字节、字、双字长度的整数值。
Figure 4-7 here
Figure 4-7 here
### 4.6.2 128-Bit Packed SIMD Data Types
[@翻译人:Hola39e](https://github.com/Hola39e)
128位包装(Packed)SIMD数据结构是在SSE扩展指令集中被引入到IA-32中去的,在SSE2,SSE3,SSSE3扩展指令集中被使用。它们主要在128位的XMM寄存器和内存中进行操作,基本的128位包装数据类型是打包对齐起来的字节、字、双字、四字组成的(见图4-8)。当对在XMM寄存器中保存的包装(Packed)数据类型执行SIMD操作时,这些数据类型会被解释进行矢量运算(Packed)指令操作或标量运算(Scalar)指令操作的单精度浮点数或双精度浮点数,或者进行矢量运算(Packed)的长度为字节、字、双字、四字的整数值。
Figure 4-8 here
Figure 4-8 here
# 第五章 Instruction Set Summary
# 第六章 Procedure Calls, Interrupts, and Exceptions
@ -580,6 +613,64 @@ Intel64和IA-32架构定义与操作一组64位和128位包装(Packed)数据
### 6.4.1 Call and Return Operation for Interrupt or Exception Handling Procedures
@翻译人:si
6.4 使用CALL和RET指令调用程序 (CALLING PROCEDURES USING CALL AND RET)
注:procedures译为代码,program译为程序
  CALL 指令允许代码控制跳转到当前代码段(近调用 near call)和不同程序代码段(远调用 far call)。近调用通常在当前运行程序或任务中提供代码访问。远调用通常访问操作系统代码或不同任务中的代码。参见第三章的 ”CALL-Call Procedure“ 。在 *Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A*的“Instruction Set Reference, A-L” 中有对CALL指令更深层次的描述。
  RET 指令也允许近或远的返回以匹配进或远版本的 CALL 指令。另外,RET 指令允许程序在返回时递增栈指针来释放栈上的参数。具体要在栈上释放多少字节决定于 RET 指令上的可选参数(n)。在 *Intel® 64 and* *IA-32 Architectures Software Developer’s Manual, Volume 2B* 的 ”Instruction Set Reference, M-U“ 中有对 RET 指令更详细的介绍。
6.4.1 Near CALL and RET Operation
  当执行近调用时,处理器会做以下这些事情(参见图 6-2 )
1. 将 EIP 寄存器的当前值压到栈中。
如果影子栈(shadow stack)被启用而且置换值为非零,将 EIP 寄存器的当前值压入影子栈中。
2. 在 EIP 寄存器中加载被调用代码的偏移量。
3. 开始执行被调用的代码
当执行的近返回(near return)时,处理器会执行这些动作:
1. 弹出栈顶的值(返回指令指针)到 EIP 寄存器中。
如果影子栈被启用,从影子栈弹出栈顶值(返回指令指针)如果与从栈中弹出的指令指针不同,处理器会报一个控制保护异常,错误码为NEAR-RET(#CP(NEAR-RET))。
2. 如果 RET 指令有一个可选的 n 参数,按 n 操作数指定的字节数递增栈指针以从栈中释放参数 。
3. 恢复调用代码的运行。
6.4.2 Far CALL and RET Operation
  当执行远调用时,处理器会执行这些动作(见图6-2):
1. 将 CS 寄存器的当前值压入栈中。
如果影子栈被启用:
a. 临时内部保存 SPP 寄存器的当前值,将SPP与下一个8字节边界对齐。
b. 将 CS 寄存器的当前值压入影子栈。
c. 将 LIP(CS.base + EIP)的当前值压入影子栈。
d. 将 SSP 寄存器内部保存值压入影子栈。
2. 将 EIP 寄存器的当前值压入栈中。
3. 加载包含调用代码的段的段选择子到 CS 寄存器中。
4. 加载调用代码的偏移值到 EIP 寄存器中。
5. 开始执行调用代码的运行。
当执行远返回时,处理器会做下面这些事情:
1. 弹出栈顶值(返回指令指针)到 EIP 寄存器中。
2. 弹出栈顶值(返回代码段的段选择子)到CS寄存器中。
如果启用了影子寄存器
a. 产生控制保护异常(#CP(FAR-RET/IRET))如果 SSP 没有对齐8字节。
b. 将影子栈在 SSP+8(LIP)地址的值 和SSP + 16(CS)的值与 从栈中弹出的 CS 和(CS.base + EIP)相比较。如果没有匹配,产生控制保护异常(#CP(FAR-RET/IRET))
c. 弹出栈顶值(返回代码的SSP)从影子栈到 SSP 寄存器中。
3. 如果返回指令有可选参数n,按 n 操作数递增栈指针 n 个数量的字节以从栈上释放参数。
4. 恢复调用代码的运行。
# 第七章 Programming With General-Purpose Instructions

6
Intel 手册中文版/卷三:系统编程指南.md

@ -1,9 +1,9 @@
翻译前先阅读整体规则的 [README](https://github.com/sunym1993/flash-linux0.11-talk/blob/main/Intel%20%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88/README.md) 哟~
@翻译人: 17cao
# 第一章 About This Manual
@翻译人: 17cao
# 第二章 System Architecture Overview
@翻译人: 17cao
# 第三章 Protected-Mode Memory Management
# 第四章 Paging

43
README.md

@ -13,6 +13,10 @@
**发文时间**:每周一和每周四
**互动方式**:微信群(关注公众号并回复“os”)
**创作番外故事**:[知识星球](https://mp.weixin.qq.com/s/NFUgJ4-hIyrs1sQr8AUCvA)
**开篇词**:[闪客新系列!你管这破玩意叫操作系统源码](https://mp.weixin.qq.com/s/tvbkGLfhDq03xxM-FZ4zuA)
**一些非必须的资料**:[资料包](https://github.com/sunym1993/flash-linux0.11-talk/tree/main/%E4%B8%80%E4%BA%9B%E9%9D%9E%E5%BF%85%E8%A6%81%E7%9A%84%E8%B5%84%E6%96%99)
@ -23,6 +27,8 @@
**还有个有趣的事情大家可以共同参与进来**:[Intel手册翻译计划](https://github.com/sunym1993/flash-linux0.11-talk/tree/main/Intel%20%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88)
当然,欢迎大家一同维护这个项目,有关操作系统普及的各种信息,都可以发起 PR 提交
---
**架构图**
@ -37,22 +43,39 @@
* **第一部分:进入内核前的苦力活**
* [回 最开始的两行代码](https://mp.weixin.qq.com/s/LIsqRX51W7d_yw-HN-s2DA)
* [回 自己给自己挪个地儿](https://mp.weixin.qq.com/s/U-txDYt0YqLh5EeFOcB4NQ)
* [回 做好最最基础的准备工作](https://mp.weixin.qq.com/s/90QBJ-lP_-du2qQJxNF-Fw)
* [回 把自己在硬盘里的其他部分也放到内存来](https://mp.weixin.qq.com/s/hStc-y-sabP-KwJUDUesTw)
* [回 进入保护模式前的最后一次折腾内存](https://mp.weixin.qq.com/s/5s_nmrWRZbA_4mkNKOQ2Cg)
* [回 先解决段寄存器的历史包袱问题](https://mp.weixin.qq.com/s/p1a6QxYZyMpJF__uBSE1Kg)
* [回 六行代码就进入了保护模式](https://mp.weixin.qq.com/s/S5zarr9BmLhUHAmdmeNypA)
* [回 烦死了又要重新设置一遍 idt 和 gdt](https://mp.weixin.qq.com/s/ssQKFMehxZxWT9i6mdRtXg)
* [回 Intel 内存管理两板斧:分段与分页](https://mp.weixin.qq.com/s/q2wU9IbX54t_GAuc9V5r7A)
* [回 进入 main 函数前的最后一跃!](https://mp.weixin.qq.com/s/ISyaX5zPWRw_d-9zvZUPUg)
* [1回 最开始的两行代码](https://mp.weixin.qq.com/s/LIsqRX51W7d_yw-HN-s2DA)
* [2回 自己给自己挪个地儿](https://mp.weixin.qq.com/s/U-txDYt0YqLh5EeFOcB4NQ)
* [3回 做好最最基础的准备工作](https://mp.weixin.qq.com/s/90QBJ-lP_-du2qQJxNF-Fw)
* [4回 把自己在硬盘里的其他部分也放到内存来](https://mp.weixin.qq.com/s/hStc-y-sabP-KwJUDUesTw)
* [5回 进入保护模式前的最后一次折腾内存](https://mp.weixin.qq.com/s/5s_nmrWRZbA_4mkNKOQ2Cg)
* [6回 先解决段寄存器的历史包袱问题](https://mp.weixin.qq.com/s/p1a6QxYZyMpJF__uBSE1Kg)
* [7回 六行代码就进入了保护模式](https://mp.weixin.qq.com/s/S5zarr9BmLhUHAmdmeNypA)
* [8回 烦死了又要重新设置一遍 idt 和 gdt](https://mp.weixin.qq.com/s/ssQKFMehxZxWT9i6mdRtXg)
* [9回 Intel 内存管理两板斧:分段与分页](https://mp.weixin.qq.com/s/q2wU9IbX54t_GAuc9V5r7A)
* [10回 进入 main 函数前的最后一跃!](https://mp.weixin.qq.com/s/ISyaX5zPWRw_d-9zvZUPUg)
* [第一部分总结与回顾](https://mp.weixin.qq.com/s/8bP3feeF_A13j7ysWur_JQ)
* **第二部分:大战前期的初始化工作**
* [第11回 整个操作系统就20几行代码](https://mp.weixin.qq.com/s/kYBrMgHt7C9EmAcwJIPIxg)
* [第12回 管理内存前先划分出三个边界值](https://mp.weixin.qq.com/s/eoBFcgm0QrHOVi_WoS7PwA)
* [第13回 主内存初始化 mem_init](https://mp.weixin.qq.com/s/_rTmjHIDCV9ADiJlfo5B3g)
* [第14回 中断初始化 trap_init](https://mp.weixin.qq.com/s/sFp_388qRncB-jpJeRzCGQ)
* [第15回 块设备请求项初始化 blk_dev_init](https://mp.weixin.qq.com/s/pIbVY1XPCktxGogc4lI1Bw)
* [第16回 控制台初始化 tty_init](https://mp.weixin.qq.com/s/yIrzEWUUuZC9OsiuU_lOaw)
* [第17回 时间初始化 time_init](https://mp.weixin.qq.com/s/y26MMfj8pP5PmbKDZBT5-A)
* [第18回 进程调度初始化 sched_init](https://mp.weixin.qq.com/s/j4FYWUSX_2gpDb_h4vEFqQ)
* [第19回 缓冲区初始化 buffer_init](https://mp.weixin.qq.com/s/X8BSbf1qShS11_fzfyOhTg)
* [第20回 硬盘初始化 hd_init](https://mp.weixin.qq.com/s/803C9jHxIe42i9BrNzEvPA)
* [第二部分总结与回顾](https://mp.weixin.qq.com/s/Hf9B1ww1wFxiUDkWb0obeQ)
* **第三部分:一个新进程的诞生**
* [第21回 新进程诞生全局概述](https://mp.weixin.qq.com/s/H_OCZ2ZtGHWHge_rYKCkJw)
* [第22回 从内核态切换到用户态](https://mp.weixin.qq.com/s/AVl6R2N9d_sldkhfvC6aEw)
* [第23回 如果让你来设计进程调度](https://mp.weixin.qq.com/s/Sf9vV7RCnVDlBKXx5jXs1Q)
* [第24回 从一次定时器滴答来看进程调度](https://mp.weixin.qq.com/s/yFre8Qv_ZCtjRkTS49n6rw)
* **第四部分:shell 程序的到来**
* **第五部分:从一个命令的执行看操作系统各模块的运作**

BIN
file1615.pdf

Binary file not shown.

BIN
一些非必要的资料/x86汇编语言-从实模式到保护模式.pdf

Binary file not shown.

BIN
一些非必要的资料/x86汇编语言_从实模式到保护模式(完整扫描版).pdf

Binary file not shown.

149
读者分享/Interrupt Table as Implemented by System BIOS

@ -0,0 +1,149 @@
From hjd(brace)
Intel Defined CPU Exception Table (see notes)
Interrupt Function
0 Divide by zero
1 Single step
2 Non-maskable (NMI)
3 Breakpoint
4 Overflow trap
5 BOUND range exceeded (186,286,386)
6 Invalid opcode (186,286,386)
7 Coprocessor not available (286,386)
8 Double fault exception (286,386)
9 Coprocessor segment overrun (286,386)
A Invalid task state segment (286,386)
B Segment not present (286,386)
C Stack exception (286,386)
D General protection exception (286,386)
E Page fault (286,386)
F Reserved
10 Coprocessor error (286,386)
IBM PC Hardware Interrupt Table (in order of priority)
IRQ# Interrupt Function
IRQ0 8 timer (55ms intervals, 18.2 per second)
IRQ1 9 keyboard service required
IRQ2 A slave 8259 or EGA/VGA vertical retrace
IRQ8 70 real time clock (AT,XT286,PS50+)
IRQ9 71 software redirected to IRQ2 (AT,XT286,PS50+)
IRQ10 72 reserved (AT,XT286,PS50+)
IRQ11 73 reserved (AT,XT286,PS50+)
IRQ12 74 mouse interrupt (PS50+)
IRQ13 75 numeric coprocessor error (AT,XT286,PS50+)
IRQ14 76 fixed disk controller (AT,XT286,PS50+)
IRQ15 77 reserved (AT,XT286,PS50+)
IRQ3 B COM2 or COM4 service required, (COM3-COM8 on MCA PS/2)
IRQ4 C COM1 or COM3 service required
IRQ5 D fixed disk or data request from LPT2
IRQ6 E floppy disk service required
IRQ7 F data request from LPT1 (unreliable on IBM mono)
Interrupt Table as Implemented by System BIOS/DOS
INT # Locus Function
0 CPU divide by zero
1 CPU single step
2 CPU non-maskable
3 CPU breakpoint
4 CPU overflow trap
5 BIOS print screen
6 CPU Invalid opcode (186,286,386)
7 CPU coprocessor not available (286,386)
8 IRQ0 timer (55ms intervals, 18.21590 per second)
9 IRQ1 keyboard service required (see INT 9)
A IRQ2 slave 8259 or EGA/VGA vertical retrace
B IRQ3 COM2 service required (PS/2 MCA COM3-COM8)
C IRQ4 COM1 service required
D IRQ5 fixed disk or data request from LPT2
E IRQ6 floppy disk service required
F IRQ7 data request from LPT1 (unreliable on IBM mono)
10 BIOS video (see INT 10)
11 BIOS Equipment determination (see INT 11)
12 BIOS memory size (see INT 12)
13 BIOS disk I/O service (see INT 13)
14 BIOS serial communications (see INT 14)
15 BIOS system services, cassette (see INT 15)
16 BIOS keyboard services (see INT 16)
17 BIOS parallel printer (see INT 17)
18 BIOS ROM BASIC loader
19 BIOS bootstrap loader (unreliable, see INT 19)
1A BIOS time of day (see INT 1A)
1B BIOS user defined ctrl-break handler (see INT 1B)
1C BIOS user defined clock tick handler (see INT 1C)
1D BIOS 6845 video parameter pointer
1E BIOS diskette parameter pointer (base table)
1F BIOS graphics character table
20 DOS general program termination
21 DOS function request services (see INT 21)
22 DOS terminate address (see INT 22)
23 DOS control break termination address (see INT 23)
24 DOS critical error handler (see INT 24)
25 DOS absolute disk read (see INT 25)
26 DOS absolute disk write (see INT 26)
27 DOS terminate and stay resident (see INT 27)
28 DOS idle loop, issued by DOS when idle (see INT 28)
29 DOS fast TTY console I/O (see INT 29)
2A DOS critical section and NETBIOS (see INT 2A)
2B DOS internal, simple IRET in DOS 2.0-5.0
2C DOS internal, simple IRET in DOS 2.0-5.0
2D DOS internal, simple IRET in DOS 2.0-5.0
2E DOS exec command from base level command
interpreter (see INT 2E)
2F DOS multiplexer (see INT 2F)
30-31 CPM far jump vector for CPM (not an interrupt)
31 DPMI DOS Protected Mode Interface (for DOS extenders)
32 reserved
33 mouse support (see INT 33)
34-3E Microsoft/Borland floating point emulation
3F overlay manager
40 BIOS hard disk
41 BIOS fixed disk 0 parameters pointer (see INT 13,9)
42 BIOS relocated video handler (EGA/VGA/PS)
43 BIOS user font table (EGA/VGA/PS)
44 BIOS first 128 graphics characters (also Netware)
45 BIOS reserved for BIOS
46 BIOS fixed disk 1 parameters ptr (see INT 13,9/INT 41)
47 BIOS reserved for BIOS
48 BIOS PCjr cordless keyboard translation
49 BIOS PCjr non-keyboard scancode translation table
4A BIOS user alarm (AT,CONV,PS/2) (see INT 4A)
4B-4F BIOS reserved
50 BIOS periodic alarm from timer (PS/2)
51-58 BIOS reserved
59 BIOS GSS Computer Graphics Interface
5A BIOS cluster adapter BIOS entry point
5B BIOS cluster adapter boot
5C NETBIOS NETBIOS interface, TOPS interface
5D-5F BIOS reserved for BIOS
60-67 reserved for user software interrupts
67 EMS LIM/EMS specification (see INT 67)
68 APPC
69-6B reserved by IBM
6C DOS DOS 3.2 real time clock update
BIOS system resume vector
6D-6F reserved
70 IRQ8 real time clock (AT,XT286,PS50+, see INT 15)
71 IRQ9 software redirected to IRQ2 (AT,XT286,PS50+)
72 IRQ10 reserved (AT,XT286,PS50+)
73 IRQ11 reserved (AT,XT286,PS50+)
74 IRQ12 mouse interrupt (PS50+)
75 IRQ13 numeric coprocessor NMI error (AT,XT286,PS50+)
76 IRQ14 fixed disk controller (AT,XT286,PS50+)
77 IRQ15 reserved (AT,XT286,PS50+)
78-79 unused
80-85 ROM BASIC
86-F0 DOS reserved for BASIC interpreter use
86 NETBIOS NETBIOS relocated INT 18
E0 CPM CP/M 86 function calls
F1-FF reserved by IBM
FE-FF may be destroyed by return from protected
mode using VDISK on 286 machines (Apr 86, DDJ)

2
读者分享/README.md

@ -1 +1 @@
这里是读者们上传的,请尽情发挥你们的见解吧
这里的世界,交给大家一起建设

BIN
读者分享/file1615.pdf

Binary file not shown.

69
读者分享/linux调度算法解析 23回补充资料.md

@ -0,0 +1,69 @@
23回补充内容 by sn:
0.11 的调度函数 schedule,在文件 kernel/sched.c 中定义为:
```c
while (1) {
c = -1; next = 0; i = NR_TASKS; p = &task[NR_TASKS];
// 找到 counter 值最大的就绪态进程
while (--i) {
if (!*--p) continue;
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
c = (*p)->counter, next = i;
}
// 如果有 counter 值大于 0 的就绪态进程,则退出
if (c) break;
// 如果没有:
// 所有进程的 counter 值除以 2 衰减后再和 priority 值相加,
// 产生新的时间片
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p) (*p)->counter = ((*p)->counter >> 1) + (*p)->priority;
}
// 切换到 next 进程
switch_to(next);
```
由上面的程序可以看出,0.11 的调度算法是选取 `counter` 值最大的就绪进程进行调度。
当没有 counter 值大于 0 的就绪进程时,要对所有的进程做 `(*p)->counter = ((*p)->counter >> 1) + (*p)->priority`
其效果是对所有的进程(**包括阻塞态进程**)都进行 counter 的衰减,并再累加 priority 值。这样,对正被阻塞的进程来说,其此时的counter不为0,那么计算后得到的counter大于就绪态进程。
于是可知,**一个进程在阻塞队列中停留的时间越长,其优先级越大,被分配的时间片也就会越大**。
所以总的来说,Linux 0.11 的进程调度是一种**综合考虑进程优先级并能动态反馈调整时间片的轮转调度算法**。
## 进程 counter 是如何初始化的
首先回答第一个问题,显然这个值是在 fork() 中设定的。Linux 0.11 的 `fork()` 会调用 `copy_process()` 来完成从父进程信息拷贝(所以才称其为 fork),看看 `copy_process()` 的实现,会发现其中有下面两条语句:
```c
// 用来复制父进程的PCB数据信息,包括 priority 和 counter
*p = *current;
// 初始化 counter
p->counter = p->priority;
// 因为父进程的counter数值已发生变化,而 priority 不会,所以上面的第二句代码将p->counter 设置成 p->priority。
// 每个进程的 priority 都是继承自父亲进程的,除非它自己改变优先级。
```
①假设没有改变优先级,时间片的初值就是进程 0 的 priority,即宏 INIT_TASK 中定义的:
```c
#define INIT_TASK \
{ 0,15,15,
// 上述三个值分别对应 state、counter 和 priority;
```
## 当进程的时间片用完时,被重新赋成何值?
接下来回答第二个问题,当就绪进程的 counter 为 0 时,不会被调度(schedule 要选取 counter 最大的,大于 0 的进程),而当所有的就绪态进程的 counter 都变成 0 时,会执行下面的语句:
```c
(*p)->counter = ((*p)->counter >> 1) + (*p)->priority;
```
算出的新的 counter 值也等于 priority,即初始时间片的大小。
Loading…
Cancel
Save