💭 写在前面:
本系列博客为复习操作系统导论的笔记,内容主要参考自:
- Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy PiecesA. Silberschatz, P. Galvin, and G. Gagne,
- Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7.Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .
0x00 早期操作系统(OS in The Early System)
Load only one process in memory.(只在内存中运行一个进程)
- Poor utilization and efficiency (利用率低,效率差)
0x01 多道程序和时分共享(Multi-programming and Multi-tasking)
Multi-programming(多道程序)
- Load multiple processes in memory.
- Execute one for a short while and switch processes between them in memory.
- Increase utilization and efficiency.
Time-sharing (multitasking)(时分共享)
Logical extension in which CPU switches jobs so frequently that users can interact with each job while it is running, creating interactive computing.
Cause an important protection issue(保护问题)
- Errant memory accesses from other processes. (来自其他进程的错误内存访问)
- 多个程序同时驻留在内存中,保护就成了重要问题。人们不希望一个进程可以读取其他进程的内存,更别说修改了。
0x02 进程地址空间(Process Address Space)
OS creates an abstraction of physical memory. (OS创造一个物理内存抽象)
Contains all about a running process. (包罗所有正在运行的进程)
Consists of program code, heap, stack, etc. (由程序代码、堆、栈组成)
- Code : Where instructions live.
- Heap : Dynamically allocate memory.
- Stack : Store return addresses or values; Contain local variables and arguments to routines
(为了便于讲解,我们假设只有这三个部分)
0x03 虚拟地址空间(Virtual Address Space)
都是假象!凉凉月色为你思念成河,化作春泥呵护着我……
Every address in a running program is virtual. (程序运行时你看到的所有地址都是虚拟的)
- OS translates the virtual address to physical address
例子:下面是一个打印内存地址的简单程序:
#include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { printf("location of code : %p\n", (void*)main); printf("location of heap : %p\n", (void*)malloc(1)); int x = 3; printf("location of stack : %p\n", (void*)&x); return x; }
🚩 运行结果如下:(在64位Linux环境下跑的)
💡 由此可见:代码在地址空间开头,然后是堆,而栈在这个大型虚拟地址空间的另一端。所有的这些地址都是虚拟的,是假的!纯纯的 fake!都是特喵的骗人的!并且将由操作系统和硬件翻译成物理地址,以便从真实的地理位置获取该地址的值。
0x04 内核是个什么玩意(What About Kernel)
Each OS process has its own virtual address space and part of each virtual address space is reserved for the kernel.
(每个操作系统都有自己的虚拟地址空间,并且每个虚拟地址都是要留一部分空间给内核的)
- The size is configurable (e.g., 1G out of 4G).
When a process traps into the kernel, kernel uses the mapped space reserved for the kernel. (当一个进程陷阱进入内核时,内核使用为保留给内核的映射空间)
Although the kernel uses virtual address mapping, most of the kernel memory is mapped linearly onto physical addresses
(尽管内核使用内存地址映射,但 绝大多数内核的内存还是以线性地方式映射到物理地址上的)
0x05 用户栈 VS 内核栈(User Stack vs Kernel Stack)
In general, two types of stacks are used to run application programs.(一般来说,有两种类型的栈被用来运行应用程序):
- When they run in user mode, the user stack is used. (当它们在用户模式下运行时,使用的是用户栈)
- When they run in kernel mode (via system call), the kernel stack is used. (当它们在内核模式下运行时 (通过系统调用),使用的是内核栈)
When application programs invoke a system call(当应用程序调用一个系统调用时):
- Enters the kernel via trap (interrupt). (通过陷阱(中断)进入内核)
- Switch from user stack to kernel stack. (从用户栈切换到内核栈)
- In Pintos, kernel stack is allocated 4KB away from the start of PCB (Limited – do not allocate big static variables inside functions).
Raise the privilege level(提高权限级别)
0x06 进程结构: struct thread(Process Structure)
💬 代码:pintos/src/threads/thread.h
struct thread { /* Owned by thread.c. */ tid_t tid; /* Thread identifier. */ enum thread_status status; /* Thread state. */ char name[16]; /* Name (for debugging purposes). */ uint8_t* stack; /* Saved (kernel) stack pointer. */ int priority; /* Priority. */ struct list_elem allelem; /* List element for all threads list. */ /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ #ifdef USERPROG /* Owned by userprog/process.c. */ uint32_t* pagedir; /* Page directory. */ #endif /* Owned by thread.c. */ unsigned magic; /* Detects stack overflow. */ };
🔍 status:
0x07 逻辑(虚拟)VS 物理地址空间(Logical (Virtual) vs. Physical Address Space)
The user program deals withlogical (virtual) addresses, it never sees the real physical addresses. 用户程序处理的是 逻辑(虚拟)地址,它永远不会看到真正的物理地址
- Logical address(逻辑地址):由 CPU 生成,也被称为虚拟地址。
- Physical address(物理地址):内存单元看到的地址。
The concept of a logical address space that is bound to a separate physical address space (i.e., mapping between logical address space and physical address space) is central to proper memory virtualization. 绑定到独立物理地址空间的逻辑地址空间 (即逻辑地址空间和物理地址空间之间的映射) 的概念是正确的内存虚拟化的核心
The run-time mapping from virtual to physical addresses is done by a hardware device called the memory management unit (MMU) .
从虚拟地址到物理地址的运行时映射是由一个称为内存管理单元(MMU)的硬件设备完成的。
0x08 虚拟内存与物理内存之间的映射: 简单概述(Mapping Between Virtual to Physical Memory: Simple Overview)
- Divide logical (virtual) memory into blocks of same size called pages (size is power of 2, between 512 bytes and 8192 bytes) . 将逻辑(虚拟)内存分为相同大小的块,称为页(大小是2的幂,在512字节和8192字节之间)。
- Divide physical memory into fixed-sized blocks called frames. 将物理内存划分为固定大小的块,称为 frames。
- Page and frame size are usually the same. 页和帧的大小通常是一样的。
- Keep track of all free frames. 追踪所有空闲的框架。
- To run a program of size n pages, we need to find m free frames (m can be smaller than n; partially load -> virtual memory). 为了运行一个 页大小的程序,我们需要找到 个空闲的帧( 可以比 小,部分加载 → 虚拟内存)。
- Each process sets up a page table to translate logical to physical addresses. 每个进程都设置了一个页表,将逻辑地址转换为物理地址。
0x09 地址转换方案: 简单概述(Address Translation Scheme: Simple Overview)
由CPU产生的地址被分为:
- Page number (p) – used as an index into a page table which contains base address of each page in physical memory.
- Page offset (d) – combined with base address to define the physical memory address that is sent to the memory unit.
📌 [ 笔者 ] 王亦优 📃 [ 更新 ] 2022.10.4 ❌ [ 勘误 ] /* 暂无 */ 📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免, 本人也很想知道这些错误,恳望读者批评指正!
📜 参考资料 Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces A. Silberschatz, P. Galvin, and G. Gagne, Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/. |