本书基于linux 2.6介绍了linux内核的设计与实现,涵盖了从核心内核系统的应用到内核设计与实现等各方面内容,主要内容包括:进程管理、调度、时间管理和定时器、系统调用接口、内存寻址、内存管理、页缓存、vfs、内核同步、可移植性、调试技术等。此外,本书还讨论了linux 2.6颇具特色的内容,包括cfs调度程序、抢占式内核、块i/o层以及i/o调度程序。 本书详细描述了linux内核的主要子系统和特点,包括其设计、实现和接口,既介绍理论也讨论具体应用,填补了linux内核理论和实践细节之间的鸿沟。能够带领读者快速走进linux内核世界,真正开发内核代码。 如果你是一名linux内核爱好者,本书的内容可以帮助你大显身手。如果你是一名普通程序员,本书的内容将会拓宽你的编程思路。如果你初次接触linux内核,本书则可以帮助你对内核各个核心子系统有一个整体把握。 本版新增内容: ·增加一章专门描述内核数据结构 ·详细描述中断处理程序 ·扩充虚拟内存和内存分配的内容 ·调试linux内核的技巧 ·内核同步和锁机制的深度描述 ·提交内核补丁以及参与linux内核社区的建设性建议
Linux下的进程也好,线程也罢,在内核中统统都以任务(task)的面目示人,他们用一样的内核数据结构来表示。
BPF 是 Linux 内核中基于寄存器的虚拟机,可安全、高效和事件驱动的方式执行加载至内核的字节码。与内核模块不同,BPF 程序经过验证以确保它们终止并且不包含任何可能锁定内核的循环。BPF 程序允许调用的内核函数也受到限制,以确保最大的安全性以防止非法的访问。
BTF(BPF Type Format)是内嵌在BPF(Berkeley Packet Filter)程序中的数据结构描述信息。BPF原本是用于数据包过滤的编程语言,但随着eBPF(extended BPF)的发展,它的用途已经扩展到多种内核子系统中,包括性能监测、网络安全和配置管理等。 BTF是为了实现更复杂的eBPF程序而设计的。其提供了一种机制,通过它可以将编程时使用的数据结构(如C语言中的结构体、联合体、枚举等)的信息嵌入到eBPF程序中。这样做的主要目的是为了让eBPF程序在运行时能够具有类型安全(Type Safety),同时也便于内核和用户空间的程序理解和操作这些数据结构。 在eBPF程序开发过程中,用户通常会在用户空间编写C代码,然后使用特定的编译器(如clang)编译这些代码为eBPF字节码。由于C程序中定义的复杂数据结构信息在编译为eBPF字节码过程中会丢失,因此BTF被设计来保留这些信息。当eBPF程序加载到内核时,BTF信息可以被内核使用,以确保程序操作的数据结构与内核预期的一致,从而保证程序的正确运行。 举个例子,如果eBPF程序需要访问内核数据结构,BTF就能够提供这些内核数据结构的确切布局,让eBPF程序能够安全而准确地读取或修改这些数据。 总之,BTF使得eBPF程序能更安全且方便地与复杂的数据类型互动,并有助于提高eBPF程序与内核间的兼容性和稳定性。
其实不想用这个题目的,只因为TCP相关的东西比较吸引人的眼球,这篇文章的主题还是eBPF,而不是TCP。
版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/84202404
冯诺依曼体系结构是计算机体系结构中的一种基本设计原则,它描述了计算机系统的组成和运作方式。该体系结构由计算机科学家约翰·冯·诺伊曼(John von Neumann)于20世纪中期提出,被广泛应用于现代计算机系统的设计和实现中。
最后,再说一点,英语非常重要。很多好的资料都是英文的,国内有些翻译本不是太好。尤其是google搜索时,学会使用英文关键词非常重要。
注意除了用offsetof宏之外, printf(“%d\n“, &(((struct foo*)0)->c));也是一种办法
前言:在了解完冯诺依曼体系结构和操作系统之后,我们进入了Linux的下一篇章Linux进程,但在学习Linux进程之前,一定要阅读理解上一篇内容,理解“先描述,再组织”才能更好的理解进程的含义。
本文介绍了地址空间和二级页表、Linux下的线程、线程的优缺点以及线程与进程的关系等概念。
在上一篇文章中介绍了提高socket性能的几个socket选项,其中给出了几个源于内核源码树中的例子,如果选择使用内核树中的Makefile进行编译的话,可能会出现与本地头文件冲突的情况,如重复定义变量,结构体类型不对等错误。这些问题大大影响了BPF程序的可移植性。
通过此次实验,我将近花了一周的时间去弄懂操作系统linux-2.4.22内核的代码,由于确实在上万行代码的浏览中有些乏力所以写了大量的注释,参考了部分博客,也查阅了大量的资料,回答了实验六要求的六个问题,并提出自己的改进策略:
很多时候,我们要监控系统状态,即监控系统cpu负载、进程状态等情况,如果我们在 Linux 应用层,我们有很多方式,命令行中常用 top、ps 命令,代码中,我们可以使用 popen 函数去执行一个 top 命令,获取返回值。或者我们直接读写 /proc下面的文件,都可以达到目的。
自旋锁:如果内核配置为SMP系统,自旋锁就按SMP系统上的要求来实现真正的自旋等待,但是对于UP系统,自旋锁仅做抢占和中断操作,没有实现真正的“自旋”。如果配置了CONFIG_DEBUG_SPINLOCK,那么自旋锁按照SMP系统来编译。
进程在内核态运行时需要自己的堆栈信息,linux内核为每个进程都提供了一个内核栈。对每个进程,Linux内核都把两个不同的数据结构紧凑的存放在一个单独为进程分配的内存区域中:
每一种技术的出现必然是因为某种需求。正因为人的本性是贪婪的,所以科技的创新才能日新月异。
1. 通过之前的学习我们知道,每个进程都有自己独立的内核数据结构,例如PCB,页表,物理内存块,mm_struct,所以具有独立性的进程之间如果想要通信的话,成本一定是不低的。
1. 关于信号这个话题我们其实并不陌生,早在以前的时候,我们想要杀死某个后台进程的时候,无法通过ctrl+c热键终止进程时,我们就会通过kill -9的命令来杀死信号。 查看信号也比较简单,通过kill -l命令就可以查看信号的种类,虽然最大的信号编号是64,但实际上所有信号只有62个信号,1-31是普通信号,34-64是实时信号,这篇博文不对实时信号做讨论,只讨论普通信号,感兴趣的老铁可以自己下去研究一下。
我们可以轻松地通过图形化界面查看当前电量百分比、是否在充电以及当前电量还可以使用多长时间等电池状态,但是却无法查看电池健康度等相关信息。
先看基础常识: 基础 内核在创建进程的时候,会为进程创建相应的堆栈。 每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。 当进程在用户空间运行时,CPU寄存器里面的内容是用户堆栈地址,使用用户栈 当进程在内核空间时,CPU寄存器里面的内容是内核栈空间地址,使用内核栈。 切换过程: 当发生系统调用时,用户态的程序发起系统调用。用户态程序权限不足,因此会中断执行,发生中断后,当前CPU执行的程序会中断,跳转到中断处理程序。内核程序开始执行,
epoll是一种事件轮询,是Linux特有的。它允许一个进程监视多个文件描述符,并在对它们进行I/O操作时获取通知。它允许边缘触发和级别触发通知。在我们研究epoll的内部之前,首先让我们研究一下语法。
epoll是一种事件轮询,是Linux特有的。它允许一个进程监视多个文件描述符,并在对它们进行I/O操作时获取通知。它允许边缘触发和级别触发通知。在我们研究epoll的内部之前,首先让我们研究一下语法。
让CPU只和内存打交道,那么整机的效率就由内存决定。内存比CPU要慢,但是比外设要快的多。
我们看到这里面就展示了当前正在运行的进程,那大家看这其实就是我们当前打开的程序嘛
BPF是近年来Linux 系统技术领域一个巨大的创新。作为 Linux 内核的一个关键发展节点,其重要程度不亚于虚拟化、容器、SDN 等技术。
内核线程没有独立的地址空间,这是因为内核线程是在操作系统内核空间中运行的,内核空间本身是所有进程共享的。以下是一些更详细的解释:
下面我们介绍一些方法来获取系统的版本,首先是通过查看Linux内核的方法,主要有2种方法:
最新 Linux 内核是 5.15 版本。现在常用 Linux 内核源码为4.14、4.19、4.9 等版本,其中 4.14 版本源码压缩包大概 90+M,解压后 700+M,合计 61350 个文件。如此众多的文件,用 source insight 或者 VSCode 查看都会比较卡,所以可以采用在线查看的方式。
学习进程,我们需要对计算机操作系统 有一个初步的了解,也就是经典的冯诺依曼体系: 计算机的逻辑结构。冯·诺依曼从逻辑入手,他的逻辑设计具有以下特点: (1)将电路、逻辑两种设计进行分离,给计算机建立创造最佳条件; (2)将个人神经系统、计算机结合在一起,提出全新理念,即生物计算机。 符合人们的一般认知:
注:本文包括了ebpf的原理介绍、流程分析、相关资料链接、工具编写实战等,可以选择感兴趣的部分直接阅读;鉴于作者语文水平有限,很多地方描述可能不清楚,有错误或疑问欢迎指出交流
有读者反馈,单看零碎的知识点,自己心中没底。还是看书更有框架一些,所以今天给大家推荐一些经典书籍,书籍电子版我已经发到百度网盘群。
假设有一个富翁,私生子比较多,但是彼此不知道各自的存在 大富翁给A花了大饼,说等他死后,10亿家产都是A的,同样的大饼大富翁也给B、C、D画上了, A 、B、C、D四个人都认为大富翁死后自己继承10亿家产 A找到大富翁,想要5万块买个表,大富翁答应了 D打电话给大富翁说想要5亿美金,摆平社会上的事,大富翁拒绝了 无论是A要到了,还是D没要到,每一个人依旧认为未来自己一定会具有10亿美金 大富翁给每一个人画的饼叫做 进程地址空间
对于进程间通信,想必管道大家再熟悉不过了,对于管道这种通信方式,其实是对底层代码的一种复用,linux工程师借助类似文件缓冲区的内存空间实现了管道,其实也算偷了一个小懒,随着linux的发展,linux正式推出了System V来专门进行进程间通信,它和管道的本质都是一样的,都是让不同的进程看到同一份资源。
Linux系统中,应用程序访问外设是通过文件的形式来进行的,Linux将所有的外设都看做文件,统一存放在/dev目录下。
前段时间,我们的项目组在帮客户解决一些操作系统安全领域的问题,涉及到windows,Linux,macOS三大操作系统平台。无论什么操作系统,本质上都是一个软件,任何软件在一开始设计的时候,都不能百分之百的满足人们的需求,所以操作系统也是一样,为了尽可能的满足人们需求,不得不提供一些供人们定制操作系统的机制。当然除了官方提供的一些机制,也有一些黑魔法,这些黑魔法不被推荐使用,但是有时候面对具体的业务场景,可以作为一个参考的思路。
近日的工作多多少少和Linux的流控有点关系。自打几年前知道有TC这么一个玩意儿而且多多少少理解了它的原理之后,我就没有再动过它,由于我不喜欢TC命令行,实在是太繁琐了。iptables命令行也比較繁琐,可是比TC命令行直观,而TC命令行则太过于技术化。
到目前为止,内存管理是unix内核中最复杂的活动。我们简单介绍一下内存管理,并通过实例说明如何在内核态获得内存。
嵌入式软件通常是指嵌入式系统中运行的软件,嵌入式系统是一种特殊的计算机系统,通常用于控制、监测和数据处理等任务。嵌入式系统通常由硬件和软件两个部分组成,其中嵌入式软件是指在嵌入式系统中运行的程序,用于控制硬件并提供特定的功能和服务。嵌入式软件应用广泛,包括汽车、医疗设备、智能家居、智能穿戴、工业自动化等众多领域。
事实上大部分程序员并没有系统化的学习过,也有很多人并没有机会好好运用它。所以,如果拉一个工作多年的程序员讨论,对方未必能说出个所以然。
在前文中我们了解了fork函数的使用,以及写时拷贝机制的原理等,并且也学习了什么是僵尸进程,但是并没有具体讲到应如何处理僵尸进程,本次章节将对fork函数以及如何终止进程,还有僵尸进程的处理做更为详细的探讨。
链表(Linked List)是一种基本的数据结构,用于组织和管理数据。它是由一系列节点(Node)组成的数据结构,每个节点包含一个数据元素和指向下一个节点的引用。链表是一种非线性数据结构,与数组不同,它可以根据需要动态分配内存。
当我们涉猎的范围越来越广之后我们会发现,每一种语言都有其对应的文件操作,包括面向过程语言C、面向对象语言C++/java、静态编译语言go、解释型语言python,甚至包括脚本语言shell 等等,最令人苦恼的是这些语言的文件操作接口都不相同,导致我们的学习成本非常高。
传统的多核运算是使用SMP(Symmetric Multi-Processor )模式:将多个处理器与一个集中的存储器和I/O总线相连。所有处理器只能访问同一个物理存储器,因此SMP系统有时也被称为一致存储器访问(UMA)结构体系,一致性意指无论在什么时候,处理器只能为内存的每个数据保持或共享唯一一个数值。
https://www.zhihu.com/question/462048846/answer/1919407185
领取专属 10元无门槛券
手把手带您无忧上云