秋招面经笔记-操作系统&Linux串烧2
read
系统调用:- 参数检查:
- 检查文件描述符存在性
- 检查当前文件读写位置(通过
file_ppos
),该位置是file
对象的,不是文件的,也就是说,同一个文件的两个句柄存有不同的位置 - 检查权限(在
inode
结构中,如果没有权限,返回-EACCESS
)
- 调用
VFS
的读函数:- 普通文件:通过超级块和
inode
,使用块设备驱动读取到内核缓冲区,如果已经在缓存中,则直接使用,最后拷贝到用户空间 - 设备文件:调用设备驱动的
read
函数
- 普通文件:通过超级块和
- 更新文件位置,返回结果
- 参数检查:
write
系统调用:- 参数检查(同
read
) - 将数据从用户空间复制到内核缓冲区,调用
VFS
读函数- 普通文件:通过
inode
和超级块定位写文件位置,如果超出大小,则扩展(根据文件系统的不同而不同),然后通过块设备驱动写入磁盘 - 设备文件:调用设备驱动的
write
函数
- 普通文件:通过
- 更新文件位置,返回结果(成功写入的长度)
一般写时会有延迟写入,
write
会暂时保存在缓冲中,在合适的时候写入(比如umount
)- 参数检查(同
内核态和用户态:
- 内核态:权限高,可以执行所有CPU指令(包括特权指令),可以直接访问硬件
- 用户态:权限低,只能执行用户级别指令,不能直接访问硬件,需要使用资源时,需要借助系统调用等操作系统API
从用户态切入内核态:
- 异常和中断处理(被动)
- 系统调用(主动)
- 缺页异常(可以认为是主动)
中断现场保存在哪(
x86
):在内核栈上,中断发生时,CPU负责将当前指令位置和相关寄存器保存到内核栈上(中断帧),然后查询中断向量表进入中断处理函数;如果是在用户态触发,则由TSS段负责切换到内核栈(提权),再进入中断处理函数。内存屏障:控制CPU核心之间按照一定的顺序访问某块内存,防止由于CPU优化等导致的缓存不一致行为(保证其他核心看到的是修改后的数据),常用来实现同步原语、中断处理中的数据修改、外设IO操作等
Linux内存申请:
kmalloc
申请不仅虚拟内存和物理内存都连续的内存,可用于DMA,用于较小内存分配vmalloc
申请虚拟连续,物理不一定连续的内存,不可用于DMA__get_free_pages
伙伴系统,获取连续页
写时复制(COW):拷贝对象时不进行复制,而是先绑定引用,当其中一个对象进行修改时,为其复制这部分数据,提高内存的使用效率。操作系统中用于进程虚拟内存管理、现代语言的标准库中用来优化对象之间的拷贝。
Linux页大小:一般是
4KB
,但也支持2MB
大页,1GB
超大页4KB
页:大多数现代处理器原生支持4KB页- 大页:对于大量连续物理内存内存的场景可以减少TLB缺失,也可以减少所需页表条目大小,降低分页管理的开销。
页面异常(Page Fault):在访问虚拟页出现问题时触发(缺页异常、保护错误)
- 越界访问、非法地址等问题
- 页面可能在内存中(交换机制)
- COW,需要在中断中进行复制
- 共享库的延迟加载,需要加载器介入
更新日志
2025/9/1 05:34
查看所有更新日志
4bba0
-C++11于