内核空间中PCI内存的地址映射 [英] Address mapping of PCI-memory in Kernel space

查看:138
本文介绍了内核空间中PCI内存的地址映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从可加载的内核模块中读写PCI设备.

I'm trying to read and write to and PCI-device from a loadable kernel module.

因此,我遵循此

但是最后,设备无法按预期完成其工作.然后我查看bar1后面的地址,发现一个很大的值ffffbaaaaa004500.

But at the end the device doesn't do his work as expected. Then I look to the address behind bar1 and found a very big value ffffbaaaaa004500.

在这一点上,我真的不明白那里发生了什么,什么是正确的.我可以将bar1解释为内核地址空间内的一个地址,该地址直接指向与PCI芯片选择地址偏移0x60000的基地址吗?

At this point I don't really understand what was happen there and what was right. Can I interpret bar1 as an address inside my kernel address space which points directly to the base address which is 0x60000 offset to the PCI Chip Select Address?

我写入bar1 + offset的值怎么会复制到设备上?该机制如何在iowrite32pci_iomap的后面起作用?

And how can it be that the value I write to bar1 + offset copied to the device? How does the mechanism work in behind of iowrite32 and pci_iomap?

感谢和问候

亚历克斯

PS:我成功地测试了从同一地址的回读.

PS: I tested a read back from the same address successfully.

PCI设备的注册说明:

Register description of the PCI device:

  • PCIBAR0 PCI基址0;用于内存映射的配置寄存器
  • PCIBAR1 PCI基址1;用于I/O映射的配置寄存器
  • PCIBAR2 PCI基址2;用于本地地址空间0
  • PCIBAR3 PCI基址3;用于本地地址空间1
  • PCIBAR4未使用的基地址
  • PCIBAR5未使用的基地址
  • PCIBAR0 PCI Base Address 0; used for Memory-Mapped Configuration Registers
  • PCIBAR1 PCI Base Address 1; used for I/O-Mapped Configuration Registers
  • PCIBAR2 PCI Base Address 2; used for Local Address Space 0
  • PCIBAR3 PCI Base Address 3; used for Local Address Space 1
  • PCIBAR4 Unused Base Address
  • PCIBAR5 Unused Base Address

你好.

上一次,我尝试了几种与BAR2寄存器进行通信的方法,但均未成功.这是我的实际代码:

In the last time I tried several approaches to communicate with the BAR2 register but without success. Here my actual code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/sched.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex");
MODULE_DESCRIPTION("test module.");
MODULE_VERSION("0.1");

#define DEV_PCI_VENDORID 0x10B5
#define DEV_PCI_DEVICEID 0x1860

static struct pci_device_id pci_drvIdTable[] =
{
  {
    .vendor      = DEV_PCI_VENDORID,      // vendor ID
    .device      = DEV_PCI_DEVICEID,      // device ID
    .subvendor   = PCI_ANY_ID,            // no subsystem available
    .subdevice   = PCI_ANY_ID,            // no subsystem available
    .class       = PCI_CLASS_NOT_DEFINED, // no device class
    .class_mask  = 0,                     // no device class
    .driver_data = 0                      // no private data to the driver
  },
  { 0, }                                  // end of table
};

struct pci_data
{
  /// the IO mapping for the PCI config space
  uint32_t *pciConfigAddr;
  uint32_t *pciB2Addr;
//  void __iomem *pciConfigAddr;

  wait_queue_head_t waitq;
  uint8_t flag;
} *data;

static irqreturn_t
_expdev_irq (int irq, void *pdata)
{
  struct pci_data *data = pdata;

  printk(KERN_INFO "Interrupt talks...\n");
  data->flag = 1;
  wake_up_interruptible( &data->waitq );

  return IRQ_HANDLED;
}


static int
_pci_probe ( struct pci_dev *pdev,
             const struct pci_device_id *ent )
{
  int ret = 0;
  int i;
  u16 reg_16;
  unsigned long bas2addr;

  data = kzalloc( sizeof(*data) , GFP_KERNEL );
  if( !data )
  {
    printk(KERN_ERR "Failed to allocate memory.\n");
    return -ENOMEM;
  }

  pci_set_drvdata(pdev, data);

  // enabling the device
  ret = pci_enable_device(pdev);
  if( ret )
  {
    printk(KERN_ERR "Failed to enable PCI device.\n");
    goto no_enable;
  }

  pci_read_config_word(pdev,0,&reg_16);
  printk(KERN_INFO "VendorID. %x\n",reg_16);

  // checking if PCI-device reachable by checking that BAR0 is defined and
  // memory mapped
  if( !(pci_resource_flags(pdev,0) & IORESOURCE_MEM) )
  {
    printk(KERN_ERR "Incorrect BAR configuration.\n");
    ret = -ENODEV;
    goto bad_bar;
  }

  // taking ownership of a memory region
  ret = pcim_iomap_regions(pdev, 0b0100, "expdev");
//  ret = pci_request_regions(pdev,"expdev");
  if( ret )
  {
    printk(KERN_ERR "Failed to request regions.\n");
    goto failed_request_regions;
  }

  bas2addr = pci_resource_start(pdev, 2);

  reg_16 = 0xAA;
  i = 0x060000;
  iowrite16( reg_16 , (unsigned long *)(bas2addr+i) );
  printk( KERN_INFO "BAR2 Register[0x%x] = 0x%x\n",
          i, ioread32( (unsigned long *)(bas2addr+i) ) );

  printk(KERN_INFO "Module successfully initialised.\n");

  return 0;

  // Error handling - backward disabling the device
failed_request_regions:
bad_bar:
  pci_disable_device(pdev);
no_enable:
  pci_set_drvdata(pdev, data);

  return ret;
}


static void
_pci_remove( struct pci_dev *pdev )
{
  free_irq(pdev->irq, data);
  pci_disable_msi(pdev);
  pci_clear_master(pdev);
  pci_iounmap(pdev,data->pciConfigAddr);
  pci_release_regions(pdev);
  pci_disable_device(pdev);

  printk(KERN_INFO "PCI-device removed.\n");
}


static struct pci_driver pci_drv =
{
  .name     = "expdev",
  .id_table = pci_drvIdTable,
  .probe    = _pci_probe,
  .remove   = _pci_remove,
};

// module related functions ///////////////////////////////////////////////////

static int __init _module_init(void){
   printk(KERN_INFO "Hello!\n");

   pci_register_driver(&pci_drv);

   return 0;
}

static void __exit _module_exit(void){

   pci_unregister_driver(&pci_drv);

   printk(KERN_INFO "Goodbye!\n");
}

module_init(_module_init);
module_exit(_module_exit);

这是带有tail -f /var/log/kern.log

kernel: [  493.719999] Hello!
kernel: [  493.720071] expdev 0000:05:02.0: enabling device (0000 -> 0003)
kernel: [  493.720845] VendorID. 10b5
kernel: [  493.722375] BUG: unable to handle kernel paging request at 00000000eb060000
kernel: [  493.722381] IP: [<ffffffff8137aca8>] iowrite16+0x38/0x40
kernel: [  493.722388] PGD 0 
kernel: [  493.722390] Oops: 0002 [#1] SMP 
kernel: [  493.722394] Modules linked in: expdev(OX+) rfcomm bnep bluetooth nvidia(POX) snd_hda_codec_hdmi joydev snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep snd_pcm coretemp snd_page_alloc snd_seq_midi snd_seq_midi_event snd_rawmidi gpio_ich kvm snd_seq snd_seq_device drm dcdbas snd_timer lpc_ich snd soundcore shpchp serio_raw ppdev i82975x_edac lp parport_pc edac_core parport mac_hid hid_generic usbhid hid psmouse ahci tg3 libahci ptp pps_core pata_acpi
kernel: [  493.722429] CPU: 0 PID: 3542 Comm: insmod Tainted: P           OX 3.13.0-79-generic #123-Ubuntu
kernel: [  493.722431] Hardware name: Dell Inc.                 Precision WorkStation 390    /0DN075, BIOS 2.3.0  05/01/2007
kernel: [  493.722434] task: ffff8800549c3000 ti: ffff8800555e6000 task.ti: ffff8800555e6000
kernel: [  493.722436] RIP: 0010:[<ffffffff8137aca8>]  [<ffffffff8137aca8>] iowrite16+0x38/0x40
kernel: [  493.722440] RSP: 0018:ffff8800555e7b88  EFLAGS: 00010212
kernel: [  493.722442] RAX: 00000000eb000000 RBX: ffff88007c2b4000 RCX: 0000000000000000
kernel: [  493.722444] RDX: 00000000eb060000 RSI: 00000000eb060000 RDI: 00000000000000aa
kernel: [  493.722446] RBP: ffff8800555e7bb0 R08: 00000000ebffffff R09: 00000000ffffffec
kernel: [  493.722448] R10: 0000000000003692 R11: 0000000000000000 R12: 00000000eb060000
kernel: [  493.722450] R13: ffff88007c2b4098 R14: ffff88007c2b4098 R15: ffffffffa022b140
kernel: [  493.722452] FS:  00007fa8053ef740(0000) GS:ffff88007f800000(0000) knlGS:0000000000000000
kernel: [  493.722454] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
kernel: [  493.722456] CR2: 00000000eb060000 CR3: 000000005a74b000 CR4: 00000000000007f0
kernel: [  493.722458] Stack:
kernel: [  493.722460]  ffffffffa02291c4 00aa88007c2b4000 ffff88007c2b4000 0000000000000000
kernel: [  493.722464]  ffffffffa022b000 ffff8800555e7be8 ffffffff813ac8a5 ffffffff813adb45
kernel: [  493.722467]  ffff88007c2b4098 ffffffffffffffff ffff88007c2b4000 0000000000000017
kernel: [  493.722471] Call Trace:
kernel: [  493.722477]  [<ffffffffa02291c4>] ? _pci_probe+0x114/0x215 [expdev]
kernel: [  493.722481]  [<ffffffff813ac8a5>] local_pci_probe+0x45/0xa0
kernel: [  493.722484]  [<ffffffff813adb45>] ? pci_match_device+0xc5/0xd0
kernel: [  493.722487]  [<ffffffff813adc69>] pci_device_probe+0xd9/0x130
kernel: [  493.722492]  [<ffffffff8149a4bd>] driver_probe_device+0x12d/0x3e0
kernel: [  493.722495]  [<ffffffff8149a843>] __driver_attach+0x93/0xa0
kernel: [  493.722498]  [<ffffffff8149a7b0>] ? __device_attach+0x40/0x40
kernel: [  493.722501]  [<ffffffff81498403>] bus_for_each_dev+0x63/0xa0
kernel: [  493.722504]  [<ffffffff81499e6e>] driver_attach+0x1e/0x20
kernel: [  493.722507]  [<ffffffff81499a50>] bus_add_driver+0x180/0x250
kernel: [  493.722510]  [<ffffffffa0005000>] ? 0xffffffffa0004fff
kernel: [  493.722514]  [<ffffffff8149aec4>] driver_register+0x64/0xf0
kernel: [  493.722517]  [<ffffffffa0005000>] ? 0xffffffffa0004fff
kernel: [  493.722520]  [<ffffffff813ac23c>] __pci_register_driver+0x4c/0x50
kernel: [  493.722523]  [<ffffffffa000502c>] _module_init+0x2c/0x1000 [expdev]
kernel: [  493.722528]  [<ffffffff8100214a>] do_one_initcall+0xfa/0x1b0
kernel: [  493.722532]  [<ffffffff810598f3>] ? set_memory_nx+0x43/0x50
kernel: [  493.722536]  [<ffffffff810e2b7d>] load_module+0x12ed/0x1b50
kernel: [  493.722540]  [<ffffffff810de5f0>] ? store_uevent+0x40/0x40
kernel: [  493.722544]  [<ffffffff810e3556>] SyS_finit_module+0x86/0xb0
kernel: [  493.722548]  [<ffffffff817363dd>] system_call_fastpath+0x1a/0x1f
kernel: [  493.722550] Code: 81 fe 00 00 01 00 76 0b 0f b7 d6 89 f8 66 ef c3 0f 1f 00 55 48 c7 c6 b0 10 a9 81 48 89 d7 48 89 e5 e8 5d fe ff ff 5d c3 0f 1f 00 <66> 89 3e c3 0f 1f 40 00 48 81 fe ff ff 03 00 48 89 f2 77 2c 48 
kernel: [  493.722583] RIP  [<ffffffff8137aca8>] iowrite16+0x38/0x40
kernel: [  493.722586]  RSP <ffff8800555e7b88>
kernel: [  493.722588] CR2: 00000000eb060000
kernel: [  493.722591] ---[ end trace 2d3dfa92998d58a7 ]---


根据Ian Abbott的说法,我现在成功地尝试了这种方法.我并不真正了解其背后的机制,但目前为止仍然有效.因此,BAR2是存储器寄存器类型.此方法使用ioremap而不是内存映射.如何通过内存映射访问BAR2?


According to Ian Abbott now I tried this approach successfully. I don't really understand the mechanism behind but it works for now. So BAR2 is an Memory Register type. This approach uses ioremap and not memory-mapping. How to get access to BAR2 via memory-mapping?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex");
MODULE_DESCRIPTION("test module.");
MODULE_VERSION("0.1");

#define DEV_PCI_VENDORID 0x10B5
#define DEV_PCI_DEVICEID 0x1860

static struct pci_device_id pci_drvIdTable[] =
{
  {
    .vendor      = DEV_PCI_VENDORID,      // vendor ID
    .device      = DEV_PCI_DEVICEID,      // device ID
    .subvendor   = PCI_ANY_ID,            // no subsystem available
    .subdevice   = PCI_ANY_ID,            // no subsystem available
    .class       = PCI_CLASS_NOT_DEFINED, // no device class
    .class_mask  = 0,                     // no device class
    .driver_data = 0                      // no private data to the driver
  },
  { 0, }                                  // end of table
};

struct pci_data
{
//  struct pci_dev *pci_dev;

  /// the IO mapping for the PCI config space
  uint32_t *pciConfigAddr;
  uint32_t *pciB2Addr;

  wait_queue_head_t waitq;
  uint8_t flag;
} *data;

static int
_pci_probe ( struct pci_dev *pdev,
             const struct pci_device_id *ent )
{
  int ret = 0;
  int i;
  u16 reg_16;
  unsigned long *pbas2addr;

  data = kzalloc( sizeof(*data) , GFP_KERNEL );
  if( !data )
  {
    printk(KERN_ERR "Failed to allocate memory.\n");
    return -ENOMEM;
  }

  pci_set_drvdata(pdev, data);

  // enabling the device
  ret = pci_enable_device(pdev);
  if( ret )
  {
    printk(KERN_ERR "Failed to enable PCI device.\n");
    goto no_enable;
  }

  pci_read_config_word(pdev,0,&reg_16);
  printk(KERN_INFO "VendorID. %x\n",reg_16);

  // checking if PCI-device reachable by checking that BAR0 is defined and
  // memory mapped
  if( !(pci_resource_flags(pdev,0) & IORESOURCE_MEM) )
  {
    printk(KERN_ERR "Incorrect BAR configuration.\n");
    ret = -ENODEV;
    goto bad_bar;
  }

  // taking ownership of a memory region
  pbas2addr = pci_ioremap_bar(pdev, 2);

  // void iowrite8(u8 val, void __iomem *addr)
    for ( i = 0x060000; i<0x070000; i++ )
    {
      iowrite8( 0x11 , pbas2addr+i );
    }

  // further read/write function in the kernel:
  // inp,  readl,  readw,  readb,  ioread8,  ioread16,  ioread32
  // outp, writel, writew, writeb, iowrite8, iowrite16, iowrite32

bad_bar:
  pci_disable_device(pdev);
no_enable:
  pci_set_drvdata(pdev, data);

  return ret;
}

static void
_pci_remove( struct pci_dev *pdev )
{
  pci_disable_device(pdev);
  printk(KERN_INFO "PCI-device removed.\n");
}

static struct pci_driver pci_drv =
{
  .name     = "expdev",
  .id_table = pci_drvIdTable,
  .probe    = _pci_probe,
  .remove   = _pci_remove,
};

// module related functions ///////////////////////////////////////////////////

static int __init _module_init(void){
   printk(KERN_INFO "Hello!\n");
   pci_register_driver(&pci_drv);
   return 0;
}

static void __exit _module_exit(void){
   pci_unregister_driver(&pci_drv);
   printk(KERN_INFO "Goodbye!\n");
}

module_init(_module_init);
module_exit(_module_exit);


我真的快结束了.我想我已经完全遵循了文档,但是它没有按预期工作.


I'm really at the end. I think I have fully follow the docs but it doesn't work as expected.

代码在这里:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/sched.h>

#include <linux/delay.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex");
MODULE_DESCRIPTION("test module.");
MODULE_VERSION("0.1");

#define DEV_PCI_VENDORID 0x10B5
#define DEV_PCI_DEVICEID 0x1860

static struct pci_device_id pci_drvIdTable[] =
{
  {
    .vendor      = DEV_PCI_VENDORID,      // vendor ID
    .device      = DEV_PCI_DEVICEID,        // device ID
    .subvendor   = PCI_ANY_ID,            // no subsystem available
    .subdevice   = PCI_ANY_ID,            // no subsystem available
    .class       = PCI_CLASS_NOT_DEFINED, // no device class
    .class_mask  = 0,                       // no device class
    .driver_data = 0                        // no private data to the driver
  },
  { 0, }
};

static int
_pci_probe ( struct pci_dev *pdev,
             const struct pci_device_id *ent )
{
  int ret = 0;
  int i;
  unsigned long *pbas2addr;

  // enabling the device
  ret = pci_enable_device(pdev);
  if( ret )
  {
    printk(KERN_ERR "Failed to enable PCI device.\n");
    goto no_enable;
  }

  pci_request_regions(pdev, "expdev");

  // checking if PCI-device reachable by checking that BAR0 is defined and
  // memory mapped
  if( !(pci_resource_flags(pdev,0) & IORESOURCE_MEM) )
  {
    printk(KERN_ERR "Incorrect BAR configuration.\n");
    ret = -ENODEV;
    goto bad_bar;
  }

  // taking ownership of a memory region
  pbas2addr = pci_ioremap_bar(pdev, 2);

  printk(KERN_INFO "BAR2: %p\n",pbas2addr);

  for ( i = 0x060000; i<0x070000; i++ )
  {
    iowrite8( 0x00 , pbas2addr+i );
  }

  // the next write operations cause crashing the the module
  // load control word to set ICD in set-up-mode
  iowrite32(0b01111000000101, pbas2addr+0x200014);
  // load the bit-stuffed set up word
  iowrite32(0b10110001001001101110000, pbas2addr+0x200018); // 39.5 MHz
  // load control word to set ICD in set-up-mode
  iowrite32(0b01111000000100, pbas2addr+0x200014);
  msleep(10);
  // load control word to set ICD in set-up-mode
  iowrite32(0b01111000000000, pbas2addr+0x200014);

  return 0;

bad_bar:
  pci_disable_device(pdev);

  return ret;
}


static void
_pci_remove( struct pci_dev *pdev )
{
  pci_release_regions(pdev);
  pci_disable_device(pdev);

  printk(KERN_INFO "PCI-device removed.\n");
}

static struct pci_driver pci_drv =
{
  .name     = "expdev",
  .id_table = pci_drvIdTable,
  .probe    = _pci_probe,
  .remove   = _pci_remove,
};

// module related functions     
static int __init _module_init(void){
   printk(KERN_INFO "Hello!\n");
   pci_register_driver(&pci_drv);
   return 0;
}

static void __exit _module_exit(void){
   pci_unregister_driver(&pci_drv);
   printk(KERN_INFO "Goodbye!\n");
}

module_init(_module_init);
module_exit(_module_exit);

仅包含for循环:

kernel: [  467.545079] Hello!
kernel: [  467.545136] expdev 0000:05:02.0: enabling device (0000 -> 0003)
kernel: [  467.546807] BAR2: ffffc90006c00000
kernel: [  467.562146] PCI-device removed.
kernel: [  467.562489] Goodbye!

我可以在设备GPIO上看到一些输出.

and I can see some outputs on the device GPIO.

如果我根据设备手册的需要写入较高的地址,则LKM崩溃:

If I write to the higher addresses as needed regarding to the device manual the LKM crashes:

kernel: [ 1324.591578] Hello!
kernel: [ 1324.593300] BAR2: ffffc90007c80000
kernel: [ 1324.605162] BUG: unable to handle kernel paging request at ffffc90008c800a0
kernel: [ 1324.605168] IP: [<ffffffff8137ace8>] iowrite32+0x38/0x40
kernel: [ 1324.605175] PGD 7d00d067 PUD 7d00e067 PMD 611e7067 PTE 0
kernel: [ 1324.605179] Oops: 0002 [#1] SMP 
kernel: [ 1324.605183] Modules linked in: expdev(OX+) rfcomm bnep bluetooth nvidia(POX) snd_hda_codec_hdmi joydev snd_hda_codec_idt snd_hda_intel snd_hda_codec gpio_ich coretemp drm snd_seq_midi kvm snd_seq_midi_event dcdbas snd_rawmidi snd_hwdep lpc_ich snd_seq snd_pcm snd_seq_device snd_page_alloc shpchp ppdev serio_raw snd_timer lp snd soundcore mac_hid i82975x_edac edac_core parport_pc parport hid_generic usbhid hid psmouse ahci libahci pata_acpi tg3 ptp pps_core [last unloaded: expdev]
kernel: [ 1324.605219] CPU: 0 PID: 3155 Comm: insmod Tainted: P           OX 3.13.0-79-generic #123-Ubuntu
kernel: [ 1324.605221] Hardware name: Dell Inc.                 Precision WorkStation 390    /0DN075, BIOS 2.3.0  05/01/2007
kernel: [ 1324.605224] task: ffff88007c048000 ti: ffff880061122000 task.ti: ffff880061122000
kernel: [ 1324.605226] RIP: 0010:[<ffffffff8137ace8>]  [<ffffffff8137ace8>] iowrite32+0x38/0x40
kernel: [ 1324.605229] RSP: 0018:ffff880061123b90  EFLAGS: 00010292
kernel: [ 1324.605231] RAX: 0000000000000016 RBX: ffffc90008c800a0 RCX: 0000000000000000
kernel: [ 1324.605233] RDX: ffffc90008c800a0 RSI: ffffc90008c800a0 RDI: 0000000000001e05
kernel: [ 1324.605235] RBP: ffff880061123bb0 R08: 0000000000000096 R09: 0000000000000306
kernel: [ 1324.605237] R10: 0000000000000000 R11: ffff8800611238c6 R12: ffffc90007f80000
kernel: [ 1324.605239] R13: ffffc90007c80000 R14: ffff88007c2b4098 R15: ffffffffa01fc140
kernel: [ 1324.605242] FS:  00007fc6802cb740(0000) GS:ffff88007f800000(0000) knlGS:0000000000000000
kernel: [ 1324.605244] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: [ 1324.605246] CR2: ffffc90008c800a0 CR3: 0000000062f96000 CR4: 00000000000007f0
kernel: [ 1324.605248] Stack:
kernel: [ 1324.605249]  ffffffffa01fa0ec ffff88007c2b4000 0000000000000000 ffffffffa01fc000
kernel: [ 1324.605253]  ffff880061123be8 ffffffff813ac8a5 ffffffff813adb45 ffff88007c2b4098
kernel: [ 1324.605257]  ffffffffffffffff ffff88007c2b4000 0000000000000018 ffff880061123c30
kernel: [ 1324.605260] Call Trace:
kernel: [ 1324.605267]  [<ffffffffa01fa0ec>] ? _pci_probe+0xbc/0x110 [expdev]
kernel: [ 1324.605271]  [<ffffffff813ac8a5>] local_pci_probe+0x45/0xa0
kernel: [ 1324.605274]  [<ffffffff813adb45>] ? pci_match_device+0xc5/0xd0
kernel: [ 1324.605277]  [<ffffffff813adc69>] pci_device_probe+0xd9/0x130
kernel: [ 1324.605281]  [<ffffffff8149a4bd>] driver_probe_device+0x12d/0x3e0
kernel: [ 1324.605285]  [<ffffffff8149a843>] __driver_attach+0x93/0xa0
kernel: [ 1324.605288]  [<ffffffff8149a7b0>] ? __device_attach+0x40/0x40
kernel: [ 1324.605290]  [<ffffffff81498403>] bus_for_each_dev+0x63/0xa0
kernel: [ 1324.605293]  [<ffffffff81499e6e>] driver_attach+0x1e/0x20
kernel: [ 1324.605296]  [<ffffffff81499a50>] bus_add_driver+0x180/0x250
kernel: [ 1324.605300]  [<ffffffffa0006000>] ? 0xffffffffa0005fff
kernel: [ 1324.605303]  [<ffffffff8149aec4>] driver_register+0x64/0xf0
kernel: [ 1324.605306]  [<ffffffffa0006000>] ? 0xffffffffa0005fff
kernel: [ 1324.605309]  [<ffffffff813ac23c>] __pci_register_driver+0x4c/0x50
kernel: [ 1324.605313]  [<ffffffffa000602c>] _module_init+0x2c/0x1000 [expdev]
kernel: [ 1324.605317]  [<ffffffff8100214a>] do_one_initcall+0xfa/0x1b0
kernel: [ 1324.605321]  [<ffffffff810598f3>] ? set_memory_nx+0x43/0x50
kernel: [ 1324.605326]  [<ffffffff810e2b7d>] load_module+0x12ed/0x1b50
kernel: [ 1324.605330]  [<ffffffff810de5f0>] ? store_uevent+0x40/0x40
kernel: [ 1324.605334]  [<ffffffff810e3556>] SyS_finit_module+0x86/0xb0
kernel: [ 1324.605338]  [<ffffffff817363dd>] system_call_fastpath+0x1a/0x1f
kernel: [ 1324.605340] Code: 81 fe 00 00 01 00 76 0b 0f b7 d6 89 f8 ef c3 0f 1f 40 00 55 48 c7 c6 bf 10 a9 81 48 89 d7 48 89 e5 e8 1d fe ff ff 5d c3 0f 1f 00 <89> 3e c3 0f 1f 44 00 00 48 81 ff ff ff 03 00 77 37 48 81 ff 00 
kernel: [ 1324.605373] RIP  [<ffffffff8137ace8>] iowrite32+0x38/0x40
kernel: [ 1324.605376]  RSP <ffff880061123b90>
kernel: [ 1324.605378] CR2: ffffc90008c800a0
kernel: [ 1324.605381] ---[ end trace 9b1029fd3f919791 ]---

RIP-但是为什么.偏移量在16 MB的范围内.

RIP - but why. The offset is within the limits of 16 MB.

推荐答案

我认为您访问了未映射到PCIe设备的PCIe内存空间的内存空间. 如您所知,BAR由PCIe设备在引导或重新扫描时定义.因此,BAR的大小也由PCIe设备决定.您可以使用启动日志进行检查. 因此,您应该在PCIe设备定义的大小范围内访问内存.

I think that you accessed the memory space which is not mapped to the PCIe memory spaces for the PCIe device. As you know, BAR is defined by PCIe devices at booting time or rescan time. So the size of BAR is also decided by PCIe devices. You can check it with the booting log. As a result, you should access the memory within the size which is defined by the PCIe device.

这篇关于内核空间中PCI内存的地址映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆