Skip to content

Commit 61486d6

Browse files
committed
update gitcode image
1 parent d078d6e commit 61486d6

File tree

5 files changed

+13
-12
lines changed

5 files changed

+13
-12
lines changed

content/11-operating-system/01-introduction.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ tags: ["os", "操作系统"]
1313
2. 管理硬件资源
1414

1515
## 操作系统硬件资源
16-
![](https://gitcode.net/xnzone/solar/-/raw/master/2021/11/30141903.png)
16+
17+
![](https://s2.loli.net/2025/09/28/x3WUyKp6uYM4kPE.png)
1718

1819
主要有:处理器,内存,硬盘,I/O设备,总线
1920

@@ -66,7 +67,7 @@ I/O设备主要是用来输入输出,因为需要及时反馈,所以又有
6667

6768
大部分系统都提供一个目录(*directory*),把多个文件集中在一起。主要模型如下
6869

69-
![](https://gitcode.net/xnzone/solar/-/raw/master/2021/11/30163835.png)
70+
![](https://s2.loli.net/2025/09/28/ksGiQ3Sjdt9fX6O.png)
7071

7172
文件也有操作权限,所以也相对来说提供了保护
7273

@@ -85,7 +86,7 @@ I/O设备主要是用来输入输出,因为需要及时反馈,所以又有
8586
## 系统调用
8687
系统调用(*system call*)是用户态的进程调用内核态的函数的方式。比如读取的系统调用过程
8788

88-
![](https://gitcode.net/xnzone/solar/-/raw/master/2021/11/30170134.png)
89+
![](https://s2.loli.net/2025/09/28/xJSsZ8qz6DytWV2.png)
8990

9091
介绍一些系统调用的用法
9192

content/11-operating-system/02-process-and-thread-intro.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tags: ["os", "操作系统"]
1919

2020
如下图所示,每个进程都有自己的程序,彼此独立运行,然而实际上只有一个CPU,只有一个物理的程序计数器,所以当进程运行的时候,进程的逻辑程序计数器被加载到实际的程序计数器,运行时间结束的时候,就会把物理程序计数器保存到逻辑程序计数器。所以看上去程序都在并行运行,但是在任意时间,都只有一个进程在运行
2121

22-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/01/06200757.png)
22+
![](https://s2.loli.net/2025/09/28/1eyKx9gkZbj2Mlv.png)
2323

2424
由于上下文切换时间不确定,所以不能对进程进行基于时间假定的编程。进程是正在运行的程序,而程序一般是保存在磁盘上的,一个程序运行两个,那就是两个进程,但是是同一个程序
2525

@@ -64,7 +64,7 @@ UNIX的系统调用是`exit`,Windows的系统调用是`ExitProcess`
6464
2. 就绪态(Ready) 可以运行的,但是临时暂停让其他进程运行。没有占用CPU
6565
3. 阻塞态(Blocked) 直到一些事件发生的时候才能运行。就算CPU空闲都不会运行
6666

67-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/01/07130633.png)
67+
![](https://s2.loli.net/2025/09/28/jKB8YLwxinZs2OI.png)
6868

6969
如上图,三个状态之间有四个转换
7070
- 转换1: 运行态->阻塞态。一般是执行系统调用或者等待事件
@@ -74,7 +74,7 @@ UNIX的系统调用是`exit`,Windows的系统调用是`ExitProcess`
7474

7575
所以进程模型总结来说就是下面这个图。操作系统底层是调度器,上层是各种进程,调度器实现了一些隐藏的细节比如上下文切换,进程数据保存和恢复等
7676

77-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/01/07131347.png)
77+
![](https://s2.loli.net/2025/09/28/tUsZXPHSx1wYiTe.png)
7878

7979
## 进程实现
8080
进程主要是通过进程表(process table)结构体实现整个进程,也有称为进程控制块(process control blocks,即PCB)。主要的数据有:程序计数器,栈计数器,内存分配,打开文件的状态,还有一些上下文切换所必须要的数据
@@ -104,7 +104,7 @@ UNIX的系统调用是`exit`,Windows的系统调用是`ExitProcess`
104104

105105
内核级线程,内核维护一张线程表,线程的操作都是通过内核调用来实现的
106106

107-
![用户级和内核级线程](https://gitcode.net/xnzone/solar/-/raw/master/2022/01/21174550.png)
107+
![](https://s2.loli.net/2025/09/28/BomXvrLcbhM43Yd.png)
108108

109109

110110

content/11-operating-system/03-interprocess-communication.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ int pipe(int fd[2]);
3535
3636
某些系统提供全双工管道:SVR4的`pipe`函数以及很多内核提供的`socketpair`函数。全双工管道的实现如图,是两个独立的数据流,即两个半双工的管道组成的
3737
38-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/02/14104215.png)
38+
![](https://s2.loli.net/2025/09/28/9TCHsfIAXimr6ea.png)
3939
4040
标准I/O提供了两个函数`popen`和`pclose`,创建一个管道并启动另外一个进程,该进程要么从该管道读出标准输入,要么往该管道写入标准输出
4141

content/11-operating-system/06-virtual-memory-address-space.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ tags: ["os", "操作系统"]
2323

2424
一个地址空间包括进程所有的信息,最基本的,我们谈论最多的就是代码(指令),堆(从小到大增长),栈(从大到小增长)。当我们描述地址空间时,描述的是操作系统提供给运行程序的抽象,程序不是在物理内存0~16KB的内存中,而是在加载到任意的物理地址
2525

26-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/02/16163205.png)
26+
![](https://s2.loli.net/2025/09/28/vV78Ek1bWel43RK.png)
2727

2828
## 如何执行
2929
虚拟内存为程序提供了一个巨大的、稀疏的、私有的地址空间(一般称为虚拟地址),这些都是对程序可见的,但是CPU运行程序的时候,是需要到实际的物理内存(一般称为物理地址或实际地址)取数据,这里需要有一个机制将虚拟地址和物理地址进行转换,一般是通过**分页****分段**去实现,后面会具体讨论。

content/11-operating-system/07.page-segmentation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ tags: ["os", "操作系统"]
2222

2323
常用段地址计算的方式有硬件和软件两种方式。软件方式是比较常用的,利用地址的前几位来表示段号,后面表示段内偏移量,如图。硬件还有其他方法来决定特定地址在哪个段。在隐式(implicit)方式中,硬件通过地址产生的方式来确定段。例如,如果地址由程序计数器产生(即它是指令获取),那么地址在代码段。如果基于栈或基址指针,它一定在栈段。其他地址则在堆段。**通常使用软件的方式比较多,这种方式在很多地方也有借鉴使用,比如雪花算法**
2424

25-
![](https://gitcode.net/xnzone/solar/-/raw/master/2022/02/17150603.png)
25+
![](https://s2.loli.net/2025/09/28/4eKgsj8awLZmz7D.png)
2626

2727
对于栈(从大到小方向增长)的地址计算,还需要一个硬件支持的标志位,增长方向
2828

@@ -91,7 +91,7 @@ TLB的内容大致为`VPN|PFN|其他位`,其他位主要是有效位、保护
9191

9292
整个虚拟地址结构大致如图。前两位表示段号,中间是页号,最后表示映射地址
9393

94-
![分段和分页虚拟地址结构](https://gitcode.net/xnzone/solar/-/raw/master/2022/02/17170457.png)
94+
![](https://s2.loli.net/2025/09/28/T2jBvob314g7Rdz.png)
9595

9696
在 TLB 未命中时(假设硬件管理的 TLB,即硬件负责处理 TLB 未命中),硬件使用分段位(SN)来确定要用哪个基址和界限对。然后硬件将其中的物理地址与 VPN 结合起来,形成页表项(PTE)的地址
9797

@@ -106,7 +106,7 @@ TLB的内容大致为`VPN|PFN|其他位`,其他位主要是有效位、保护
106106

107107
如图展示了一个例子。图的左边是经典的线性页表。即使地址空间的大部分中间区域无效,我们仍然需要为这些区域分配页表空间(即页表的中间两页)。右侧是一个多级页表。页目录仅将页表的两页标记为有效(第一个和最后一个);因此,页表的这两页就驻留在内存中。因此,你可以形象地看到多级页表的工作方式:它只是让线性页表的一部分消失(释放这些帧用于其他用途),并用页目录来记录页表的哪些页被分配。
108108

109-
![线性页表和多级列表](https://gitcode.net/xnzone/solar/-/raw/master/2022/02/17171427.png)
109+
![](https://s2.loli.net/2025/09/28/5E1AdT8rSwOb2p7.png)
110110

111111
在一个简单的两级页表中,页目录为每页页表包含了一项。它由多个页目录项(Page Directory Entries,PDE)组成。PDE(至少)拥有有效位(valid bit)和页帧号(page frame number,PFN),类似于 PTE。但是,正如上面所暗示的,这个有效位的含义稍有不同:如果 PDE 项是有效的,则意味着该项指向的页表(通过 PFN)中至少有一页是有效的,即在该 PDE 所指向的页中,至少一个 PTE,其有效位被设置为 1。如果 PDE 项无效(即等于零),则 PDE的其余部分没有定义。
112112

0 commit comments

Comments
 (0)