1、分页映射是内存管理最重要的技术之一,以下说法错误有(多选):(《深入理解LINUX内核》第二章)
A、通过分页映射,MMU在每次访问时都需要经过特权级、权限等检查,防止访问不该访问的内容,达到保护的作用
B、通过分页映射,MMU将线性地址转换为物理地址
C、通过分页映射,MMU将虚拟地址转换为线性地址
D、系统运行时,对于采用对等映射的内核态访问内存时,不需要经过分页映射,因为物理地址只需要在虚拟地址的基础上减去一个固定偏移量就行了
参考答案:C、D
试题解析:
将虚拟地址转换为线性地址的技术是分段技术,而分页技术是将线性地址转换为物理地址;由于Linux不使用分段技术,虚拟地址和线性是一一对应的关系,因此在Linux系统中80010000分虚拟地址和80010000,统称为虚拟地址。
内核态的对等映射有一个特点,其虚拟地址和物理地址是一一对应的,虚拟地址=物理地址+offset,物理地址=虚拟地址-offset。但对于硬件运行时,访问任何一个虚拟地址都需要通过查找页表的方式去访问其对应的物理地址。
2、在一个具有4G内存的X86系统中,下列哪些虚拟地址不可能存在(多选):(内核代码介绍文档mm.txt)
A、00007fffff000000
B、00008fffffffffff
C、ffffc7ffff000000
D、ffffe9000000abcd
E、ffffffff80010000
参考答案:B、C、D
试题解析:
00007fffff000000属于用户态地址,可能存在;00008fffffffffff属于不被使用的地址空间,不可能存在;ffffc7ffff000000属于内核对等映射区,但ffffc7ffff000000-ffff880000000000=3fffff000000>>4G,该对等映射地址不可能存在,因为对等映射区域是根据物理内存建立的,对于4G的系统,对等映射区域只有4G的大小;ffffe9000000abcd地址处于hole空间,不可能存在;ffffffff80010000属于内核文本映射区,且小于4G,可能存在。
3、Linux内存分配的一项基本原则为缺页处理,即多数内存分配时只分配虚拟内存,只有当访问此地址时发现没有对应的物理地址,从而产生缺页,再为此虚拟内存分配物理内存。那么下列哪个地址造成的缺页异常内核无法处理(单选):(内核代码介绍文档mm.txt,《深入理解LINUX内核》第九章)
A、00007fffff00abcd
B、ffffc9000000abcd
C、ffff88000000abcd
参考答案:C
试题解析:
内核可以正常处理的缺页异常地址包括用户态地址和vmalloc分配的地址两种,而对于内核对等映射的虚拟地址内核是不会处理的,因为该区域的页表是初始化就已经建立,因此不可能产生缺页。题中选项C的地址属于对等映射区,选项A的地址属于用户态,选项B的地址都是通过vmalloc分配的,可以产生正常的缺页。
4、硬件TLB的作用为(单选):(《深入理解LINUX内核》第二章)
A、缓存虚拟地址和线性地址的映射关系
B、缓存线性地址和物理地址的映射关系
C、缓存物理地址对应的内存数据
D、缓存虚拟地址对应的内存数据
参考答案:B
试题解析:TLB硬件用于缓存页表映射的内容,即缓存线性地址和物理地址的映射关系。
5、下列哪些操作会发生页表修改动作(多选):(内核代码介绍文档mm.txt,《深入理解LINUX内核》第九章)
A、在用户态发生缺页异常
B、在内核态发生缺页异常
C、在对等映射区分配内存
D、在对等映射区释放内存
E、在用户态申请内存
F、在用户态释放内存
参考答案:A、B、F
试题解析:
用户态和内核态发生缺页异常,说明是访问虚拟地址时发生没有对应的物理地址产生缺页异常,此时内核会为此虚拟地址申请物理地址,然后将映射关系写入页表,因此选项A、B都会发生页表修改。
对等映射区的页表是在初始化时就已经建立,无论后续是分配、释放内存,都不会涉及该页表的修改,因此选项C、D不会修改页表。
在用户态申请内存时,内核只会为该操作申请虚拟地址,不会申请物理地址,物理地址的申请需要通过缺页异常来触发,因此选项E不会修改页表。但在用户态释放内存时,需要将物理内存释放回系统,需要将对应的页表映射关系去除,否则容易产生内存非法访问,因此选项F会修改页表。
6、 ia64系统启动时内存初始化不包括以下哪个部分?(单选):(《深入Linux内核架构》3.4)
A、 bootmem分配器的初始化
B 、伙伴算法、slab/slub分配器的初始化
C、内核页表的初始化
D 、zone管理区和zonelist链表的初始化
参考答案:C
试题解析:
系统启动初始化内存部分包括早期的e820图(x86)、efi图(ia64)的构建、用户命令行参数的解析、内核页表的初始化(只有x86有,ia64没有)、pgdat和bootmem分配的创建、伙伴算法分配器的初始化、slab/slub分配器的初始化、zone管理区和zonelist链表的初始化等等。
7、 page结构体描述符中的_count字段和_mapcount字段的区别,以下描述错误的是(单选):(《深入Linux内核架构》P119-P123)
A、 _count是一个引用计数,表示内核中引用该页的次数
B 、_mapcount表示在页表中有多少项指向该页
C、 _count的值与_mapcount的值存在不相等的情况
D 、在反向映射删除页表后,_count值变为0,但_mapcount值不变
参考答案:D
试题解析:
_count和_mapcount是page结构体中的两个字段:_count是一个引用计数,表示内核中有多少个地方用到这个page,没有用到的话值为0;_mapcount表示内核中该page对应的用户态页表数量,若没有页表与该page对应则值为-1,0表示有一个页表,大于0表示该页是共享页,存在多个页表。这两个字段是两个概念,它们的值没有直接联系,因此会有不相等的情况。在rmap(反向映射)删除页表后,_mapcount值变为-1,但_count值一般不为0。
8、 关于节点描述符pgdat,以下描述错误的是(单选):(《深入Linux内核架构》P111-P115)
A、 NUMA系统中每个节点有且只有一个pgdat
B 、若改变指向pgdat的指针数组NODE_DATA[]的值将直接导致系统宕机
C 、系统所有的zone描述符本身都包含在每一个pgdat里面
D 、系统所有的zone描述符的zonelist链表包含在每一个pgdat里面
参考答案:C
试题解析:
NUMA系统中每个节点有且只有一个pgdat,若随意改变pgdat的值将直接导致系统宕机,比如插入模块,使NODE_DATA(0)=NULL后系统直接挂掉(NODE_DATA()指向pgdat)。一个pgdat结构体里只包含本节点中的zone结构体,但包含系统中所有zone结构体的全局zonelist链表。
4、 x86_64系统中,关于zone类型的划分,以下正确的是(单选):(《深入理解Linux内核》P299-P300)
A 、系统中没有ZONE_DMA
B 、系统中一般会存在ZONE_DMA32
C 、系统中物理内存16M-896M区域是ZONE_NORMAL
D 、系统中不管物理内存多大,始终存在ZONE_NORMAL
参考答案:B
试题解析:
x86_32系统中:0-16M为ZONE_DMA,16-896M为ZONE_NORMAL,大于896M为ZONE_HIGHMEM。x86_64系统中:0-16M为ZONE_DMA,16M-4G为ZONE_DMA32,大于4G为ZONE_NORMAL,不存在ZONE_HIGHMEM。在ia64系统中:16M-4G为ZONE_DMA,大于4G为ZONE_NORMAL,不存在ZONE_HIGHMEM。
10、 关于每cpu页,以下描述正确的是(单选):(《深入理解Linux内核》P317-P319)
A 每cpu页,即pcp,通常用于分配单个页框,以提高系统整体性能
B 修改内核,强制屏蔽pcp之后将导致系统起不来
C 释放单个页框时,通常是先放入伙伴算法,而不是放入pcp
D 若要分配单个页框,必须先从pcp分配,不能跳过pcp而直接使用alloc_pages()等这些API
参考答案:A
试题解析:
每cpu页,即pcp,通常用于分配单个页框,以提高系统整体性能。修改内核,强制屏蔽pcp之后系统是可以起来的,只是性能上会有所损失。释放单个页框时,通常会先放入pcp,若pcp满了后才会放入伙伴算法。若要分配单个页框,内核一般是从pcp分配,但不强制,比如系统初始化时分配的内存有些就直接使用alloc_pages()等这些API分配单个页框。