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有两个阶段
- memblock init之前;主要是静态分配,根据dts配置中预留内存定义(reserved memory),内核本身(code等),dtb等,在物理内存上分配出所需的预留内存。
- memblock init之后,伙伴系统初始化完之前;主要是Linux内核机制产生的动态内存分配。
- 两个阶段以以memblock configuration为分隔。
分配结果
- memblock分配结果都是预留内存,分配结束后固定占用,无法释放和复用。
代码逻辑
- memblock源码在Linux内核根目录下的:
include/linux/memblock.h
mm/memblock.c
数据结构和实例
- memblock从大到小定义了三个数据结构,如下:
- 总context定义
struct memblock {bool bottom_up; //内存分配的方向:从高到低(FALSE)、从低到高(TRUE)phys_addr_t current_limit; //最大内存地址struct memblock_type memory; //可管理的内存段struct memblock_type reserved; //预留内存
};
- 内存类型定义
struct memblock_type {unsigned long cnt; //内存区域个数(占用数组个数)unsigned long max; //最大区域个数(数组总个数)phys_addr_t total_size; //该内存类型总大小struct memblock_region *regions; //包含的内存区域数组char *name;
};
- 内存区域(地址段)定义
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
- memblock_add
- 将内存区域加入memblock可管理的内存区域,即memory的region队列。
- 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);
}
- …
调试
- 获取memblock的详细分配log,可以通过在uboot bootargs中加入“memblock=debug”,内核启动后,通过dmesg或者/proc/kmsg查看调试信息。
- 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内核启动早期用于管理物理内存的机制,在伙伴系统(Buddy System)接管内存管理之前为系统提供物理内存分配、释放等功能。相对于伙伴系统,memblock功能和实现较为简单。本文基于:linux_5.10 arm64平…...
SQL、Jdbc、JdbcTemplate、Mybatics
数据库:查询(show、select)、创建(create)、使用(use)、删除(drop)数据库 表:创建(【字段】约束、数据类型)、查询、修改(alter *add)、删除 DML:增加(inse…...
四六级高频词组8
目录 词组 其他链接 词组 301. in fashion(stylish, most modern)时兴,流行 302. after the fashion (of) 依照… 303. find fault with(complain about;criticize)找…...
fastapi-amis-admin快速创建一个后台管理系统增加音乐管理功能(3)
感觉为了实现maui的效果。准备了一个后端及restful项目 ,如同想吃鱼就健个鲁塘一下,但还是写一下吧。 fastapi_amis_admin 是一个功能强大的框架,旨在帮助开发者在使用 FastAPI 进行 web 开发时,能够快速创建一个高效且易于管理的…...
全球化需要先搬离中国?中国公司出海不应失去“模式自信”
中国企业出海近期热闹非凡,其中以短剧为代表的文化内容产业和跨境电商产业都吸引了大量关注。例如亚马逊在12月12日公布一组最新数据,亚马逊过去一年销售额超过1000万美金的中国卖家数量,同比增长接近30%。中国跨境电商平台在刚刚过去的“黑五…...
三大维度解码剑南春“高质量发展”丨年度盘点
执笔 | 洪大大 编辑 | 扬 灵 2023年即将画上句点,当我们回首这一年为行业带来惊喜的品牌,剑南春是其中之一。 回顾剑南春今年一整年的动作,从新品频发到双节(618、双11)热销,从全国巡展到荣誉满载&…...
外包干了3个月,技术退步明显.......
先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...
思福迪运维安全管理系统 test_qrcode_b RCE漏洞复现
0x01 产品简介 思福迪运维安全管理系统是思福迪开发的一款运维安全管理堡垒机。 0x02 漏洞概述 由于思福迪运维安全管理系统 test_qrcode_b路由存在命令执行漏洞,攻击者可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限&#…...
Salesforce×阿里云,影响几何?
实际上,从这个视角来看,Salesforce和阿里云的合作也恰在成为着这个市场的一个新催化剂。“期待Salesforce能给中国市场带来一些新的增量,包括对合作伙伴的态度,对产品的态度等等。”一位CRM相关人士告诉我们。 那么,阿…...
Qt对excel操作
Qt库中自带对excel操作的模块QAxObject,QAxObject是Qt提供给程序员从代码中访问Office的对象类,其本质上是一个面向微软操作系统的COM接口。 QAxObject将所有Office的工作簿、表格、文档等都作为其子对象,程序员通过调用querySubObject()这个…...
每日一练 | 华为认证真题练习Day148
1、关于RSTP协议提供的保护功能说法正确的有?(多选) A. Root保护功能只能在指定端口上配置生效 B. 环路保护功能只能在根端口或Alternate端口上配置生效 C. 启用防TC— BPDU报文攻击功能后,可以避免频繁的删除HAC地址表项 D. 交换设备上…...
ES6学习(二):解构赋值
前言 解构赋值是ES6中新提出的语法,简单并且实用,数组和对象都可以使用 数组解构赋值 规则 1.其实是按照顺序一一匹配的,就像排队领取物资一样,你领到什么就是什么,没有挑的份,你排的晚了什么都没领到,那就是undifined。 2.如果给分配的是一个数组,那可以在命名时外部嵌套…...
kubebuilder开发operator
安装kubebuilder前 需要有kubernetes环境和golang环境 官网: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数据迁移,直接 SCP拷贝至另外一台服务器 原服务器处理好后拷贝回来,然后启动elasticsearch报错 {"type": "server", "timestamp": "2…...
java集成Nacos服务
1,添加依赖:首先,在你的 Java 项目中,你需要添加 Nacos 客户端 SDK 的依赖 <dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>2.1.1</ve…...
开源IPad Pro应用IDE:使用SSH远程连接服务器进行云端编程开发
🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…...
ubuntu 自动安装 MKL Intel fortran 编译器 ifort 及完美平替
首先据不完全观察,gfortran 与 openblas是 intel fortran 编译器 ifotr和mkl的非常优秀的平替,openblas连函数名都跟mkl一样,加了一个下划线。 1, 概况 https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-too…...
elementui select中添加新增标签
<el-select v-model"ruleForm.eventType" :placeholder"请选择事件类型,可手动添加" ref"template" clearable visible-change"(v) > visibleChange(v, template)"><el-option v-for"item in eventTypeOp…...
图像截屏公式识别——LaTeX-OCR安装与使用
一、简介 LaTeX-OCR 是一个开源的光学字符识别(OCR)软件,专为 LaTeX 文档提供支持。其主要目的是帮助用户将扫描的文档转换为 LaTeX 编辑器可以使用的可编辑文本,从而方便进行修改、编辑和排版。LaTeX广泛用于科技、数学、工程等…...
LabVIEW与Tektronix示波器实现电源测试自动化
LabVIEW与Tektronix示波器实现电源测试自动化 在现代电子测试与测量领域,自动化测试系统的构建是提高效率和精确度的关键。本案例介绍了如何利用LabVIEW软件结合Tektronix MDO MSO DPO2000/3000/4000系列示波器,开发一个自动化测试项目。该项目旨在自动…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
