uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL | __GFP_DMA);这段代码为什么报这个问题:Unable to handle kernel paging request at virtual address 0000000200005401

时间: 2024-04-19 10:30:06 浏览: 9
这个问题是由于代码尝试访问一个未映射的虚拟地址导致的。当内核收到一个无效的虚拟地址时,会触发页错误异常(page fault exception)。 这可能是因为 `kmalloc` 分配的内存超出了可用的地址范围,或者分配的内存大小超过了系统内存限制。 你可以检查以下几点来解决这个问题: 1. 确保 `PL011_DMA_BUFFER_SIZE` 的大小合理,不超过系统可用的地址空间。 2. 检查系统内存是否足够支持所需的内存分配大小。 3. 确保内存分配标志 `GFP_KERNEL | __GFP_DMA` 设置正确,以便在合适的内存区域进行分配。 对于大型的内存分配,你可以考虑使用 `vmalloc` 或者 `get_free_pages` 来替代 `kmalloc`,以便能够分配更大范围的内存。 通过仔细检查这些因素并进行调试,可以找到导致此问题的具体原因,并进行适当的修复。
相关问题

uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL | __GFP_DMA);是什么意思

这段代码是在 Linux 内核中使用 kmalloc 函数为 uap->dmatx.buf 分配内存空间。kmalloc 是一种分配内核内存的函数,它接受两个参数:分配的大小和分配内存时的标志。在这里,分配的大小是 PL011_DMA_BUFFER_SIZE,标志使用了 GFP_KERNEL | __GFP_DMA。GFP_KERNEL 表示在内核上下文中进行内存分配,__GFP_DMA 表示分配的内存需要位于可进行 DMA 操作的区域。 因此,这段代码的作用是为 uap->dmatx.buf 分配大小为 PL011_DMA_BUFFER_SIZE 的内核内存,并且这段内存可以用于 DMA 操作。

static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource *r; int portnr, ret; int baudrate; /* * Check the mandatory baud rate parameter in the DT node early * so that we can easily exit with the error. */ if (pdev->dev.of_node) { struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); }linux内核uart驱动在设备注册时,使用acpi表定义的波特率来初始化串口,请根据我的要求和上述代码,在代码中添加这一功能

好的,根据你的要求,我可以在该函数中添加获取ACPI表中定义的波特率的功能,并使用该波特率来初始化串口。代码如下: ``` static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource *r; int portnr, ret; int baudrate; struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); /* Check if ACPI companion device exists, and if so, read the current-speed property */ if (adev) { struct acpi_device_node *adev_node = acpi_node_get_device_node(adev->handle); if (adev_node) { struct fwnode_handle *fwnode = &adev_node->fwnode; ret = fwnode_property_read_u32(fwnode, "current-speed", &baudrate); if (ret) return ret; } } else if (pdev->dev.of_node) { /* If there is no ACPI companion device, fall back to reading the current-speed property from DT node */ struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); } ``` 我添加的代码在函数开头处,首先判断是否存在ACPI companion device,如果存在则从其属性中读取波特率,否则从DT node中读取。读取到的波特率将被用于初始化串口。

相关推荐

static void pl011_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned int lcr_h, old_cr; unsigned long flags; unsigned int baud, quot, clkdiv; if (uap->vendor->oversampling) clkdiv = 8; else clkdiv = 16; baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / clkdiv); if (baud > port->uartclk/16) quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); else quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud); switch (termios->c_cflag & CSIZE) { case CS5: lcr_h = UART01x_LCRH_WLEN_5; break; case CS6: lcr_h = UART01x_LCRH_WLEN_6; break; case CS7: lcr_h = UART01x_LCRH_WLEN_7; break; default: // CS8 lcr_h = UART01x_LCRH_WLEN_8; break; } if (termios->c_cflag & CSTOPB) lcr_h |= UART01x_LCRH_STP2; if (termios->c_cflag & PARENB) { lcr_h |= UART01x_LCRH_PEN; if (!(termios->c_cflag & PARODD)) lcr_h |= UART01x_LCRH_EPS; if (termios->c_cflag & CMSPAR) lcr_h |= UART011_LCRH_SPS; } if (uap->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); pl011_setup_status_masks(port, termios); if (UART_ENABLE_MS(port, termios->c_cflag)) pl011_enable_ms(port); old_cr = pl011_read(uap, REG_CR); pl011_write(0, uap, REG_CR); if (termios->c_cflag & CRTSCTS) { if (old_cr & UART011_CR_RTS) old_cr |= UART011_CR_RTSEN; old_cr |= UART011_CR_CTSEN; port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; } else { old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); } if (uap->vendor->oversampling) { if (baud > port->uartclk / 16) old_cr |= ST_UART011_CR_OVSFACT; else old_cr &= ~ST_UART011_CR_OVSFACT; } if (uap->vendor->oversampling) { if ((baud >= 3000000) && (baud < 3250000) && (quot > 1)) quot -= 1; else if ((baud > 3250000) && (quot > 2)) quot -= 2; } pl011_write(quot & 0x3f, uap, REG_FBRD); pl011_write(quot >> 6, uap, REG_IBRD); pl011_write_lcr_h(uap, lcr_h); pl011_write(old_cr, uap, REG_CR); spin_unlock_irqrestore(&port->lock, flags); 详细分析这段代码中哪些部分是设置波特率,哪些是设置校验位,哪些是设置停止位,拆分出来

最新推荐

recommend-type

SG-UAP_V2.3_高级开发手册_分册3.服务端开发

本文定位为“高级开发参考手册”,在“快速开发实战指南”的基础上,对平台操作功能进行了深入的介绍。本文主要分为四部分对平台进行了详细的介绍,分别为:业务系统开发、任务调度与集成开发、即席报表与集成开发和...
recommend-type

SG-UAP_V1.5应用常见问题解答汇总

SG-UAP_V1.5应用常见问题解答汇总 SG-UAP_V1.5应用常见问题解答汇总
recommend-type

NCV6X-语义模型红皮书.docx

NC6系列UAP语义模型技术红皮书 第一章 前言 4 1.1 概念 5 1.2 定位 5 第二章 结构 6 2.1 应用模型 7 2.2 语义模型 7 2.2.1 定义形态 7 2.2.2 执行流程 9 2.2.3 数据形态 10 2.3 语义提供者 10 2.3.1 接口...
recommend-type

U8UAP开发报表设置方案——存储过程

UAP是用友U8开发的工具,本文主要介绍UAP的使用过程,适合初学者,比较详细,希望可以帮助到你U8UAP开发报表设置方案——存储过程
recommend-type

用友UAP的Portal开发

用友UAP的Portal开发 快速 在web开发中,我们已经创建一个lfwdemo项目,下面的案例均是在那个案例基础上进行的portlet的开发,当然如果你比较熟悉web开发的话,也不限于那个项目。 本portal开发案例,用6个案例讲解...
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

如何用python编写api接口

在Python中编写API接口可以使用多种框架,其中比较流行的有Flask和Django。这里以Flask框架为例,简单介绍如何编写API接口。 1. 安装Flask框架 使用pip命令安装Flask框架: ``` pip install flask ``` 2. 编写API接口 创建一个Python文件,例如app.py,编写以下代码: ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/api/hello', methods=['GET']) def hello():
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。