Browsed by
Month: April 2017

[Linux 0.11] Draft 6 IA32架构下多任务的硬件支持

[Linux 0.11] Draft 6 IA32架构下多任务的硬件支持

Overview 支持多任务的硬件结构为 Task Register (TR) Task State Segment (TSS), LDT 以及 Task Gate。而最核心的,存储任务上下文信息的就是 Task State Segment, 下面对其进行详细的说明 TSS基本数据结构 GDT, LDT TSS(Task State Segment)  has its own descriptor called TSS Descriptor Structure of 32 bit TSS, store the context and link to previous task, and 3 different privileged Stack 下面对一些比较关键的部分进行介绍 Previous Task Link: 存储的是上一个任务的选择符 LDT Segment Selector: 存储的是这个Task使用的LDT I/O Map Base Address: I/O Map的基地址(要对 I/O Map 是什么进行进一步的解读: I/O Map 包含一个权限Map和一个Interrupt redirect Map) TSS 描述符的一些说明 TSS Descriptor 用于描述 Task State Segment 的描述符,当选择符的TI…

Read More Read More

[Linux 0.11] Draft 5 虚拟内存管理(mm/memory.c)

[Linux 0.11] Draft 5 虚拟内存管理(mm/memory.c)

Overview 本文介绍 32 位保护模式下的内存分页, 以及 linux0.11 对物理内存的管理。 意义 既然要使用内存分页,那么就一定有他的优势所在。我们首先来探讨一下使用内存分页的意义, 分页在于为进程提供了虚拟地址空间,通过提供的这个虚拟地址空间,我们可以做到下面的这些: 精细的权限控制粒度: 内存页大小以 4KB 为一页单位(也可以是4MB, 这里不讨论这种情况), 可以针对每一个内存页设置该4K空间的访问权限。相比分段的粗粒度精细了很多,目前的分段功能只是一个兼容性考虑,分段都是将整个0 – 最大内存空间直接映射为一个段; 可以使得进程独享地址空间: 通过切换CR3寄存器的内容,可以实现多个进程占用同一个虚拟地址空间。 有效的解决了进程对大块连续内存的请求: 这里用一个例子来说明一下。 例子是这样的: 如果我们有16MB的物理内存,现在有进程A B C分别占用5MB, 2MB, 3MB内存, 且不共享内存。然后现在进程B退出了,我们还剩余8MB内存,可是如果不使用分页的话,内存连续分配, 我们现在没有办法分配出一个连续的8MB的空间了,只能分配最多最多6MB连续的内存空间, 如下图所示。 而现在存在分页,虚拟地址,我们完全可以分配连续的8MB的虚拟地址空间,其中2MB映射到物理内存的中间那个2MB空隙,其余6MB映射到最后剩余的6MB。 由此可见,分页是十分必要的,那么下面就来介绍一下如何实现分页&虚拟内存管理 地址转换过程 我们先来看一下虚拟地址是如何转换为物理地址的 完整的转换过程为 虚拟地址 –> (GDT) –> 线性地址 –> (Page Table) –> 物理地址 关于VirtualAddr -> LinearAddr 的过程我在之前的文章中有过介绍,这里就不做说明,想要跳过那个文章的读者可以简单的理解为目前的虚拟地址和线性地址值是相同的,因而我们直接从线性地址出发。首先来看下图   (图片来源:Intel® 64 and IA-32 Architectures Software Developer’s Manual) 线性地址为32位的地址, 其中高十位为 Page Directory,中间十位为 Page Table,最后十二位是 Offset。过程如下: 根据 CR3 寄存器(忘记了寄存器的功能的话戳这里)找到了页目录表的地址。 根据 Linear Address 的高十位与页表目录地址相加,找到了对应的页目录项(PDE)。 页目录项内存有该页目录的起始地址,将此地址与 Linear Address 21 – 12 位(即中间十位)相加,找到对应的页表项(PTE)…

Read More Read More