Linux内核设计与实现的方法是什么

39次阅读
没有评论

共计 3784 个字符,预计需要花费 10 分钟才能阅读完成。

今天丸趣 TV 小编给大家分享一下 Linux 内核设计与实现的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

 

Unix 强大的根本原因:

Unix 简洁, 提供几百个系统调用, 设计目的明确

Unix 中 所有东西都被当做文件对待

Unix 内核和相关系统工具是用 C 语言开发的, 移植能力强大

Unix 进程创建迅速, 有独特的 fork 机制

Unix 提供简单稳定的进程间通信元语

Linux 是类 Unix 系统, 借鉴了 Unix 设计并实现了 Unix 的 API.

应用程序通常调用库函数 (如 C 库函数) 再由库函数通过系统调用界面, 让内核代其完成各种任务.

Linux 支持动态加载内核模块

Linux 支持对称多处理 (SMP) 机制

Linux 为 抢占式内核

Linux 并不区分线程和其他的一般进程

Linux 提供具有设备类的面向对象的设备模型, 热插拔事件, 以及用户控件的设备文件系统

中断和中断处理

中断是一种解决处理器和速度差异的方案, 只有在硬件需要的时候再向内核发出信号. 中断本质上是一种特殊的电信号.

内核响应特定中断, 然后 内核 调用特定的 中断处理程序 , 终端处理程序是设备驱动程序的一部分

Linux 中的终端处理程序是不可重入的, 同一个中断处理程序不会被同时调用

中断上下文不可以睡眠(我理解当前被中断的程序再中断处理结束后需要继续执行)

中断处理程序不在进程上下文中进行, 他们不能阻塞

中断处理分为两部分, 上半部为中断处理程序, 要求尽可能快的执行, 下半部 (用于减少中断处理程序的工作量  ) 执行与中断处理密切相关但中断处理程序本身不执行的工作

下半部的实现方法 软中断、tasklet、工作队列 ,

中断机制的实现: 设置产生中断, 通过电信号给处理器的特定管脚发送一个信号, 处理器听着当前处理工作, 关闭中断系统 ,   然后调到内存中预定义的位置 (中断处理程序的入口点) 开始执行. 计算终端号, do_IRQ() 对接收的中断进行应答, 禁止这条线上的中断传递.

内核同步

对于共享资源, 如果同时被多个线程访问和操作, 就可能发生各线程之间相互覆盖共享数据, 造成访问数据不一致.

同步实现通过主要 锁机制 对共享资源进行加锁, 只有持有锁的线程才能操作共享资源, 其他线程睡眠(或者轮询). 资源操作完成后, 持有锁的线程释放锁,   由等待线程抢锁.

内核同步方法:

原子操作

自旋锁 , 特性是当线程无法获取锁, 会一直忙循环 (忙等) 等待锁重新可以, 适用于短期轻量级加锁

读 / 写自旋锁 (共享 / 排它锁), 一个或多个任务可以并发的持有读者锁, 写者锁只能被一个写任务持有.

信号量 (睡眠锁), 如果一个任务试图获得一个被占用的信用量时, 信号量会将其推进一个等待队列, 然后让其睡眠. 当信号量可用后,   等待队列中的任务会被唤醒. 适用于锁被长期占用的时候.

mutex(计数为 1 的信号量), 这个是编程中最常见的.

顺序锁

屏障 (barriers), 用于确保指令序列和读写的执行顺序

内核中造成并发的原因:

中断, 几乎可以再任何时刻异步发生, 可能随时打断当前正在执行的代码

软中断和 tasklet, 内核能在任何时刻唤醒或调度软中断或 tasklet, 打断当前正在执行的代码

内核抢占

睡眠及与用户空间的同步

对称多处理, 多个处理器同时执行代码

内存管理

内核把物理页作为内存管理的基本单位, 内存管理单元(MMU, 管理内存并将虚拟地址转换为物理地址) 通常以页为单位来管理系统中的页表.

内核把也划分为不同的区(zone), 使用区对具有相似特性的页进行分组

//  linux/gfp.h   该函数分配 2 的 order 次方个连续 ` 物理页 `,  返回指针指向 *** 个页的 page 结构体  staticinlinestructpage * alloc_pages(gfp_tgfp_mask,unsignedintorder) //  释放物理页  externvoidfree_pages(unsignedlongaddr,unsignedintorder); // linux/slab.h 以字节为单位分配一块内核内存(物理上连续) static__always_inlinevoid*kmalloc(size_tsize,gfp_tflags) // 释放 kmalloc 分配的内存块  voidkfree(constvoid*);

虚拟文件系统

虚拟文件系统为用户控件程序提供了文件和文件系统相关接口.

文件的元数据, 被存储在一个单独的数据结构中, 被称为 inode (索引节点)

虚拟文件系统 (VFS) 有四个主要的对象模型:

超级块对象, 代表一个具体的已安装文件系统, 存储特定文件系统的信息

索引节点对象, 代表一个具体文件, 包含内核在操作文件或目录时需要的全部信息, 一个索引节点代表文件系统中的一个文件,

目录项对象, 代表一个目录项, 是路径的一个组成部分, VFS 把目录当做文件处理 , 目录项对象没有对应的磁盘数据结构

文件对象, 代表进程打开的文件, 进程直接处理的是文件

//  linux/fs.h   文件对象的数据结构  structfile { union{ structllist_node fu_llist; structrcu_head fu_rcuhead; } f_u; structpath f_path; structinode *f_inode;/* cached value */ conststructfile_operations *f_op; /* * Protects f_ep_links, f_flags. * Must not be taken from IRQ context. */ spinlock_tf_lock; atomic_long_tf_count; unsignedintf_flags; fmode_tf_mode; structmutex f_pos_lock; loff_tf_pos; structfown_struct f_owner; conststructcred *f_cred; structfile_ra_state f_ra; u64 f_version; #ifdefCONFIG_SECURITY void*f_security; #endif /* needed for tty driver, and maybe others */ void*private_data; #ifdefCONFIG_EPOLL /* Used by fs/eventpoll.c to link all the hooks to this file */ structlist_head f_ep_links; structlist_head f_tfile_llink; #endif/* #ifdef CONFIG_EPOLL */ structaddress_space *f_mapping; } __attribute__((aligned(4)));/* lest something weird decides that 2 is OK */

块 I / O 层

系统中能够 随机访问 固定大小数据片 (chunks) 的硬件设备称作块设备, 如硬盘. 按照字符流的方式被 有序访问 的硬件设备称为字符设备,   如键盘

#  linux/bio.h I/ O 设备基本容器由 bio 结构体表示

I/ O 调度程序 用于管理块设备的请求队列, 决定队列中的请求排列顺序以及什么时刻派发请求到挂设备. 这样有利于减少磁盘的寻址时间,   从而提高全局的吞吐量

linux 实际使用的 I / O 调度程序有 linux 电梯, 最终期限 I / O 调度, 预测 I / O 调度程序, 空操作的 I / O 调度程序

进程地址空间

内核需要管理用户空间中进程的内存, 这个内存称为 进程地址空间 , 系统中所有进程之间以虚拟方式共享内存.

进程地址空间由进程可寻址的虚拟内存组成, 每个进程有 32 位或 64 位地址空间.

虚拟地址空间, 可被访问的合法地址空间称为 内存区域 :

可执行文件代码的内存映射, 称为代码段

可执行文件的已初始化全局变量的内存映射, 称为数据段

包含未初始化全局变量,bss(block started by symbol)段的零页的内存映射

用于进程用户空间栈的零页内存映射

每一个如 C 库或动态链接程序等共享库的代码段、数据段和 bss 会被载入进程的地址空间

任何内存映射文件

任何共享内存段

任何匿名的内存映射, 如 malloc 分配的内存

内核使用内存描述符结构体表示进程的地址空间, 内存描述符由 mm_struct(linux/sched.h)结构体表示.   内核线程没有进程地址空间, 也没有相关的内存描述符, 所有内核线程没有用户上下文

应用程序操作的对象是 映射到物理内存上的虚拟内存 , 而处理器操作的是物理内存, Linux 使用三级页表完成地址转换, 每个虚拟地址作为索引指向页表,   页表项则指向下一级的页表. 在多级页表中通过 TLB(translate lookaside buffer)作为一个虚拟地址映射到物理地址的缓存

以上就是“Linux 内核设计与实现的方法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,丸趣 TV 小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计3784字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)