麒麟系统在FT2000+下预留连续物理内存空间

news2024/12/25 12:56:52

1、背景介绍

项目需要在系统下预留一段连续物理地址空间供FPGA启动DMA直接写入,这样提高读写带宽。目前有两种方式可以实现该需求。

注意:前提是操作系统将内存空间访问权限全部放开,否则无法预留空间。

2、实现方法

方式一:

直接修改grub.cfg,添加memmap参数从内存的物理地址开始预留需要的空间,如下:

上图中圈出来的0xc00000000这段内存地址是BIOS里面配置的,八通道32G的FT2000+内存物理地址分配如下:

	memory@0 {
		device_type = "memory";
		reg = <0x000 0x00000000 0x002 0x00000000>;
		numa-node-id = <0>;
	};

	memory@1 {
		device_type = "memory";
		reg = <0x002 0x00000000 0x002 0x00000000>;
		numa-node-id = <1>;
	};

	memory@2 {
		device_type = "memory";
		reg = <0x004 0x00000000 0x002 0x00000000>;
		numa-node-id = <2>;
	};

	memory@3 {
		device_type = "memory";
		reg = <0x006 0x00000000 0x002 0x00000000>;
		numa-node-id = <3>;
	};

	memory@4 {
		device_type = "memory";
		reg = <0x008 0x00000000 0x002 0x00000000>;
		numa-node-id = <4>;
	};

	memory@5 {
		device_type = "memory";
		reg = <0x00A 0x00000000 0x002 0x00000000>;
		numa-node-id = <5>;
	};

	memory@6 {
		device_type = "memory";
		reg = <0x00C 0x00000000 0x002 0x00000000>;
		numa-node-id = <6>;
	};

	memory@7 {
		device_type = "memory";
		reg = <0x00E 0x00000000 0x002 0x00000000>;
		numa-node-id = <7>;
	};

重启后通过cat /proc/iomem就能查看是否预留成功,成功会有显示

注:下图只是示例,不是预留的0xc00000000这个地址

方式一的优点:在操作系统启动阶段就预留好,每次都能预留成功,方法简单

缺点:这段内存无法被系统识别,应用只能通过devmem方式去使用,无法使用malloc等其他方式分配使用,浪费空间。

方式二:

采用cma方式预留,bios中需要首先预留一段内存空间,并添加一个cma设备,地址、大小都需要指定好

添加设备

这么做的目的就是让cma分配空间时从预留的这段内存中去分配。

然后添加驱动程序,上电加载驱动,代码如下,驱动中可以修改预留大小

#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/poll.h>
#include <linux/of_reserved_mem.h>
#include <linux/dma-mapping.h>

#define ALLOC_SIZE (2048*1024*1024UL) //分配大小设置

dma_addr_t dma_phy_addr = 0;
unsigned int *buffer = NULL;
static struct device *mdev;

static int test_dma_probe(struct platform_device *pdev)
{
	int ret;

	printk("into test_dma_probe\n");
	mdev = &pdev->dev;

	dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
    ret = of_reserved_mem_device_init(&pdev->dev);
	if (ret) {
		printk("test_dma_probe of_reserved_mem_device_init err: %d\n", ret);
		return 0;
	}

	buffer = dma_alloc_coherent(&pdev->dev, ALLOC_SIZE, &dma_phy_addr, GFP_KERNEL);
	if (!buffer) {
		dev_err(&pdev->dev, "dma_alloc_coherent buffer allocation failed\n");
		return 0;
	}
	
	printk("dma_phy_addr=%llx\n", dma_phy_addr);
	printk("dma_phy_addr=%p\n", buffer);

	
    return 0;
}



static const struct of_device_id test_of_match[] = {
    { .compatible = "hc,test-dma-driver"},
    {}
};
MODULE_DEVICE_TABLE(of, test_of_match);

static struct platform_driver test_dma_driver = {
	.driver		= {
		.name	= "test_dma_mem",
                .of_match_table = of_match_ptr(test_of_match),
        },
	.probe		= test_dma_probe,
};


static int __init test_dma_init(void)
{
    int ret;

    ret = platform_driver_register(&test_dma_driver);
    if (ret)
    {
        pr_info("platform_driver_register fail\n");
        return 0;
    }

    pr_info("platform_driver_register success 0x%x \n",ret);
 	return 0;

}

static void __exit test_dma_exit(void)
{
	if (dma_phy_addr) {
		printk("--free dma mem\n");
		dma_free_coherent(mdev, ALLOC_SIZE, buffer, dma_phy_addr);
	}

	platform_driver_unregister(&test_dma_driver);
    printk("dma test exit successed\n");
}

module_init(test_dma_init);
module_exit(test_dma_exit);

MODULE_AUTHOR("test");
MODULE_DESCRIPTION("test dma driver");
MODULE_LICENSE("GPL");

Makefile如下:

# SPDX-License-Identifier: GPL-2.0

obj-m	+=test-dma-driver.o

KDIR=/lib/modules/$(shell uname -r)/build

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean

系统启动后能看到这里是reserved内存空间

驱动加载之后能看到预留成功

方式二的优点:cma方式如果不加载驱动那就不会预留空间,这样就避免内存浪费,虽然无法使用malloc方式访问,但可以用dma方式访问,如下:

 

同时用户可以通过脚本的方式在系统启动后这个阶段来指定哪些设备需要加载驱动,哪些不需要加载驱动,比较灵活,不像方式一那样是系统启动过程中预留,必须要修改启动文件才能修改

缺点:需要在bios的设备树中指定分配的起始地址和大小,如果换了地址就需要更改bios

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

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

相关文章

vue中form和table标签过长

form标签过长 效果&#xff1a; 代码&#xff1a; <el-form-item v-for"(item,index) in ticketEditTable1" :label"item.fieldNameCn" :propitem.fieldName :key"item.fieldNameCn" overflow"":rules"form[item.fieldName…

测试先行:探索测试驱动开发的深层价值

引言 在软件开发的世界中,如何确保代码的质量和可维护性始终是一个核心议题。测试驱动开发(TDD)为此提供了一个答案。与传统的开发方法相比,TDD鼓励开发者从用户的角度出发,先定义期望的结果,再进行实际的开发。这种方法不仅可以确保代码满足预期的需求,还可以在整个开…

数组和指针练习(1)

题目&#xff1a; int main() { int a[5] { 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5}; int * ptr (int * )(&a 1); printf("%d&#xff0c;%d"&#xff0c;*(a 1)&#xff0c;*(ptr - 1)); return 0; } 思路分析&#xff1a;…

BFT最前线|字节跳动AI对话产品“豆包”上线!联想集团推出AI大模型训练服务器!雷尼绍推出工业自动化产品系列

原创 | 文 BFT机器人 AI视界 TECHNOLOGY NEWS 看点1 天才少年稚晖君首秀&#xff0c;官宣智元人形机器人&#xff01; 2023年8月18日上午&#xff0c;从华为离职的“天才少年”彭志辉&#xff0c;也是B站硬核科技UP主稚晖君&#xff0c;公布了他所在的智元团队创业半年的成果…

【严重】Smartbi windowUnloading 限制绕过导致远程代码执行 (MPS-e2z8-wdi6)

zhi.oscs1024.com​​​​​ 漏洞类型授权机制不恰当发现时间2023-08-22漏洞等级严重MPS编号MPS-e2z8-wdi6CVE编号-漏洞影响广度广 漏洞危害 OSCS 描述 Smartbi 是思迈特软件旗下的一款商业智能应用&#xff0c;提供了数据集成、分析、可视化等功能&#xff0c;帮助用户理解和…

湘潭大学 湘大 XTU OJ 1116 水仙花数 题解(非常详细)

链接 1116 题面 Description 如果一个n位数的每个数位的n次方和就是本身&#xff0c;那么我们称这种数为“水仙花数”。比如371,337313273431 371。现给你一个数&#xff0c;请求这个数是否是水仙花数。 输入 有多组样例。每个样例占一行&#xff0c;为一个整数a&#xff0…

72 # http 缓存策略

前面实现了一个 http-server&#xff0c;并且实现了 gzip 的压缩&#xff0c;下面通过前面几节学习的缓存知识来添加一下缓存。 大致就是先强制缓存 10s&#xff0c;然后采用协商&#xff08;对比&#xff09;缓存&#xff0c;大致图如下 在之前的 http-server 的代码基础上添…

2023年8月22日OpenAI推出了革命性更新:ChatGPT-3.5 Turbo微调和API更新,为您的业务量身打造AI模型

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

C++day3(设计一个Per类,类中包含私有成员:姓名、年龄...)

1.设计一个Per类&#xff0c;类中包含私有成员&#xff1a;姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员&#xff1a;成绩、Per类对象 p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream&g…

【图论】拓扑排序

一.定义 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法&#xff0c;使得图中的每个顶点在排序中都位于其依赖的顶点之后。它通常用于表示一些任务之间的依赖关系&#xff0c;例如在一个项目中&#xff0c;某些任务必须在其他任务之前完成。 拓扑排序的…

解决:错误: 找不到或无法加载主类 XXX

解决&#xff1a;错误: 找不到或无法加载主类 XXX 一问题描述&#xff1a;1.在MacBook电脑上面&#xff0c;想用java原生命令执行一个class文件2.进入到class文件目录下面&#xff0c;使用“java 类名”命令&#xff0c;总是报错如下图所示。因为在windows环境的cmd环境这样都可…

游戏出海需知:Admob游戏广告变现策略

越来越多的出海游戏公司更加重视应用内的广告变现&#xff0c;而 AdMob因为其提供的丰富的广告资源&#xff0c;稳定平台支持&#xff0c;被广泛接入采用。 Admob推出的广告变现策略包括bidding、插页式激励视频、开屏广告、各种细分功能的报告等等。 一、Bidding 竞价策略 …

文件夹的批量下载

1.业务背景 公司想实现文件系统下载&#xff0c;上次图简单就草率的写了文件下载&#xff0c;这不趁着同事请假赶集吧这坑给填上。 2.遇到问题 刚准备开始写&#xff0c;就头疼&#xff0c;文件只要获得数据输出流就行&#xff0c;但是这文件夹需要维护层级关系。 前端…

Postman高级用法——newman安装运行

newman是为postman而生专门的执行软件&#xff0c;newman执行脚本即非GUI方式执行&#xff08;命令行方式&#xff09; 下面为newman安装运行的详细操作&#xff01;&#xff01;&#xff01;&#xff08;认真看噢&#xff09; &#xff08;1&#xff09;安装node.js&#xf…

多个promise并发执行,如果某个promise失败,则尝试重新执行该promise一次,如果还是失败则提示错误

思路 可以使用 Promise.all()和Promise.catch() 结合的方式来实现多个promise的并发执行&#xff0c;并在某个promise失败时尝试重新执行。 首先&#xff0c;将所有的promise放入数组中&#xff0c;并使用Promise.all()来同时执行这些promise&#xff0c;这样可以确保所有的p…

利用 XGBoost 进行时间序列预测

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建3D应用场景 XGBoost 应用程序的常见情况是分类预测&#xff08;如欺诈检测&#xff09;或回归预测&#xff08;如房价预测&#xff09;。但是&#xff0c;也可以扩展 XGBoost 算法以预测时间序列数据。它是如何工作的&#xf…

【业务功能篇73】web系统架构演变-单体-集群-垂直化-服务化-微服务化

1.服务架构的演 1.1 单体架构 单体架构应该是我们最先接触到的架构实现了&#xff0c;在单体架构中使用经典的三层模型&#xff0c;即表现层&#xff0c;业务逻辑层和数据访问层。 单体架构只适合在应用初期&#xff0c;且访问量比较下的情况下使用&#xff0c;优点是性价比很…

Redis五种类型

Redis 基础类型 String 应用场景 缓存功能&#xff1a;string 最常用的就是缓存功能&#xff0c;会将一些更新不频繁但是查询频繁的数据缓存起来&#xff0c;以此来减轻 DB 的压力。 底层实现 如果字符串对象保存的是一个字符串值&#xff0c; 并且这个字符串值的长度大于…

【2023中国算力大会】高质量建设西部数谷,努力把宁夏打造成算力之都

2023年8月18日—19日&#xff0c;2023中国算力大会在宁夏银川举行&#xff0c;本届大会以“算领新产业潮流 力赋高质量发展”为主题&#xff0c;打造“主题论坛、成果展示、产业推介、先锋引领”四大核心内容&#xff0c;全面展示算力产业发展最新成果&#xff0c;为产业各方搭…

servlet介绍,tomcat容器下载启动

1.1servlet是什么&#xff1f; servlet是一种java程序类&#xff0c;这些类继承了httpservlet类。这些类没有main方法&#xff0c;有两大对象request请求&#xff0c; response响应对象。这些类需要servlet容器才可以运行。 servlet 2.5 servlet 3.0 WEB-INF/web.xml <…