文章

LINUX操作系统复习

前言

垃圾学习通,还不让我复制文字,没想到我能直接ctrl^s网页然后直接下载下来做吧!! 这个复习题仅供参考!!!

如果觉得我做的不错的话请给我的GitHub点个赞(随便哪个repo都行)

一.简答题

字符设备的名词解释是?

字符设备是指以字节流形式进行数据传输的设备,每次只能访问一个字节,没有缓冲区。例如:键盘、鼠标、串口等。

块设备的名词解释是?

块设备是指以数据块为单位进行数据传输的设备,可以随机访问任意数据块,通常有缓冲区。例如:硬盘、U盘、SD卡等。

jiffies的名词解释是?

jiffies是 Linux 内核中的一个全局变量,用于记录系统启动以来的时钟中断次数。它可以用来计算时间间隔、实现定时器等功能。

VFS的名词解释是?

VFS(Virtual File System,虚拟文件系统是 Linux 内核中的一种抽象层,它为用户空间程序提供统一的文件系统接口,屏蔽了底层不同文件系统的差异。

文件描述符的名词解释是?

文件描述符是一个非负整数,它代表了进程打开的一个文件或其他 I/O 资源。进程通过文件描述符来访问对应的文件或 I/O 资源。

在x86体系下,进程控制块存放在内核空间的什么位置(从内核堆栈的角度进行分析)。

在 x86 体系结构下,进程控制块(PCB)通常存放在内核空间的进程内核栈的底部。 当进程从用户态陷入内核态时,CPU 会将当前进程的寄存器值、函数调用栈等信息压入内核栈,并在内核栈的底部创建该进程的 PCB。

请用图示的方式表达Linux内核中进程控制块、进程虚拟地址空间、内存区域(memory area)以及进程页表之间的数据结构关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 +------------------+     +------------------+
 |  进程控制块 (PCB) |---->|  进程页表 (Page Table) |
 +------------------+     +------------------+
        |                       |
        |                       | 映射
        V                       V
 +------------------+     +------------------+
 | 进程虚拟地址空间       |     |  物理内存 (Memory Area) |
 +------------------+     +------------------+
        |
        | 包含多个
        V
 +------------------+
 |  内存区域 (Memory Area) |
 +------------------+

当Linux因为中断内转入内核可以分为两种情况,一种是由用户态切入内核,一种是在发生中断前系统已经在内核态。假设系统是X86架构,请说明这两种情况下系统堆栈的变化情况(仅介绍系统的陷入过程)。

1. 用户态切入内核:

  • 中断/异常发生前: CPU 处于用户态,执行用户程序的代码。此时,CPU 使用的是用户态堆栈, ESP 寄存器指向用户态堆栈的栈顶。
  • 中断/异常发生: CPU 硬件检测到中断/异常请求,根据中断向量表找到对应的中断处理程序入口地址。
  • CPU 切换到内核态: CPU 将当前执行状态(EFLAGS、CS、EIP 寄存器)压入内核堆栈,并将 ESP 寄存器指向内核堆栈的栈顶。
  • 保存现场: CPU 将中断/异常发生时的现场信息(通用寄存器等)压入内核堆栈。
  • 执行中断处理程序: CPU 开始执行内核态的中断处理程序。

2. 内核态发生中断:

  • 中断/异常发生前: CPU 处于内核态,可能正在执行系统调用或其他内核代码。此时,CPU 已经在使用内核态堆栈。
  • 中断/异常发生: CPU 硬件检测到中断/异常请求,根据中断向量表找到对应的中断处理程序入口地址。
  • 判断是否需要嵌套: CPU 检查当前中断/异常的优先级是否高于正在执行的代码,如果优先级更高,则进行嵌套处理。
  • 保存现场: CPU 将中断/异常发生时的现场信息(包括之前执行的代码的 EFLAGS、CS、EIP 寄存器以及通用寄存器等)压入内核堆栈。
  • 执行中断处理程序: CPU 开始执行新的中断处理程序。

请阅读下面内核空间的模块代码,对要求注释的地方加以注释。并说明如何加载与卸载该模块以及此二过程中控制台的显示内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void) {
    printk(KERN_ALERT "aaaaaaaa%i  bbbbbb%s ",current->pid,current->comm);
    printk(KERN_ALERT "\n");

    int pid_no=current->pid;    //
    struct task_struct * task=current;

    for_each_process(task) {    //
        if(task->pid==pid_no) break;  //
        printk(KERN_ALERT "process id = %d tpid= %d",(int)task->pid,(int)task->comm);
    }

    printk(KERN_ALERT "\n");
    return 0;
}

static void hello_exit(void) {
    printk(KERN_ALERT "Goodbye, cruel world\n");
}

module_init(hello_init);          // 
module_exit(hello_exit);          //
1
2
3
4
5
int pid_no=current->pid;    // 获取当前进程的进程号
for_each_process(task) {    //遍历系统中所有进程
if(task->pid==pid_no) break;  // 如果找到当前进程,则退出循环
module_init(hello_init);          // 模块加载函数
module_exit(hello_exit);          // 模块卸载函数

加载模块使用(假设你是root用户)

1
insmod **(模块名).ko

输出

1
2
3
4
aaaaaaaa<进程号>  bbbbbb<模块名> 
process id = 1 tpid= 0 
process id = 2 tpid= 0 
...

卸载模块

1
rmmod **(模块名)

输出

1
拜拜了您嘞,残酷的世界

根据fork()系统调用的特点,请注明下面用户空间程序执行到注释部分前时所处的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <unistd.h>
#include <stdio.h>
int main(void)
{
    pid_t pid=1000;
    int count=0;
    int a;
    ____ = fork(); //请填写一个变量名
    printf("\n Now, the pid returned by calling fork() is %d\n", pid);
    if (pid > 0)
    {
        //请说明此处为父进程还是子进程.
    }
    else if (!pid)
    {
        //请说明此处为父进程还是子进程.
    }
    else
    {
        //执行到这里是发生了什么状况.
    }
    return 0;
}
1
2
3
4
5
pid=fork()
printf("俺是父进程");
printf("俺是子进程");
printf("进程fork失败");
//整活用 不建议在编程时使用任何非ASCII码,会有意想不到的结果

二.单选题

当物理页面不再需要时, Linux内核提供了__函数来释放它们。

A._rmqueue() B.release_page C._free_page() D.clone()

正确答案:C. _free_page()

  • _free_page() 函数用于释放一个物理页面到伙伴系统。
  • rmqueue() 函数与队列操作相关,用于从队列中移除元素。
  • release_page() 函数用于减少页面的引用计数,并在计数为0时调用 __free_page() 释放页面。
  • clone() 函数用于创建进程,与内存管理无关。

Linux2.6内核中提供了多种机制来实现中断下半部,如下__不属于中断下半部机制。

A.工作队列 B.handle_IRQ_event() C.软中断 D.tasklet

正确答案:B. handle_IRQ_event()

  • handle_IRQ_event() 函数是中断处理程序的一部分,用于处理中断的上半部分。
  • 工作队列、软中断和 tasklet 都是 Linux 内核中实现中断下半部的机制,用于将中断处理的部分工作延迟执行。

以下选项中哪一个不属于Linux设备分类划分的范畴

A.虚拟设备 B.字符设备 C.块设备 D.网络接口设备

正确答案:A. 虚拟设备

  • Linux 内核将设备分为三类:字符设备、块设备和网络接口设备。
  • 虚拟设备并不是一个独立的设备类别,它通常指模拟真实设备功能的软件抽象,例如虚拟磁盘、虚拟网卡等。

以下数据结构中,哪一个是与进程地址空间直接相关的

A.free_area B.kmem_cache C.vm_area_struct D.page

正确答案:C. vm_area_struct

  • vm_area_struct 结构体描述了进程地址空间中的一段连续虚拟内存区域,也称为 VMA(Virtual Memory Area)。
  • free_area 结构体用于管理伙伴系统中的空闲内存块。
  • kmem_cache 结构体用于管理内核中的 slab 缓存。
  • page 结构体描述了一个物理页面,与进程地址空间没有直接关联。

在x86架构引入“门”的概念来“保护”系统资源访问,在调用trap_init()函数和init IRQ()函数进行IDT表项初始化时,需要使用定义在arch/x86/kernel/traps32.c中的几个函数对不同的“门”进行设置。以下选项中,哪一个不属于此范畴

A.set_trap_gate() B.set_syscall_gate() C.set_task_gate() D.set_intr_gate()

正确答案:B. set_syscall_gate()

  • set_syscall_gate() 函数通常在其他体系结构中使用,或者在 x86 上用于设置快速系统调用(fast system call)机制。

  • set_trap_gate(): 设置陷阱门,用于处理异常和系统调用以外的中断。
  • set_task_gate(): 设置任务门,用于在不同特权级之间进行任务切换。
  • set_intr_gate(): 设置中断门,用于处理硬件中断请求。

中断处理程序是__的一部分。

A.BIOS B.应用逻辑上下文 C.设备驱动程序 D.内核线程

**正确答案:C. 设备驱动程序 **

  • 设备驱动程序是操作系统内核的一部分,负责管理和控制硬件设备。它们充当了硬件和操作系统之间的桥梁。

Linux系统进程之间存在明显的继承关系,所有的进程都是__进程的后代。

A.init B.top C.root D./

正确答案:A. init

  • 在 Linux 系统中,init 进程(PID 为 1)是所有其他进程的祖先。
  • 当系统启动时,init 进程会启动其他系统服务和用户进程。

有关中断处理程序,下面描述不正确的是

A.运行在进程上下文 B.被分为两个半部(half C.运行在内核状态 D.不一定会有运行级别切换

正确答案:A. 运行在进程上下文

  • 中断处理程序运行在中断上下文中,而不是进程上下文。
  • 中断上下文是一种特殊的执行环境,它独立于任何进程,并且具有更高的优先级。
  • B. 被分为两个半部 (half):中断处理程序通常被分为上半部和下半部,以提高系统响应速度。
  • C. 运行在内核状态:中断处理程序始终运行在内核态,以访问系统资源。
  • D. 不一定会有运行级别切换:中断处理程序不一定导致运行级别切换,这取决于中断的类型和处理逻辑。

以下系统调用中,哪一个是与进程创建无直接关系的。

A.sys_vfork() B.sys_process() C.sys_clone() D.sys_fork()

正确答案:B. sys_process()

  • Linux 内核中没有 sys_process() 系统调用。
  • sys_vfork()sys_clone()sys_fork() 都是用于创建新进程的系统调用。

VFS是一个抽象的通用访问接口,它屏蔽了底层文件系统和物理介质的差异性,每一种类型的文件系统代码都隐藏了实现的细节。下面选项哪一个不属于此范畴

A.read() B.write() C.brk() D.open() 正确答案:C. brk()

  • brk() 系统调用用于修改进程的堆空间大小,与文件系统操作无关。
  • read()write()open() 都是 VFS 提供的通用文件操作接口。

    Linux中使用三级页表完成地址转换,其中顶级页表是页全局目录

    A.PGD B.PTE C.PMD D.GDT 正确答案:A. PGD (Page Global Directory)

  • 在 Linux 的三级页表机制中,PGD 是顶级页表,指向多个 PMD(Page Middle Directory)。
  • PMD 指向多个 PTE(Page Table Entry),最终指向物理页面。
  • GDT (Global Descriptor Table) 用于段式内存管理,与页式内存管理无关。

下面选项中哪一个是与CPU运行权限改变无关的,

A.EPL B.CPL C.DPL D.RPL 正确答案:A. EPL (External Privilege Level)

可以看看这个帖子

  • EPL 不是 CPU 中的概念,与运行权限无关。
  • CPL (Current Privilege Level) 表示当前运行代码的特权级。
  • DPL (Descriptor Privilege Level) 表示段描述符的特权级。
  • RPL (Requestor Privilege Level) 表示请求访问段时使用的特权级。

ext3相对ext2的主要改进是。

A.增加了对NFS(网络文件系统)的支持 B.ext3使用三级页表,而ext2使用2级 C.不可以当作ext2来挂载 D.增加了日志功能

  • ext3 文件系统最大的改进就是引入了日志功能,极大地提高了文件系统的可靠性。日志功能可以记录文件系统的修改,在系统崩溃或断电后,可以利用日志快速恢复文件系统的一致性,避免数据丢失或损坏。
  • A. ext2 已经支持 NFS。
  • B. ext2 和 ext3 都使用多级页表,但级数可能有所不同,这取决于具体的配置。
  • C. ext3 可以兼容 ext2,可以被当作 ext2 文件系统挂载。

Linux对物理内存的管理分3个层次,以下哪一个内核数据结构与该三层次管理无关

A.zone B.inode C.page D.pgdatat

正确答案:B. inode

  • Linux 内核使用 zone、page 和 pgdat 三种主要数据结构来管理物理内存。
  • zone: 将物理内存划分为不同的区域,例如 DMA 区域、NORMAL 区域等。
  • page: 将物理内存划分为固定大小的页面,通常为 4KB。
  • pgdat: 每个 zone 对应一个 pgdat 结构,用于管理该 zone 中的页面分配。

inode 是用于管理文件系统中文件元数据的结构,与物理内存管理没有直接关系。

下面哪个选项是和进程控制块的组织无关的。

A.循环链表 B.等待队列 C.红黑树 D.哈希表

正确答案:C. 红黑树

  • 进程控制块 (PCB) 通常使用以下数据结构组织:
    • 循环链表: 所有进程的 PCB 通过循环链表链接在一起,方便遍历。
    • 等待队列: 处于阻塞状态的进程会根据等待的资源类型被放入不同的等待队列中。
    • 哈希表: 可以根据进程 ID 等信息快速查找对应的 PCB。

红黑树是一种自平衡二叉搜索树,通常用于维护有序的数据集,与 PCB 的组织没有直接关系。

模块编程对内存的申请可以通过调用kmalloc()。函数来实现,以下选项中哪一个与kmalloc()无关

A.kswapd B.kmemcachealloc C.通用高速缓存 D.slab

正确答案:A. kswapd

  • kmalloc() 是 Linux 内核中用于分配内存的常用函数,它从 slab 分配器中获取内存。
  • kmem_cachealloc() 是 slab 分配器的接口函数,kmalloc() 内部会调用它来分配内存。
  • 通用高速缓存slab 都是 Linux 内核中用于提高内存分配效率的机制,kmalloc() 基于 slab 分配器实现。

kswapd 是 Linux 内核中的守护进程,负责内存回收和交换,与 kmalloc() 的内存分配过程没有直接关系。

三.多选

这是因为二者所描述的目标不同,dentry 结构代表的是逻辑意义上的文件,所 描述的是文件逻辑上的属性,因此,目录项对象在磁盘上并没有对应的映像;而inode 结构 代表的是物理意义上的文件,记录的是物理上的属性,对于一个具体的文件系统(如Ext2), Ext2_ inode 结构在磁盘上就有对应的映像。

具体可以看看这个帖子

dentry结构代表的是__意义上的文件,所描述的是文件的__属性;

A.文件的 B.目录的 C.逻辑 D.物理

inode结构代表的是__意义上的文件,记录的是文件的__属性。其中之一在磁盘上有对应的映像,而另外一个则没有。

A.物理 B.逻辑 C.文件的 D.目录的

四.填空题

当内核与用户空间有大量数据传输时,Linux系统提供了____两个函数,用于用户态空间和内核态空间的数据交换。

copy_from_user()

copy_to_user()

进程控制块PCB是系统为了管理进程而设置的专门数据结构,它在Linux中的数据结构名是___

task_struct

Slab分配器直接工作于伙伴系统____(考核二者之间的关系)。

之上

Linux内核把目录当作___来处理,对其操作接口与文件的接口相同。

文件

Linux2.4内核中,x86体系结构在内核中的时钟中断频率为____HZ(每秒钟发生多少次时钟中断),而Linux 2.6内核时钟中断频率是2.4内核的10倍。

100

内核利用____来存放进程地址空间对应的虚拟内存区域(VMA)描述符节点,从而确保了内核能以最快速度访问指定的虚拟内存区域描述符。

红黑树

在x86架构下,Linux使用trap_init()和init_IRQO函数初始化系统中的中断描述符。其中__用于初始化中断向量号在0~31之间的不可屏蔽中断和异常所需的中断描述符,这些中断和异常由Intel预定义。而___主要用于初始化外部设备描述符。

前者 后者

内核通过访问宏___返回一个全局指针指向当前运行进程的进程控制块。

current

五.判断题

在Linux中,所有设备的I/O操作都必然是通过页高速缓存进行的。 ()

  1. 错误 在Linux中,所有设备的I/O操作 不一定 都要通过页高速缓存进行。有些设备可能使用直接内存访问 (DMA) 等技术绕过页高速缓存,直接与内存进行数据传输,以提高效率。

系统调用表存储在sys_call.table中,它与体系结构有关,一般在entry.s中定义。()

  1. 正确 系统调用表存储在 sys_call_table 中,它与体系结构有关,一般在 汇编代码 中定义,例如在 x86 架构下,可能在 entry_32.Sentry_64.S 中定义。

Linux定时器可以用来完成精确的定时操作,Linux能保证所提供的定时器处理函数不会在规定的时间之前执行,同时也保证该函数不会被推后执行。 ()

  1. 错误 Linux定时器 不能 用来完成精确的定时操作。
    • Linux 是抢占式操作系统,定时器中断的处理可能会被其他更高优先级的任务打断,因此不能保证定时器处理函数在规定的时间之前或之后执行。

x86是32位的体系结构,它只支持4GB的地址空间,其中3GB为用户空间保留,1GB分配给内核地址空间。 ()

  1. 正确 x86 是 32 (2^32==4GB) 位的体系结构,它只支持 4GB 的地址空间,其中 3GB 为用户空间保留,1GB 分配给内核地址空间。

在NUMA计算机系统的存储管理中,只有一个NODE,且内存是同质的。 ()

  1. 错误 在 NUMA 计算机系统的存储管理中, 有多个 NODE,每个 NODE 拥有自己的本地内存,内存是 异构 的。

在X86实模式下,中断矢量表放在内存的固定位置,而在保护模式下,中断矢量表放在GDTR所指向的位置。 ()

  1. 错误 在保护模式下,中断矢量表放在IDTR所指向的位置

如果页中没有任何地址被事先访问过,那么该页就尚未被载入内存。当第一次访问该页时便会产生一个系统调用来装载页,因为这时内存中并没有该页,必须从磁盘请求。()

  1. 错误 如果页中没有任何地址被事先访问过,那么该页就尚未被载入内存。当第一次访问该页时会产生一个 缺页异常 (Page Fault),这时操作系统会将该页从磁盘加载到内存中。系统调用是用户空间程序请求内核服务的接口,不负责处理缺页异常。

伙伴系统使用free_area数组来寻找和释放页面,伙伴系统把物理页面划分为不同的页面块,该数组中第一个元素描述1个页面大小的块,第二个元素表示2个页面大小的块而接下来的元素表示4个页面大小的块,总之都是2的N次幕倍大小。 ()

  1. 正确 伙伴系统使用 free_area 数组来寻找和释放页面,伙伴系统把物理页面划分为不同的页面块,该数组中第一个元素描述 1 个页面大小的块,第二个元素表示 2 个页面大小的块,而接下来的元素表示 4 个页面大小的块,以此类推,都是 2 的 N 次幂倍大小。

在Linux中创建一个线程与一个进程非常相似,线程就是轻量级的进程。 ()

  1. 正确 在 Linux 中创建一个线程与一个进程非常相似,线程可以看作是轻量级的进程,它们共享同一个地址空间和其他资源。

在Linux中,每个注册的文件系统实例都可以安装在现有文件系统目录树中的一个目录上。 ()

  1. 正确 在 Linux 中,每个注册的文件系统实例都可以安装在现有文件系统目录树中的一个目录上,这个目录被称为该文件系统的 挂载点
本文由作者按照 CC BY 4.0 进行授权