linux内核-内存管理

news2024/9/29 21:30:54

linux内核内存管理

注意!内核空间和用户空间都是处于虚拟空间中

Linux的虚拟地址空间范围为0~4G,Linux内核将这4G字节的空间分为两部分

内核空间: 最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),而映射到物理内存中是从0x00000000地址开始

用户空间:较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF)(所有进程一起使用)

每个进程可以通过系统调用进入内核,所以Linux内核由系统内的所有进程共享。从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。

内核态的内存管理和用户态的内存管理方式不一样点:

  • 内核态虚拟地址到物理地址基本是直接映射,分配的物理内存是连续的(除vmalloc)。用户态会基于进程各自的页表,分配非连续的物理内存
  • 内核态会直接依赖物理内存的管理因为物理内存中有一部分内存只能被内核访问。用户态则需要多一层的虚拟地址空间到物理地址的转换

现代的操作系统都处于32位保护模式下。每个进程一般都能寻址4G的物理空间。我们的物理内存一般都是几百M,但是通过虚拟内存技术即可使进程获得4G 的物理空间使用

内核对于物理内存管理主要包括以下几个概念:

  • 分配块内存的伙伴系统;
  • 分配非连续内存块的vmalloc机制及内存映射机制;
  • 分配块内存的slab,slub和slob

32位内核内存空间分布图,64位不一样!

img

内核态空间分布 高地址 --> 低地址

ffff:ffff:ffff:ffff   +--------------------------+
                      |                          |
                      |                          |
                      z                          z
                      |                          |
                      |                          |
ffff:ffc0:b000:0000   |--------------------------|                       
                      |                          |                       
                      |     memory (2.75G)       |                       
                      |                          |                       
ffff:ffc0:0000:0000   +==========================+  <-- PAGE_OFFSET  
                      |                          |
                      |                          |
                      |                          |
                      |      vmemmap (4G)        |
                      | +----------------------+ |
                      | |    actual (44M)      | |
ffff:ffbf:0000:0000   +--------------------------+
                      |//|
ffff:ffbe:ffe0:0000   +--------------------------+
                      |     PCI I/O (16M)        |
ffff:ffbe:fee0:0000   +--------------------------+
                      |//|
ffff:ffbe:fec0:0000   +--------------------------+
                      |     fixed (4M)           |
ffff:ffbe:fe7f:d000   +--------------------------+
                      |//|
ffff:ffbe:bfff:0000   +--------------------------+
                      |                          |
                      |                          |
                      |                          |
                      |                          |
                      |                          |
                      |                          |
                      z     vmalloc (250G)       z
                      |                          |
                      |                          |
                      |                          |
                      |                          |
                      |                          |
                      |                          |
ffff:ff80:087c:f76c   | +----------------------+ |
                      | |        .bss          | |
                      | |        .data         | |
                      | |        .init         | |  Kernel
                      | |        .rodata       | |
                      | |        .text         | |
ffff:ff80:0808:0000   | +----------------------+ |
ffff:ff80:0800:0000   +--------------------------+
                      |     modules (128M)       |
ffff:ff80:0000:0000   +--------------------------+

以下内核日后学习了会继续补充

/*
在内核中(以下所涉及的栈都指内核栈):
模块地址往往是`0xffff ffff c000 0000` 的偏移比如函数地址`0xffffffffc00000f0` (babydevice为例)
栈地址往往是`0xffff c900 0000 0000`的偏移比如->`0xffffc900001b7e90` 
slub分配的object地址往往是`0xffff888000000000`的偏移比如`0xffff888007198340` 
*/

slub分配器使用

在这里插入图片描述

kmem_cache数据结构

在这里插入图片描述

slab分配器的对象单位–>管理自己的kmem_cache–>kmem_cache存在于slab_caches双链表中

kmem_cache里的一些小slab对象–>存在于“kmem_cache_node->partial”中 --> 每个node对应于kmem_cache_node数组项

kmem_cache里的另一部分小slab对象–>存在于“kmem_cache_cpu->partial”中

slab中没有被使用的对象称为空闲对象(free object),同一slab中的所有空闲对象被串成了一个单项链表(freelist),每个空闲对象的首地址 + kmem_cache->offset处会保存下一个空闲对象的地址,这样就形成了一个单链表

分配对象

在这里插入图片描述

有了上面的kmem_cache结构体就可以通过kmem_cache_alloc()分配对象在分配时有如下情况:

  • fast path:直接从本地cpu缓存中的freelist拿到可用object
  • slow path:本地cpu缓存中的freelist为NULL,但本地cpu缓存中的partial中有未满的slab
  • very slow path:本地cpu缓存中的freelist为NULL,且本地cpu缓存中的partial也无slab可用。

内存管理是按大小块管理的具体可看cat /proc/slainfo 大小相同的会物理相邻

专用高速缓存是由kmem_cache_creat()函数创建的,专门使用与特殊类型的对象

普通高速缓存使用kmalloc()进行分配

释放对象

在这里插入图片描述

函数定义:

/*分配一块给某个数据结构使用的缓存描述符
  name:对象的名字   size:对象的实际大小  align:对齐要求,通常填0,创建是自动选择。   flags:可选标志位    ctor: 构造函数 */
struct kmem_cache *kmem_cache_create( const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void*));
/*销毁kmem_cache_create分配的kmem_cache*/
int kmem_cache_destroy( struct kmem_cache *cachep);

/*从kmem_cache中分配一个object  flags参数:GFP_KERNEL为常用的可睡眠的,GFP_ATOMIC从不睡眠 GFP_NOFS等等等*/
void* kmem_cache_alloc(struct kmem_cache* cachep, gfp_t flags);
/*释放object,把它返还给原先的slab*/
void kmem_cache_free(struct kmem_cache* cachep,  void* objp);

常见的pwn题使用kmem_cache_alloc_trace如下:(ctf linux内核-内存管理slub分配器)

int __cdecl sudrv_init()
{
  int v0; // eax
  __int64 v1; // rdi

  printk("\x016SUCTF 2019 SUDriver\n");
  v0 = _register_chrdev(0xE9LL, 0LL, 0x100LL, "meizijiutql", &fops);
  v1 = kmalloc_caches[12];
  su_fd = v0;
  su_buf = (char *)kmem_cache_alloc_trace(v1, 0x480020LL, 0x1000LL);// 
                                                // kmem_cache_alloc_trace(cachep, flags,size);
  return 0;
}

kmem_cache_alloc_trace函数就是kmem_cache_create + kmem_cache_alloc这样就通过slub分配器分配了一块内存了

参考资料

https://blog.csdn.net/u012489236/article/details/108188375(写的很容易理解)

https://zhuanlan.zhihu.com/p/166649492

https://cloud.tencent.com/developer/news/646104(写的很全)

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

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

相关文章

RTSP,RTP,RTCP协议

一 RTSP 1 简介 实时流传输协议&#xff0c;是一个应用层协议&#xff08;TCP/IP网络体系中&#xff09;&#xff0c;它是一个多媒体播放控制协议&#xff0c;主要用来使用户在播放流媒体时可以像操作本地的影碟机一样进行控制&#xff0c;即可以对流媒体进行暂停/继续、后退和…

SAP FICO 关于资产的详细解析

SAP资产模块概述 一、概述 资产&#xff08;AA&#xff09;模块是资产会计模块的简称&#xff0c;是财务会计&#xff08;FI&#xff09;模块的一个子模块&#xff0c;主要处理与各类长期资产相关业务的模块。不单指固定资产&#xff0c;也不泛指资产负债表中的资产&#xff0c…

Week4

1.试题 历届真题 时间显示【第十二届】【省赛】【B组】 思路 不难发现,应该从小时往秒处理,这样可以用O(1)的时间复杂度求出,不过有比较麻烦的进位处理。 先看里面可以拼成几个小时,然后得到的小时%24,然后把总时间减去小时的时间,再看有多少分钟,分钟%60,都是此时判断分…

vue多环境配置之 .env配置文件

Vue之.env环境配置文件 .env文件是运行项目时的环境配置文件。但是在实际开发过程中&#xff0c;有本地环境、测试环境、预生产、生产环境等等&#xff0c;不同环境对应的配置会不一样。因此&#xff0c;需要通过不同的.env文件实现差异化配置。 * 文章目录Vue之.env环境配置文…

【JAVA核心知识】46:什么是零拷贝Zero-copy

零拷贝相较于传统的IO流程拥有更高的数据发送效率&#xff0c;无论是RocketMq,Kafka还是Netty等都用到了零拷贝技术&#xff0c;那究竟什么是零拷贝呢&#xff0c;零拷贝又是通过什么方式提升数据发送效率呢&#xff1f; 首先我们要明白&#xff0c;一次数据发送过程就是将磁盘…

Java基础--方法

前言&#xff1a;介绍 Java 中方法的基本语法、分类、执行并分析参数传值。 关键字&#xff1a;方法、形参、实参、返回值、实例方法、静态方法、参数传值 程序引例–为什么要「方法」 public class IntroduceOfMethod {// 入口主方法。public static void main(String[] args…

docker 高级篇

一、DockerFile 1.1、概述 dockerfile 是用来构建docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 为什么要有dockerfile呢 在基础篇我们讲过&#xff0c;比如我们下载个 ubuntu镜像里面不包含 vim、ifconfig等组件&#xff0c;这个时候 新增…

DES加密算法

DES算法原理 对称密码算法中的分组加密算法&#xff08;对应于流密码&#xff09; 密钥64位&#xff0c;56位参与运算8位校验位&#xff08;校验位为&#xff1a;8、16、24、32、40、48、56、64&#xff09; 加密原理 1. IP置换 将明文数据转化为二进制数&#xff0c;并将它…

Lnix文件权限的修改

首先我们要清楚Linux文件的权限信息 在Linux中输入ls -l 或者 ll查看文件和目录的详细信息 文件详情实例中&#xff0c;a目录的第一个属性用“d”标识这个a是一个目录。 anaconda-ks.cfg第一个属性用“-”标识他是一个文件。 在Linux文件详情的后面属性需要分为三组查看 rwx&am…

三种调用机制: 同步调用、异步调用、回调(同步/异步)

c并发编程-01-并发与并行_发如雪-ty的博客-CSDN博客 c并发编程02-什么是I/O_发如雪-ty的博客-CSDN博客 c并发编程03-I/O多路复用_发如雪-ty的博客-CSDN博客 c并发编程04-同步与异步_发如雪-ty的博客-CSDN博客_c同步和异步 c并发编程05-什么是回调函数_发如雪-ty的博客-CSDN…

Web前端:使用ReactJS构建的应用类型

使用ReactJS&#xff0c;你可以构建各种各样的应用程序&#xff0c;包括单页应用程序、渐进式web应用程序、移动应用程序、仪表板、电子商务平台、企业web应用程序以及社交媒体和消息应用程序。1.单页应用程序(spa)单页应用程序(SPA)基本上是一个网页&#xff0c;它通过使用从w…

MySQL(七):undo日志——保证事务的原子性

目录一、前言1.1 如何回滚事务1.2 事务id1.3 roll pointer 隐藏列1.4 trx_id 隐藏列二、undo日志2.1 undo日志的格式2.2 insert 对应的undo日志2.3 delete 操作对应的undo日志2.4 update操作对应的undo日志2.5 Undo页面链表2.6 undo日志写入过程2.6.1 Undo Log Header2.7 回滚段…

springboot请求参数绑定原理篇

上篇文章写了SpringBoot 参数接收只看这一篇文章就够了&#xff0c;只是写了使用方法&#xff0c;没有写为什么&#xff0c;原理是什么&#xff0c;这篇文章也是之前的预先的计划&#xff0c;稍微花点时间整理下&#xff0c;知其然知其所以然&#xff0c;才算是能彻底掌握&…

如何用IDEA创建SpringBoot项目

一、创建一个 Spring Initializr 工程 next后选择2.7.8版本&#xff0c;勾选以下几个 Web里的spring bootTemplate Engines 里的 ThymeleafSQL里的MyBatis Framework 和 Mysql Driver 然后finish完成 二、配置resources文件 2.1、 application.properties&#xff1a; #??…

Docker容器命令无权限,WEB访问403

问题背景(描述) 部署dockerWeb后&#xff0c;重启访问403,详细如下 docker容器正常运行,且开机自启 #通过如下命令开机自启 docker update --restart always 容器id但是访问web服务出现403. 进入容器后,输入命令提示如下: 解决方案 关闭selinux SELinux(Security-Enhanced…

【网络安全】记一次红队渗透实战项目

前言 【一一帮助安全学习&#xff08;网络安全面试题学习路线视频教程工具&#xff09;一一】 一、信息收集 信息收集非常重要&#xff0c;有了信息才能知道下一步该如何进行&#xff0c;接下来将用nmap来演示信息收集 1、nmap扫描存活IP 由于本项目环境是nat模式需要项目…

【Java基础】——面向对象:封装

【Java基础】——面向对象:封装一、类和对象二、类的结构&#xff1a;属性、方法、构造器1、属性2、方法2.1、方法的定义2.2、方法的重载2.3、可变个数的形参2.4、方法参数的值传递机制3、构造器3.1、构造器的特征3.2、构造器的作用&#xff1a;3.3、构造器重载三、封装与隐藏1…

细菌,真菌,病毒——感染,免疫反应以及治疗用药差异

谷禾健康 与人类密切相关的微生物 我们的世界大到浩瀚宇宙&#xff0c;小到微观下的生物分子。我们总说漫天繁星&#xff0c;其实身边微生物数量可能更多。动物、植物、真菌、细菌、病毒等&#xff0c;共同构成了丰富多彩的生命世界。 细菌、真菌、病毒是其中的三个大类&#x…

spring integration使用:消息路由

系列文章目录 …TODO spring integration开篇&#xff1a;说明 …TODO spring integration使用&#xff1a;消息路由 spring integration使用&#xff1a;消息路由系列文章目录前言消息路由的概念二、路由的分类基于内容的路由器spring integration中的实现RecipientListRoute…

Python property()函数:定义属性

我们一直在用“类对象.属性”的方式访问类中定义的属性&#xff0c;其实这种做法是欠妥的&#xff0c;因为它破坏了类的封装原则。正常情况下&#xff0c;类包含的属性应该是隐藏的&#xff0c;只允许通过类提供的方法来间接实现对类属性的访问和操作。因此&#xff0c;在不破坏…