【问题标题】:Why is membase adress different each time kernel module is loaded?为什么每次加载内核模块时membase地址都不同?
【发布时间】:2020-04-16 08:10:18
【问题描述】:

我一直以 Linux 版本为例构建 RTDM UART 驱动程序。 UART基地址应该是0x80070000,使用linux驱动时dmesg显示没有问题:

80070000.serial: ttyAPP3 at MMIO 0x80070000 (irq = 234, base_baud = 1500000) is a 80070000.serial
mxs-auart 80070000.serial: Found APPUART 3.1.0

但是,当我使用我正在构建的驱动程序时,每次加载模块时都会得到一个不同的地址(例如0xc8df6000),而且它们都不正确。

这是我正在使用的探测功能:

static int rt_mxs_auart_probe(struct platform_device *pdev)

{
    const struct of_device_id *of_id =

            of_match_device(mxs_auart_dt_ids, &pdev->dev);

    int ret;
    struct resource *r;

    struct rtdm_device *dev;

    struct rt_mxs_auart_port *s;

    //allocate managed kernel memory

    s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
    if (!s)
        return -ENOMEM;

    ret = rt_serial_mxs_probe_dt(s, pdev);

    if (ret < 0){
        return ret;
        }

    if (of_id) {

        pdev->id_entry = of_id->data;
        s->devtype = pdev->id_entry->driver_data;
    }

    r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    if (!r)
        return -ENXIO;

    //get irq line
    s->irq = platform_get_irq(pdev, 0);
    if (s->irq < 0)
        return -ENODEV;

    //base memory
    s->membase = ioremap(r->start, resource_size(r));

    if (IS_ERR(s->membase))
        return PTR_ERR(s->membase);


    /*define the rtdm_device*/
    dev = &s->rtdm_dev;
    dev->driver = &ida_driver;
    dev->label = "xeno_ida";
    dev->device_data = s;

    ret = mxs_get_clks(s, pdev); //activate clocks
    if (ret)
        return ret;

    s->uartclk = clk_get_rate(s->clk);
    s->fifosize = MXS_AUART_FIFO_SIZE;

    mxs_init_regs(s);

    ret = rtdm_dev_register(dev); //register driver in RTDM space

    if (ret)
        return ret;

    platform_set_drvdata(pdev, s); //add device-related data to device struct


    pr_info("Probe: Successful\n");
    pr_info("%s on IMX UART%d: membase=0x%p irq=%d uartclk=%d\n",
           dev->name, pdev->id, s->membase, s->irq, s->uartclk);

    return 0;
}

它基于mxs-auart.crt_imx_uart.c

对于membase,我使用与mxs-auart.c 相同的代码,这就是为什么我不明白为什么会遇到这个问题。当我尝试rmmod它时,我的驱动程序也冻结了一段时间,所以我想知道它是否是由这个引起的。

不胜感激!

【问题讨论】:

  • ioremap 不保证任何特定的返回值。为什么你认为 0x80070000 正确而 0xc8df6000 不正确?
  • 因为我正在使用设备的 AUART3,并且根据数据表,我知道它的基本内存为 0x80070000
  • 0x80070000 是一个物理地址,您将其传递ioremapioremap 返回 无关紧要。可以是任何东西。
  • 哦,我明白了!那么这是否意味着我的 r 变量是 platform_get_resource 的返回值是 0x80070000 ?
  • 是的,应该是。

标签: c linux-kernel linux-device-driver kernel-module


【解决方案1】:

ioremap 的返回值是虚拟地址,不是物理地址。它可以在虚拟地址空间中的任何位置。

物理地址存储在r-&gt;startioremap的输入)中。

【讨论】:

    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2017-04-17
    相关资源
    最近更新 更多