当前位置: 首页 > news >正文

Linux - 内存 - memblock 分配器

说明

  • memblock是Linux内核启动早期用于管理物理内存的机制,在伙伴系统(Buddy System)接管内存管理之前为系统提供物理内存分配、释放等功能。
  • 相对于伙伴系统,memblock功能和实现较为简单。
  • 本文基于:linux_5.10 arm64平台。

历史

  • 启动早期的内存管理器实现有bootmem和memblock,bootmem是早期内核采用,4.x以后内核内核采用memblock,配置了NO_BOOTMEM宏。
  • memblock取代了bootmem算法。

实现原理

获取物理内存布局

  • 不同于伙伴系统以内存页为操作对象,memblock以物理内存段为操作对象,系统从dtb或者uboot传递来的mem信息中解析出总的物理内存信息(核心信息是地址范围),此时的物理内存是一段段的地址空间,再初始化memblock。

fdt方式

  • dts配置中有memory的配置
* 单段物理内存
memory {device_type = "memory";reg = <0x0 0x80000000 0x0 0x10000000>;
};
* 多段物理内存
memory@0 {device_type = "memory";reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,<0x00000000 0x05f00000 0x00000000 0x00001000>,<0x00000000 0x05f02000 0x00000000 0x00efd000>,<0x00000000 0x06e00000 0x00000000 0x0060f000>,<0x00000000 0x07410000 0x00000000 0x1aaf0000>,<0x00000000 0x22000000 0x00000000 0x1c000000>;
};

uboot bootargs方式

  • uboot启动linux时,可以通过linux的启动参数bootargs,传递物理内存信息(基址和size),初始化memblock。
  • 格式如下:
mem=size@start
  • 配置流程
* 函数调用栈
early_mem  //file: arch/arm64/mm/init.c,解析出物理内存信息,保存在全局变量中
arm64_memblock_init //file: arch/arm64/mm/init.c 
->  memblock_add
* 核心代码
void __init arm64_memblock_init(void)
{...if (memory_limit != PHYS_ADDR_MAX) { //全局变量非默认值memblock_mem_limit_remove_map(memory_limit); memblock_add(__pa_symbol(_text), (u64)(_end - _text));}...
}

可用段查找原理

  • memblock内存分配时可用段查找采用first match算法,即占用首先找到的可以段。
  • 内存分配查找的方向可以是从高到低,也可以是从低到高,通过总context中的成员变量bottom_up决定。

两个阶段

  • memblock有两个阶段
  1. memblock init之前;主要是静态分配,根据dts配置中预留内存定义(reserved memory),内核本身(code等),dtb等,在物理内存上分配出所需的预留内存。
  2. memblock init之后,伙伴系统初始化完之前;主要是Linux内核机制产生的动态内存分配。
  • 两个阶段以以memblock configuration为分隔。

分配结果

  • memblock分配结果都是预留内存,分配结束后固定占用,无法释放和复用。

代码逻辑

  • memblock源码在Linux内核根目录下的:
include/linux/memblock.h 
mm/memblock.c 

数据结构和实例

  • memblock从大到小定义了三个数据结构,如下:
  1. 总context定义
struct memblock {bool bottom_up;  //内存分配的方向:从高到低(FALSE)、从低到高(TRUE)phys_addr_t current_limit; //最大内存地址struct memblock_type memory; //可管理的内存段struct memblock_type reserved; //预留内存
};
  1. 内存类型定义
struct memblock_type {unsigned long cnt; //内存区域个数(占用数组个数)unsigned long max; //最大区域个数(数组总个数)phys_addr_t total_size; //该内存类型总大小struct memblock_region *regions; //包含的内存区域数组char *name;
};
  1. 内存区域(地址段)定义
struct memblock_region {phys_addr_t base;  //基址phys_addr_t size;  //空间大小enum memblock_flags flags; //flag
#ifdef CONFIG_NUMAint nid;   //物理内存 node id,NUMA可以存在多个物理内存节点(node)
#endif
};enum memblock_flags {MEMBLOCK_NONE           = 0x0,  /* No special request */ //正常MEMBLOCK_HOTPLUG        = 0x1,  /* hotpluggable region */ //可插拔区域MEMBLOCK_MIRROR         = 0x2,  /* mirrored region */MEMBLOCK_NOMAP          = 0x4,  /* don't add to kernel direct mapping */ //no map区域
};
  • 总context实例,以全局静态变量(保存在BSS段中)形式定义,区域都是预先定义的全局静态数组,数组个数默认128(INIT_MEMBLOCK_REGIONS)。
static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock;
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS];
#endifstruct memblock memblock __initdata_memblock = {.memory.regions         = memblock_memory_init_regions,.memory.cnt             = 1,    /* empty dummy entry */.memory.max             = INIT_MEMBLOCK_REGIONS,.memory.name            = "memory",.reserved.regions       = memblock_reserved_init_regions,.reserved.cnt           = 1,    /* empty dummy entry */.reserved.max           = INIT_MEMBLOCK_RESERVED_REGIONS,.reserved.name          = "reserved",.bottom_up              = false,.current_limit          = MEMBLOCK_ALLOC_ANYWHERE,
};

API

  1. memblock_add
  • 将内存区域加入memblock可管理的内存区域,即memory的region队列。
  1. memblock_free
  • 将一个物理内存段从预留内存中移除,该内存段重新标记为可用。
int memblock_free(phys_addr_t base, phys_addr_t size)
{memblock_dbg("   memblock_free: [%#016llx-%#016llx] %pF\n",(unsigned long long)base,(unsigned long long)base + size - 1,(void *)_RET_IP_);kmemleak_free_part_phys(base, size);return memblock_remove_range(&memblock.reserved, base, size);
}

调试

  1. 获取memblock的详细分配log,可以通过在uboot bootargs中加入“memblock=debug”,内核启动后,通过dmesg或者/proc/kmsg查看调试信息。
  2. linux kernel启动后可以通过debug fs查看内存地址范围和reserved区域,如下:
/sys/kernel/debug/memblock/memory #交由系统管理的内存 
/sys/kernel/debug/memblock/reserved #预留的内存
* 需要开启配置
CONFIG_DEBUG_FS
CONFIG_ARCH_KEEP_MEMBLOCK //是否保留memblock分配信息
  • 该功能不是很有必要并且会占用一定硬件资源,方法1足以满足调试需求,新版本内核CONFIG_ARCH_KEEP_MEMBLOCK配置默认是关闭的。

交接

  • buddy分配器初始化ok后,memblock分配器将内存管理工作交接给buddy(伙伴)分配器。

标志

  • memblock和伙伴系统的交接标志:释放init进程内存(free_initmem函数处理),之后系统可用内存(/proc/meminfo中的MemTotal)就固定了。

分配实例分析

  • 分配实例

相关文章:

Linux - 内存 - memblock 分配器

说明 memblock是Linux内核启动早期用于管理物理内存的机制&#xff0c;在伙伴系统&#xff08;Buddy System&#xff09;接管内存管理之前为系统提供物理内存分配、释放等功能。相对于伙伴系统&#xff0c;memblock功能和实现较为简单。本文基于&#xff1a;linux_5.10 arm64平…...

SQL、Jdbc、JdbcTemplate、Mybatics

数据库&#xff1a;查询&#xff08;show、select&#xff09;、创建&#xff08;create)、使用(use)、删除(drop)数据库 表&#xff1a;创建&#xff08;【字段】约束、数据类型&#xff09;、查询、修改&#xff08;alter *add&#xff09;、删除 DML&#xff1a;增加(inse…...

四六级高频词组8

目录 词组 其他链接 词组 301. in fashion&#xff08;stylish&#xff0c; most modern&#xff09;时兴&#xff0c;流行 302. after the fashion &#xff08;of&#xff09; 依照… 303. find fault with&#xff08;complain about&#xff1b;criticize&#xff09;找…...

fastapi-amis-admin快速创建一个后台管理系统增加音乐管理功能(3)

感觉为了实现maui的效果。准备了一个后端及restful项目 &#xff0c;如同想吃鱼就健个鲁塘一下&#xff0c;但还是写一下吧。 fastapi_amis_admin 是一个功能强大的框架&#xff0c;旨在帮助开发者在使用 FastAPI 进行 web 开发时&#xff0c;能够快速创建一个高效且易于管理的…...

全球化需要先搬离中国?中国公司出海不应失去“模式自信”

中国企业出海近期热闹非凡&#xff0c;其中以短剧为代表的文化内容产业和跨境电商产业都吸引了大量关注。例如亚马逊在12月12日公布一组最新数据&#xff0c;亚马逊过去一年销售额超过1000万美金的中国卖家数量&#xff0c;同比增长接近30%。中国跨境电商平台在刚刚过去的“黑五…...

三大维度解码剑南春“高质量发展”丨年度盘点

执笔 | 洪大大 编辑 | 扬 灵 2023年即将画上句点&#xff0c;当我们回首这一年为行业带来惊喜的品牌&#xff0c;剑南春是其中之一。 回顾剑南春今年一整年的动作&#xff0c;从新品频发到双节&#xff08;618、双11&#xff09;热销&#xff0c;从全国巡展到荣誉满载&…...

外包干了3个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

思福迪运维安全管理系统 test_qrcode_b RCE漏洞复现

0x01 产品简介 思福迪运维安全管理系统是思福迪开发的一款运维安全管理堡垒机。 0x02 漏洞概述 由于思福迪运维安全管理系统 test_qrcode_b路由存在命令执行漏洞&#xff0c;攻击者可通过该漏洞在服务器端任意执行代码&#xff0c;写入后门&#xff0c;获取服务器权限&#…...

Salesforce×阿里云,影响几何?

实际上&#xff0c;从这个视角来看&#xff0c;Salesforce和阿里云的合作也恰在成为着这个市场的一个新催化剂。“期待Salesforce能给中国市场带来一些新的增量&#xff0c;包括对合作伙伴的态度&#xff0c;对产品的态度等等。”一位CRM相关人士告诉我们。 那么&#xff0c;阿…...

Qt对excel操作

Qt库中自带对excel操作的模块QAxObject&#xff0c;QAxObject是Qt提供给程序员从代码中访问Office的对象类&#xff0c;其本质上是一个面向微软操作系统的COM接口。 QAxObject将所有Office的工作簿、表格、文档等都作为其子对象&#xff0c;程序员通过调用querySubObject()这个…...

每日一练 | 华为认证真题练习Day148

1、关于RSTP协议提供的保护功能说法正确的有?&#xff08;多选&#xff09; A. Root保护功能只能在指定端口上配置生效 B. 环路保护功能只能在根端口或Alternate端口上配置生效 C. 启用防TC— BPDU报文攻击功能后&#xff0c;可以避免频繁的删除HAC地址表项 D. 交换设备上…...

ES6学习(二):解构赋值

前言 解构赋值是ES6中新提出的语法,简单并且实用,数组和对象都可以使用 数组解构赋值 规则 1.其实是按照顺序一一匹配的,就像排队领取物资一样,你领到什么就是什么,没有挑的份,你排的晚了什么都没领到,那就是undifined。 2.如果给分配的是一个数组,那可以在命名时外部嵌套…...

kubebuilder开发operator

安装kubebuilder前 需要有kubernetes环境和golang环境 官网&#xff1a;https://go.kubebuilder.io/ 安装kubebuilder #下载 wget https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH) #改名kubebuilder后加权限 chmod x kubebuilder #放到环境变量里 mv k…...

docker中启动ES报错:AccessDeniedException: /usr/share/elasticsearch/data/nodes

一、K8S部署的elasticsearch 6.8版本 数据持久化到本地磁盘 今天做elasticsearch数据迁移&#xff0c;直接 SCP拷贝至另外一台服务器 原服务器处理好后拷贝回来&#xff0c;然后启动elasticsearch报错 {"type": "server", "timestamp": "2…...

java集成Nacos服务

1&#xff0c;添加依赖&#xff1a;首先&#xff0c;在你的 Java 项目中&#xff0c;你需要添加 Nacos 客户端 SDK 的依赖 <dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>2.1.1</ve…...

开源IPad Pro应用IDE:使用SSH远程连接服务器进行云端编程开发

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…...

ubuntu 自动安装 MKL Intel fortran 编译器 ifort 及完美平替

首先据不完全观察&#xff0c;gfortran 与 openblas是 intel fortran 编译器 ifotr和mkl的非常优秀的平替&#xff0c;openblas连函数名都跟mkl一样&#xff0c;加了一个下划线。 1&#xff0c; 概况 https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-too…...

elementui select中添加新增标签

<el-select v-model"ruleForm.eventType" :placeholder"请选择事件类型&#xff0c;可手动添加" ref"template" clearable visible-change"(v) > visibleChange(v, template)"><el-option v-for"item in eventTypeOp…...

图像截屏公式识别——LaTeX-OCR安装与使用

一、简介 LaTeX-OCR 是一个开源的光学字符识别&#xff08;OCR&#xff09;软件&#xff0c;专为 LaTeX 文档提供支持。其主要目的是帮助用户将扫描的文档转换为 LaTeX 编辑器可以使用的可编辑文本&#xff0c;从而方便进行修改、编辑和排版。LaTeX广泛用于科技、数学、工程等…...

LabVIEW与Tektronix示波器实现电源测试自动化

LabVIEW与Tektronix示波器实现电源测试自动化 在现代电子测试与测量领域&#xff0c;自动化测试系统的构建是提高效率和精确度的关键。本案例介绍了如何利用LabVIEW软件结合Tektronix MDO MSO DPO2000/3000/4000系列示波器&#xff0c;开发一个自动化测试项目。该项目旨在自动…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...