《深入Linux内核架构》第1章 简洁和概述

目录

1.1 内核的任务

1.2 实现策略

1.3 内核的组成部分

​1.3.1 进程、进程切换、调度

1.3.2 UNIX 进程

1.3.3 地址空间和特权级别

1.3.4 页表

1.3.5 物理内存的分配

1.3.6 计时

1.3.7 系统调用

1.3.8 设备驱动程序

1.3.9 网络

1.3.10 文件系统

1.3.11 模块和热插拔

1.3.12 缓存

1.3.13 链表处理

1.3.14 对象管理和引用计数

1.3.15 数据类型

1.3.16 本书的局限性

1.4 为什么内核是特别的

1.5 行文注记

1.6 小结


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

本章是概述,如有不懂,欢迎阅读后续章节。

1.1 内核的任务

管理系统软硬件资源。

1.2 实现策略

常见操作系统有两类实现:

        微内核:中央内核+子模块(文件系统,内存管理,网络)

                优点:可动态拓展。

                缺点:模块间通信负荷大。

        宏内核:单内核,所有功能在一个内核镜像中。

                优点:模块间通信简单高效,因为都在同一个地址空间。

Linux为宏内核,但引入微内核的模块特性。

1.3 内核的组成部分


1.3.1 进程、进程切换、调度

后续章节讲。

1.3.2 UNIX 进程

init:第一个运行进程,由内核启动。

pstree命令:查看进程关系拓扑。

Unix系统中创建新进程机制:fork和exec

        Linux独有创建新进程机制:clone

fork:采用写时拷贝, 内存复制操作延迟到子进程或父进程写内存。若只读,父子进程共享同一内存页。

命名空间namespace:

        内核2.6开始引入,用于支持容器虚拟化,和KVM的虚拟化机制不同。

页帧:物理内存页。

页: 虚拟内存地址空间页。

内核可决定物理内存哪些区域可被多个应用进程共享,哪些区域不共享。

1.3.3 地址空间和特权级别

CPU字长:

        含义:CPU一次能并行处理的二进制位数。

        决定了可管理地址空间的最大长度。

由task_struct可知:内核中"task"指用户空间进程。

所以TASK_SIZE指用户空间。

32位系统为例:

        TASK_SIZE = 3G,即每个进程的用户空间0-3G。

        3G-4G内核空间是所有进程共享的,每创建一个进程,就创建一个内核栈(THREAD_SIZE),大小为8或16KB。

        所有进程的内核栈,都存在于3G-4G虚拟地址空间中。

传统X86 CPU有4种特权级别:最高ring 0、ring 1、ring 2、ring 3最低。

但Linux设计之初只使用两种:

        ring 0:内核态

        ring 3:用户态

后来Linux虚拟化需要比ring 0更高的特权级别,如KVM+QEMU中,KVM和QEMU分别都需要不同的特权级别。

所以X86 CPU新增4个特权级别,即root mode的ring0-ring3,原来的ring0-ring3变为non-root mode的ring0-ring3。

如下图:

1.3.4 页表

页表:一个保存了虚拟地址空间到物理地址空间映射关系的数据结构。

页帧:一个物理内存页。

        页帧号:该物理页编号。

一个进程的整个虚拟地址空间通常不会同时映射到物理内存。

        如:

                1. 需要使用时才换入内存时,建立映射表。

                2. 内存不足时换出到硬盘交换分区。

虚拟地址空间中未使用或未映射的区域,不必创建页目录和页表,可节省内存。

页表:为减少页表占用内存,采用多级页表。

全局页表(第一级页表)的物理地址放到页表基址寄存器PTR中:

        X86中的PTR:CR3寄存器。

        ARM-v7:协处理器CP15的寄存器TTBR。

        ARM-v8:系统寄存器TTBR。

TTBR:Tranlation Table Base Register

CR3:Control Register 3

四级页表:使用四个数组,而PGD,PMD,PTE,Offset值都作为对应数组的索引。

MMU:Memory Management Unit,CPU内部的一个单元。

        功能:

                完成虚拟地址到物理地址的转换。

                缓存页表。

MMU内包含两部分:

        TLB:(Translation Lookaside Buffer),用于缓存页表。

        TWU:(Table Walk Unit),执行查询页表。

TLB未命中:没有缓存到虚拟地址对应的物理地址映射,此时才进行四级页表转换。

当页表更改,需使TLB内容无效。

VA:虚拟地址。

PA:物理地址。

1.3.5 物理内存的分配

通过查看页表项中的PG_xx标志。可知对应页帧是已分配或空闲。

内核可按整页分配内存。

        也可按字节分配,如kmalloc。

伙伴系统:

        目标:

                用于分配连续页。

                解决内存碎片问题。

     

          当应用程序释放内存时,若相邻内存块都空闲则合并成更大页,并放回到伙伴列表中。

        分配粒度:页。

slab缓存

        将从伙伴系统分配的页划分为更小的部分 ,用于缓存频繁使用的数据结构,如:task_struct,mm_struct

        kmalloc也基于slab机制,对应slab数据结构是kmalloc-32,kmalloc-16等。

        slab缓存自动维护与伙伴系统的交互,在缓存用尽时从伙伴系统请求新的页帧。

页面交换swap

        内存不足时,将页内容交换到磁盘空间。

        被换出的页的页表项有特殊标识:PG_swapcache。

        进程访问该标志的页帧时,CPU发出缺页异常,然后内核从硬盘读数据到内存。

1.3.6 计时

每次定时器中断会更新内核全局变量jiffies。

        jiffies:系统从启动以来的时钟滴答数(tick)。

HZ常量:每秒时钟滴答次数,即每秒jiffies会增加HZ数。

        如系统启动5秒后:jiffies = HZ * 5。HZ值通常为100、250、1000。

1.3.7 系统调用

系统调用原理:

        1. 使用int 0x80或syscall指令,触发系统调用中断。

        2. 执行中断服务程序ISR。

        3. 从EAX寄存器中读取系统调用号。

        4. ISR执行系统调用号对应处理函数。

        5. 通过寄存器或栈传递函数返回值给用户空间。

        6. 用户程序恢复执行。

系统调用号是有限的,所有可能多个系统调用一个号,如socket,bind,connect等都会调用SYSTEM_socket,具体通过参数区分。

x86常用的寄存器EAX、EBX、ECX、EDX

0x80号中断对应的中断处理程序是system_call。

1.3.8 设备驱动程序

字符设备:

        连续数据流,按字节为单位读写。

        只能顺序读取,不支持随机存取。

块设备:

        可随机存取某区域,不需要按顺序。

        只能以块(通常512B)为单位读写。

        通常有缓存机制。

1.3.9 网络

网卡不能通过设备文件访问。

1.3.10 文件系统

inode:存储文件属性。包含:

        文件类型:普通文件、目录、符号链接等。

        文件权限:读、写、执行。

        文件大小。

        文件的访问和修改时间。

        文件数据的物理磁盘位置。

Ext2特点:

        inode也存储在磁盘上,目录也表示为普通文件。

        (inode:存储文件属性。)

一个目录文件的内容是:该目录下所有文件的inode指针。

1.3.11 模块和热插拔

热插拔原理:

        1. 内核检测热插拔。

        2. 内核调用modprobe/hotplug等应用程序。

        3. 加载相应驱动或子系统。

1.3.12 缓存

块设备的缓存管理:

        分配内存页面。

        映射块设备数据:将块设备的数据映射到分配的页面上。

        缓存管理:当需要访问块设备时,先检查缓存中是否存在所需的数据。如果存在,直接访问缓存中数据,而无需访问实际的块设备。

        数据同步:修改块设备数据后,将数据从缓存写回到块设备上,确保数据同步。

1.3.13 链表处理

struct list_head {

        struct list_head *next, *prev;

};

表头struct list_head *p;

void list_add(struct list_head *new, struct list_head *head) //从表头插入

{

        __list_add(new, head, head->next);

}

void list_add_tail(struct list_head *new, struct list_head *head)//从表尾插入

{

        __list_add(new, head->prev, head);

}

void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)

{

        new->next = next;

        new->prev = prev;

        next->prev = new;

        prev->next = new;

}

int list_empty(struct list_head *head)

{

        return head->next == head;

}

1.3.14 对象管理和引用计数

kset kobj ktype作用:

        用于设备模型。

        构建内核中的对象系统。

总结:

    kobject:

                表示内核中的各种实体。

    kset:

                表示内核对象的集合,可组织和管理这些对象。

                可有一个或多个子 kset,形成父子关系的树形结构。

        ktype:

                定义了 kobj对象的属性、方法。如提供/sys中对象对应的读写函数。    

struct kobject {

        const char *name;

        struct list_head entry; 用于将当前对象链接到父对象中。

        struct kobject *parent; 父对象

        struct kset *kset; 所属kset

        struct kobj_type *ktype;

        struct kernfs_node *sd; /* sysfs directory entry */

        struct kref kref; 引用计数

};

kobject相关函数:

        kobject_get,kobject_put,kobject_register,kobject_add

struct kset {         //作用:归类

        struct list_head list; 连接该kset集合所有kobject

        spinlock_t list_lock;

        struct kobject kobj; 该kset所有kobject的父对象。

        struct kset_uevent_ops *uevent_ops; 生成uevent事件给hotplug进程,实现热插拔功能。

}

struct kobj_type {         //即ktype,作用:提供sysfs文件系统接口

        const struct sysfs_ops *sysfs_ops;

        struct attribute **default_attrs;

};

引用计数kref值封装在一个结构中,以防止直接+/-操作该值。必须使用对应API,如:

        kref_get(struct kref *kref);

        kref_put();

1.3.15 数据类型

pid_t,sector_t,struct kref: 这些变量不能直接访问,需通过指定函数。

MIPS CPU可同时支持大小端,需设置。

cpu_to_le64:将64位数据转成小端。

不存在cpu_to_le8函数,因为8位数据(char)大小端都一样。如下图:

判断大小端的代码:

int num = 0x11223344;

int isBigEnd()

{

        int *p = #

        char *p2 = (char*)p;

        if (*p2==0x11){

                return 1;

        }

        return 0;

}

per-cpu变量:

        多处理器中为每个CPU都分配一个值。数据在各自CPU缓存中,可快速访问不同CPU缓存中,避免同步加锁。

        定义方法:

                DEFINE_PER_CPU(type, name)

        读写变量值:

                int value = get_cpu_var(per_cpu_var);

                        //读写操作...

                put_cpu_var(per_cpu_var);

__user:表示该指针属于用户地址空间。

1.3.16 本书的局限性

1.4 为什么内核是特别的

许多体系不支持非对齐的内存访问。

1.5 行文注记

1.6 小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC实战——StyleGAN(Style-Based Generative Adversarial Network)

AIGC实战——StyleGAN 0. 前言1. StyleGAN1.1 映射网络1.2 合成网络1.3 自适应实例归一化层1.4 风格混合1.5 随机变化 2. StyleGAN 生成样本3. StyleGAN23.1 权重调制与解调3.2 路径长度正则化3.3 非渐进式增长 4. StyleGAN2 生成样本小结系列链接 0. 前言 StyleGAN (Style-Ba…

安卓的认证测试

1 CTS CTS 是 Android 兼容性测试套件,用于验证设备是否符合 Android 平台的兼容性标准。它包含一系列测试用例,涵盖了设备的各个方面,如硬件功能、软件功能、API 的正确实现等。通过 CTS 测试,设备厂商可以确保其设备符合 Andro…

学习笔记:解决拖延

1 解决拖延,减轻压力的关键心态和方法 1.1 要点梳理 拖延是因为自己一直在逃避,重点是要有效突破逃避圈,进入学习圈,扩展成长圈。 毒蛇曲线(见思维导图)中越是临近截止期限,拖延的焦虑越上升…

VRRP虚拟路由实验(思科)

一,技术简介 VRRP(Virtual Router Redundancy Protocol)是一种网络协议,用于实现路由器冗余,提高网络可靠性和容错能力。VRRP允许多台路由器共享一个虚拟IP地址,其中一台路由器被选为Master,负…

C++初阶:6.string类

string类 string不属于STL,早于STL出现 看文档 C非官网(建议用这个) C官网 文章目录 string类一.为什么学习string类?1.C语言中的字符串2. 两个面试题(暂不做讲解) 二.标准库中的string类1. string类(了解)2. string类的常用接口说明(注意下面我只讲解…

设计模式总结-装饰者模式

模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增…

Golang-Gin 框架写的免杀平台,内置分离、捆绑等多种BypassAV方式

Golang-Gin 框架写的免杀平台,内置分离、捆绑等多种BypassAV方式 Golang-Gin 框架写的免杀平台,内置分离、捆绑等多种BypassAV方式。 cool 时间线: Golang Gin 框架写的免杀平台- (2021.11.12)Golang Gin 框架写的免杀平台,更…

环境监测站升级选择ARM网关驱动精准数据采集

物联网技术的深入发展和环保需求的不断攀升,API调用网关在环境监测领域的应用正成为科技创新的重要推手。其中,集成了API调用功能的ARM工控机/网关,以其出色的计算性能、节能特性及高度稳定性,成功搭建起连接物理世界与数字世界的…

【教程】App打包成IPA文件类型的四种方法

摘要 本教程总结了将App应用程序打包为IPA包的四种常用方法,包括Apple推荐的方式、iTunes拖入方法、自动编译脚本和解压改后缀名方法。每种方法都有其特点和适用场景,在实际开发中可以根据需求选择合适的方式进行打包。通过本教程,您将了解到…

微服务(狂神)

什么是微服务: 微服务方案: 1. SpringCloud NetFlix 2. Dubbo 3. SpringCloud Alibaba 解决了什么问题: 1. 服务过多,客户端怎么访问 2. 服务过多,服务间怎么传值 3. 服务过多,如何治理 4. 服务过多…

美团一面4/9

面的时候自我感觉良好,复盘感觉答的一坨。。 0怎么比较两个对象 0Integer 不使用new会自动装箱,返回提前创建的。使用new就创建新对象。 1.Object类有什么方法 java中Object类中有哪些常用方法以及作用_java中object的方法有什么用-CSDN博客 2.hash…

基于JSP的网上订餐系统

第一章 绪论 1.1课题背景与意义 自新世纪以来,我国经济发生翻天覆地的变化。中国经济发展迎来空前巨大的机遇与挑战,世界性的发展交流在这三十年较近四十年的时间中整体性上升发展,东西文化的碰撞,不断为国民经济的发展注入新鲜…

大话设计模式——19.责任链模式(Chain of Responsibility Pattern)

简介 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 主要有两个核心行为:1.处理请求;2.将请求传递到下一节点 U…

“AI”科普丨Transformer架构图解最强教程!

今天给大家分享一篇关于深度学习模型Transformer的文章。我愿称之为讲解Transformer模型最好的文章。 文章内容主要介绍 Transformer 模型的具体实现: Transformer整体架构 Transformer概览 引入张量 自注意力机制Self-Attention 多头注意力机制Mutil-Head Att…

算法四十天-删除排序链表中的重复元素

删除排序链表中的重复元素 题目要求 解题思路 一次遍历 由于给定的链表是排好序的,因此重复的元素在链表中的出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。 具体地,我们从指针cur指向链表的头节…

光子学,能否催生下一代计算革命?

研究和技术开发在光子计算领域正迅猛增长,其产品也逐渐融入市场。这一新兴的计算技术革命预计将对科学家和工程师的研究能力产生深远影响。 光子技术在加速大规模计算基础设施的数据处理速度方面展现出巨大的潜力,同时有可能显著降低网络及通讯的能耗。该…

解析大语言模型训练三阶段

大语言模型的训练过程一般包括3个阶段:预训练(Pre-training)、SFT(有监督的微调,Supervised-Finetuning)以及RLHF(基于人类反馈的强化学习,Reinforcement Learning from Human Feedb…

第一届长城杯初赛部分wp(个人解题思路)

目录 Black web babyrsa2 APISIX-FLOW cloacked 本人不是很擅长ctf,这只是我自己做出的西部赛区部分题的思路,仅供参考 Black web 访问http://192.168.16.45:8000/uploads/1711779736.php 蚁剑连接 访问/var/www/html/u_c4nt_f1nd_flag.php babyr…

艾瑞咨询最新发布《2024年中国采购数字化平台行业研究报告》,企企通市场份额稳居第一!

导读 根据艾瑞咨询统计,以SRM和ERP背景的厂商为主,企企通以18.5%的市场份额,稳居国内采购数字化平台市场第一位置。 近日,国内知名研究机构艾瑞咨询发布《2024年中国采购数字化平台行业研究报告》(以下简称”《报告》…

HJ1 字符串最后一个单词的长度(字符串,import java.util.HashSet;)

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int num sc.nextInt();boolean[] in new boolean[…