共计 3608 个字符,预计需要花费 10 分钟才能阅读完成。
Linux 操作系统学习总结
BIOS 阶段
当机器按下电源键通电之后,执行的第一行代码是存储在只读存储器中的 BOIS 程序。BIOS 程序要实现的性能有:
- 查看机器各个硬件组件是否失常
- 检测启动盘
启动盘能够是 U 盘、磁盘、移动硬盘,它具备一个标识:设施的第一个扇区是疏导扇区,外面保留的是疏导程序(boot.img)。疏导程序会加载疏导程序的各个模块进入内存,最终会将启动盘上的内核信息以列表的通过显示器展现给用户,用户抉择一个操作系统内核之后,进入内核的启动阶段。
内核启动阶段
内核启动阶段会初始化各个内核模块,这些模块也能够叫做子系统。有工作管理子系统、内存管理子系统、文件管理系统等等。
内核程序在执行过程中创立的第一个过程,是用户态的过程的先人。第二个过程是内核态所有过程的先人。
内核态程序:治理硬件资源的程序,硬件资源是无限的,须要对立治理。
用户态程序:应用硬件资源,通常是应用零碎调用,运行内核程序,从而操作硬件。
程序执行过程
在 Linux 上,可执行的程序都是满足 elf 规范的文件。可执行程序由源代码通过编译失去二进制程序,也就是 elf 文件。一个过程通过执行 fork 调用,创立一个新的过程,新的过程是子过程,而执行 fork 调用的过程是这个新过程的父过程,子过程再通过 exec 零碎调用,将可执行文件加载到内存中,最终交给 CPU 执行。
elf 文件格式
- elf 文件头(文件总体形容)
- 程序指令
- 数据段
过程管理子系统
Linux 将每个过程都组织成一个 task 构造,一个 task 构造蕴含这些信息。
- 过程 id:每个过程都要一个 id, 是这个过程的惟一标识。
- 过程状态:TASK_RUNNING(过程可执行)、TASK_INTERRPTIBLE(睡眠状态,能够响应中断)、TASK_UNINTERRUPTIBLE(睡眠状态,不可中断,必须在条件满足之后才能够继续执行)、TASK_KILLABLE(睡眠状态,不可中断、能够响应致命信号)、EXIT_ZOMBIE(过程执行完结,父过程尚未获知其终止信息)、EXIT_DEAD(过程终止状态)
- 过程运行统计信息:在用户态、内核态耗费的工夫、上下文切换次数等等
- 过程间关系:父子关系、兄弟关系。
- 过程权限信息:对文件或目录的拜访权限、对别的过程的拜访权限、别的过程对本过程的拜访权限等。
- 占用的内存信息
- 占用的文件信息
线程
在 Linux 中,线程也是一个 task 构造,CPU 最终调度的对象就是 task。
任务调度
每个 CPU 有一个工作队列,CPU 在运行的时候就从队列中取一个工作(task)进去执行。任务调度能够有很多中调度形式,比方 fifo、lru、cfs 等等。罕用的是 cfs(Completely Fair Scheduling),即齐全偏心调度。齐全偏心调度算法根据 task 运行工夫、优先级来保障偏心。
调度机会:抉择具体的调度算法,解决了如何调度问题,而还有一个问题是何时调度。
- 被动让出 CPU:当一个过程执行 sleep 调用或者进行了阻塞 IO 操作,都会被动放弃 CPU,在内核中就会被动执行 schedule()函数来执行调度。
- 被动让出 CPU:过程执行工夫太长了,该让出 CPU 给别的过程应用。这种状况,会在以下几个非凡机会触发 schedule()函数。
- 对于用户态的过程来讲,从零碎调用中返回的那个时刻,是一个被抢占的机会。
- 对于用户态的过程来讲,从中断中返回的那个时刻,也是一个被抢占的机会。
- 对内核态的执行中,被抢占的机会个别产生在 preempt_enable() 中。在内核态的执行中,有的操作是不能被中断的,所以在进行这些操作之前,总是先调用 preempt_disable() 敞开抢占。再次关上的时候,就是一次内核态代码被抢占的机会。
- 在内核态也会遇到中断的状况,当中断返回的时候,返回的依然是内核态。这个时候也是一个执行抢占的机会。
内存管理子系统
在 Linux 零碎中,程序执行时拜访的指令地址、数据地址都是虚拟地址。每个程序都认为本人独占了整个物理内存。实际上,内存的每个字节只有一个惟一的地址,不同程序程序对于同一个地址的拜访最终会通过页表翻译为最终的物理地址,也就是虚拟地址翻译为物理地址。这样,每个程序都能够应用同一个虚拟地址,而对于同一个虚拟地址,最初会被翻译为不同的物理地址。
内存管理子系统须要实现以下性能:
- 物理内存的治理
- 虚拟内存的治理
- 虚拟内存到物理内存的映射
物理内存治理 :操作系统将内存分成节点,每个 CPU 先拜访离本人最近的内存节点(下图第二种)。
每个节点外面再分区域(zone),用于辨别不同的用法。每个区域外面再分页,默认大小为 4KB。一个页是每个程序应用内存的最小单位。分配内存的时候,以一个页的整数倍进行调配,这个整数是 1、2、4…1024。当一个页长时间不必了,能够临时写到磁盘,要用的时候在读回内存,这就是换入换出,这样能够减少物理内存的应用效率。
虚拟内存治理 :对于每个过程来说,内存分两个局部,一部分由内核程序应用(称为内核空间),剩下的局部全副归本人应用(称为用户空间)。用户过程不能拜访内核空间。
用户空间的内存,分段治理,每一段寄存不同的数据,elf 格局的程序加载到内存之后,各局部对应放到各个段。内核空间外面也会有内核的程序,同样有 Text Segment、Data Segment 和 BSS Segment,内核程序也是 elf 格局的。
虚拟内存到物理内存的映射:将虚拟内存地址转换为物理内存地址,须要应用页表。能够简略的将页表了解为一个映射构造,输出虚拟地址,输入物理地址。
文件系统
文件系统有两个状态,一种状态是磁盘上的文件系统,这是在对磁盘进行格式化的时候写入到磁盘的。另一种状态是内核中的文件系统。内核中的文件系统定义了对磁盘上文件系统的操作以及相应的数据结构。
在文件系统中,存储的最小单位为块,每个块默认是 4KB 大小。一个文件能够拆分为多个块进行寄存,因而须要有一个中央来记录文件都存在于哪些块,这是文件索引节点的须要提供的信息。
文件索引节点(inode)也是保留在块外面,每个文件对应一个 inode。在 inode 中,有以下的信息:
- 文件读写权限
- 文件属于的用户、用户组
- 文件大小
- 文件占用多少个块、每个块的地址信息
文件夹(目录):在文件系统的概念中,目录也是一种文件,每个目录也对应一个 inode。与一般文件不一样的是,目录中寄存的是下一级文件的文件名和对应的 inode,而一般文件外面寄存的就是数据内容。
Linux 内核程序在内存中保护了一套数据结构,用来记录哪些文件被哪些过程关上和应用,每个过程能关上的文件数量是有下限的,因而在开发中,用完文件之后要妥善敞开文件。
输入输出零碎
输入输出零碎,是对 IO 设施的进行治理的零碎。常见的 IO 设施分为两种:字符设施、块设施。输入输出零碎应用了层层形象来对 IO 设施进行管制。
- 应用设施控制器屏蔽设施差别
- 应用设施零碎程序屏蔽设施控制器差别
- 用中断控制器对立解决内部事件
- 用文件系统接口屏蔽驱动程序的差别
过程间通信机制
- 管道:单向数据传递。将前一个程序的输入作为后一个程序的输出。管道实际上以一段缓存。
- 音讯队列
- 共享内存 + 信号量
- 信号:内核机制,在非凡状况下会发出信号,用户的程序只有筹备信号处理函数就能够解决收到的信号。
网络通信
无论是 windows 还是 linux,网络模型是一样的。网络模型与具体的操作系统无关。不同机器之间要通信就要通过网络。一个应用层的信息要发送到另一台机器的利用,须要将音讯层层包装,加上各层协定的内容。指标机器收到网络包之后,逐层剔除协定,再依据端口好转发到对应的利用。
Socket 是用户态与内核态的连接体,用户态的程序通过 Socket 接口就能够实现网络通信,无需关怀各层协定细节。TCP、IP 协定都是在内核中实现的,不同的操作系统实现细节不一样。
虚拟化 & 容器化
虚拟化就是在操作系统上运行操作系统,使用这种技术,能够将一台大机器虚构为多个小机器。比拟好的一种虚构形式是半虚拟化(硬件辅助 + 半虚拟化驱动),启用硬件辅助技术之后,虚拟机的指令就能间接运行在宿主机的 CPU 上,不必通过翻译。半虚拟化驱动就是指应用非凡的、更高效的 IO 设施驱动,进步 IO 效率。
集群的操作系统
一台物理机器,最重要的四种硬件资源是 CPU、内存、存储和网络。对于一个集群,比如说数据中心,如何灵便的治理和调配一堆计算资源,是一个难题。
Kubernetes,数据中心的“操作系统”,能够灵便的实现少量的资源管理。其中,对于 CPU 和内存,能够利用 docker 容器技术。对于存储,无论是分布式文件系统和分布式块存储,Kubernetes 提供了接口,就行提供了驱动程序接口一样。对于网络,同样提供了标准接口只有对接这个对立的接口,Kubernetes 就能够治理容器的网络。。
docker 容器技术能够将 CPU 和内存资源,从大的资源池外面隔离进去,并通过镜像技术,在数据中心外面实现计算资源的自在漂移。