即便在如此简单的一个环境中,网络包的发送过程,竟然如此的复杂。TCP/UDP->IPv4->ARP 这一条链。
共享内存和信号量的配合机制。
信号的发送与处理是一个复杂的过程
在用户程序里面,有两个函数可以调用,一个是 signal,一个是 sigaction,推荐使用 sigaction。
管道、消息队列、共享内存、信号
对于块设备的 I/O 操作分为两种,一种是直接 I/O,另一种是缓存 I/O。无论是哪种 I/O,最终都会调用 submit_bio 提交块设备 I/O 请求。
块设备比字符设备复杂多了,涉及三个文件系统。
中断是从外部设备发起的,会形成外部中断。外部中断会到达中断控制器,中断控制器会发送中断向量 Interrupt Vector 给 CPU。
字符设备的打开、写入最常见的操作。
输入输出需要层层屏蔽差异化的部分,给上层提供标准化的部分,最终到用户态,给用户提供了基于文件系统的统一的接口。
在系统调用层需要仔细学习 read 和 write。在 VFS 层调用的是 vfs_read 和 vfs_write 并且调用 file_operation。在 ext4 层调用的是 ext4_file_read_iter 和 ext4_file_write_iter。接下来就是分叉。你需要知道缓存 I/O 和直接 I/O。直接 I/O 读写的流程是一样的,调用
解析系统调用是了解内核架构最有力的一把钥匙。
无论是文件夹还是文件,都有一个 inode。inode 里面会指向数据块,对于文件夹的数据块,里面是一个表,是下一层的文件名和 inode 的对应关系,文件的数据块里面存放的才是真正的数据。
文件通过文件夹组织起来,可以方便用户使用。为了能够更快读取文件,内存里会分配一块空间作为缓存,让一些数据块放在缓存里面。
对于内核态,kmalloc 在分配大内存的时候,以及 vmalloc 分配不连续物理页的时候,直接使用伙伴系统,分配后转换为虚拟地址,访问的时候需要通过内核页表进行映射。
用户态内存映射函数 mmap,包括用它来做匿名映射和文件映射。用户态的页表结构,存储位置在 mm_struct 中。
如果有多个 CPU,那就有多个节点。每个节点用 struct pglist_data 表示,放在一个数组里面。每个节点分为多个区域,每个区域用 struct zone 表示,也放在一个数组里面。每个区域分为多个页。为了方便分配,空闲页放在 struct free_area 里面,使用伙伴系统进行管理和分配,每一页用 struct page 表示。
进程要运行起来需要以下的内存结构:用户态和内存态。
内存管理系统精细化为下面三件事情:第一,虚拟内存空间的管理,将虚拟内存分成大小相等的页;第二,物理内存的管理,将物理内存分成大小相等的页;第三,内存映射,将虚拟内存页和物理内存页映射起来,并且在内存紧张的时候可以换出到硬盘中。
一个 CPU 上有一个队列,CFS 的队列是一棵红黑树,树的每一个节点都是一个 sched_entity,每个 sched_entity 都属于一个 task_struct,task_struct 里面有指针指向这个进程属于哪个调度类
函数调用的用户态与内核态
进程亲缘关系维护的数据结构,是一种很有参考价值的实现方式,在内核中会多个地方出现类似的结构。
线程是如何运行的
一个进程从代码到二进制到运行时的一个过程
Linux内核初始化的过程
Linux 内核初始化的过程
从BIOS到bootloader是如何运行的
Linux学习路线
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号