Skip to the content.

ioremap 和 resource 机制

因为内核也是运行在虚拟地址空间上的,而访问设备是需要物理地址,为了将访问设备的物理地址映射到虚拟地址空间中,所以需要 ioremap,当然 pci 访问带来的各种 cache coherency 问题也是需要尽量考虑的:

ioremap 的调用时间

#0  __ioremap_caller (phys_addr=4263518208, size=4096, pcm=pcm@entry=_PAGE_CACHE_MODE_UC_MINUS, caller=0xffffffff8174efd4 <vp_modern_map_capability+308>, encrypted=<optimized out>) at arch/x86/mm/ioremap.c:179
#1  0xffffffff810f485e in ioremap (phys_addr=<optimized out>, size=<optimized out>) at arch/x86/mm/ioremap.c:350
#2  0xffffffff816889b7 in pci_iomap_range (dev=dev@entry=0xffff888100c70000, bar=<optimized out>, offset=<optimized out>, maxlen=<optimized out>) at lib/pci_iomap.c:46
#3  0xffffffff8174efd4 in vp_modern_map_capability (mdev=mdev@entry=0xffff888101003b48, off=off@entry=96, minlen=minlen@entry=0, align=align@entry=4, start=start@entry=0, size=size@entry=4096, len=0xffff888101003b80, pa=0x0 <fixed_percpu_data>) at drivers/virtio/virtio_pci_modern_dev.c:94
#4  0xffffffff8174f96a in vp_modern_probe (mdev=mdev@entry=0xffff888101003b48) at drivers/virtio/virtio_pci_modern_dev.c:331
#5  0xffffffff8175057a in virtio_pci_modern_probe (vp_dev=vp_dev@entry=0xffff888101003800) at drivers/virtio/virtio_pci_modern.c:533
#6  0xffffffff817509f5 in virtio_pci_probe (pci_dev=0xffff888100c70000, id=<optimized out>) at drivers/virtio/virtio_pci_common.c:551
#7  0xffffffff816c94aa in local_pci_probe (_ddi=_ddi@entry=0xffffc9000005fd60) at drivers/pci/pci-driver.c:324

使用 x86 为例子:

__iomem 是做什么的

resource 的初始化

初始化时间

ioapic 的初始化:

#0  insert_resource (parent=0xffffffff82a61160 <iomem_resource>, new=new@entry=0xffff88823fff1880) at kernel/resource.c:857
#1  0xffffffff833525a8 in ioapic_insert_resources () at arch/x86/kernel/apic/io_apic.c:2751
#2  0xffffffff83392b6c in pcibios_resource_survey () at arch/x86/pci/i386.c:408
#3  0xffffffff833944ec in pcibios_init () at arch/x86/pci/common.c:509
#4  0xffffffff83393929 in pci_subsys_init () at arch/x86/pci/legacy.c:73
#5  0xffffffff81000e7c in do_one_initcall (fn=0xffffffff833938cf <pci_subsys_init>) at init/main.c:1303
#6  0xffffffff8333b4c7 in do_initcall_level (command_line=0xffff888004438900 "root", level=4) at init/main.c:1376
#7  do_initcalls () at init/main.c:1392
#8  do_basic_setup () at init/main.c:1411
#9  kernel_init_freeable () at init/main.c:1631
#10 0xffffffff81faff01 in kernel_init (unused=<optimized out>) at init/main.c:1519
#11 0xffffffff81001a6f in ret_from_fork () at arch/x86/entry/entry_64.S:306

但是顶层的 PCI 设备什么时候注册的,我没有找到:

c0000000-febfffff : PCI Bus 0000:00

resource 注册申请

#0  __request_region (parent=0xffffffff82a611a0 <ioport_resource>, start=744, n=8, name=name@entry=0xffffffff82832361 "serial", flags=flags@entry=0) at kernel/resource.c:1220
#1  0xffffffff8177da7f in serial8250_request_std_resource (up=up@entry=0xffffffff835502a0 <serial8250_ports+2304>) at drivers/tty/serial/8250/8250_port.c:2997
#2  0xffffffff8177f608 in serial8250_config_port (port=0xffffffff835502a0 <serial8250_ports+2304>, flags=3) at drivers/tty/serial/8250/8250_port.c:3193
#3  0xffffffff8177cadf in univ8250_config_port (port=0xffffffff835502a0 <serial8250_ports+2304>, flags=3) at drivers/tty/serial/8250/8250_core.c:444
#4  0xffffffff8177b519 in uart_configure_port (drv=0xffffffff82c10b80 <serial8250_reg>, port=0xffffffff835502a0 <serial8250_ports+2304>, state=0xffff8880055f0528) at drivers/tty/serial/serial_core.c:2547
#5  uart_add_one_port (drv=drv@entry=0xffffffff82c10b80 <serial8250_reg>, uport=uport@entry=0xffffffff835502a0 <serial8250_ports+2304>) at drivers/tty/serial/serial_core.c:3096
#6  0xffffffff8337b0ba in serial8250_register_ports (drv=0xffffffff82c10b80 <serial8250_reg>, dev=0xffff888004545810) at drivers/tty/serial/8250/8250_core.c:572
#7  serial8250_init () at drivers/tty/serial/8250/8250_core.c:1205
#8  0xffffffff81000e7c in do_one_initcall (fn=0xffffffff8337af91 <serial8250_init>) at init/main.c:1303
#9  0xffffffff8333b4c7 in do_initcall_level (command_line=0xffff88800440b900 "root", level=6) at init/main.c:1376
#10 do_initcalls () at init/main.c:1392
#11 do_basic_setup () at init/main.c:1411
#12 kernel_init_freeable () at init/main.c:1631
#13 0xffffffff81faff01 in kernel_init (unused=<optimized out>) at init/main.c:1519
#14 0xffffffff81001a6f in ret_from_fork () at arch/x86/entry/entry_64.S:306

其中 PCI 设备 pci_request_selected_regions —> __request_region_locked

/proc/iomap 的实现

sudo cat /proc/iomem
[sudo] password for martins3:
00000000-00000fff : Reserved
00001000-0009dfff : System RAM
0009e000-0009efff : Reserved
0009f000-0009ffff : System RAM
000a0000-000fffff : Reserved
  000a0000-000bffff : PCI Bus 0000:00
  00000000-00000000 : PCI Bus 0000:00
  00000000-00000000 : PCI Bus 0000:00
  00000000-00000000 : PCI Bus 0000:00
  000e0000-000effff : PCI Bus 0000:00
  000f0000-000fffff : System ROM
00100000-5ed4b017 : System RAM
  4e000000-55ffffff : Crash kernel
5ed4b018-5ed5a057 : System RAM
5ed5a058-63e5dfff : System RAM
63e5e000-63e5efff : Reserved
63e5f000-63e9bfff : System RAM
63e9c000-63e9cfff : Reserved
63e9d000-6b60bfff : System RAM
6b60c000-6b9d8fff : Reserved
6b9d9000-6dc60fff : System RAM
6dc61000-6dc61fff : Reserved
6dc62000-70560fff : System RAM
70561000-74260fff : Reserved
74261000-744b0fff : ACPI Tables
744b1000-7471efff : ACPI Non-volatile Storage
7471f000-75ffefff : Reserved
75fff000-75ffffff : System RAM
76000000-79ffffff : Reserved
7a400000-7a7fffff : Reserved
7b000000-807fffff : Reserved
  7c800000-807fffff : Graphics Stolen Memory
80800000-bfffffff : PCI Bus 0000:00
  80800000-80800fff : 0000:00:1f.5
    80800000-80800fff : 0000:00:1f.5 0000:00:1f.5
  82000000-83ffffff : 0000:00:0e.0
    82000000-83ffffff : VMD MEMBAR1
  84000000-849fffff : PCI Bus 0000:03
  84a00000-84bfffff : PCI Bus 0000:04
    84a00000-84afffff : 0000:04:00.0
      84a00000-84afffff : igc
    84b00000-84b03fff : 0000:04:00.0
      84b00000-84b03fff : igc
  84c00000-84cfffff : PCI Bus 0000:02
    84c00000-84c03fff : 0000:02:00.0
      84c00000-84c03fff : nvme
    84c04000-84c0ffff : 0000:02:00.0
  84d00000-84dfffff : PCI Bus 0000:01
    84d00000-84d1ffff : 0000:01:00.0
    84d20000-84d2ffff : 0000:01:00.0
      84d20000-84d2ffff : nvme
    84d30000-84d33fff : 0000:01:00.0
      84d30000-84d33fff : nvme
    84d34000-84db3fff : 0000:01:00.0
  84e00000-84e01fff : 0000:00:17.0
    84e00000-84e01fff : ahci
  84e02000-84e027ff : 0000:00:17.0
    84e02000-84e027ff : ahci
  84e03000-84e030ff : 0000:00:17.0
    84e03000-84e030ff : ahci
c0000000-cfffffff : PCI MMCONFIG 0000 [bus 00-ff]
  c0000000-cfffffff : Reserved
e0690000-e069ffff : INTC1056:00
  e0690000-e069ffff : INTC1056:00 INTC1056:00
e06a0000-e06affff : INTC1056:00
  e06a0000-e06affff : INTC1056:00 INTC1056:00
e06b0000-e06bffff : INTC1056:00
  e06b0000-e06bffff : INTC1056:00 INTC1056:00
e06d0000-e06dffff : INTC1056:00
  e06d0000-e06dffff : INTC1056:00 INTC1056:00
e06e0000-e06effff : INTC1056:00
  e06e0000-e06effff : INTC1056:00 INTC1056:00
fe000000-fe010fff : Reserved
fec00000-fec00fff : Reserved
  fec00000-fec003ff : IOAPIC 0
fed00000-fed00fff : Reserved
  fed00000-fed003ff : HPET 0
    fed00000-fed003ff : PNP0103:00
fed20000-fed7ffff : Reserved
  fed40000-fed44fff : MSFT0101:00
    fed40000-fed44fff : MSFT0101:00
fed90000-fed90fff : dmar0
fed91000-fed91fff : dmar1
feda0000-feda0fff : pnp 00:04
feda1000-feda1fff : pnp 00:04
fedc0000-fedc7fff : pnp 00:04
fee00000-fee00fff : Local APIC
  fee00000-fee00fff : Reserved
ff000000-ffffffff : Reserved
100000000-107f7fffff : System RAM
  d3f000000-d3fc01a87 : Kernel code
  d3fe00000-d40587fff : Kernel rodata
  d40600000-d4083607f : Kernel data
  d40da4000-d40ffffff : Kernel bss
107f800000-107fffffff : RAM buffer
4000000000-7fffffffff : PCI Bus 0000:00
  4000000000-400fffffff : 0000:00:02.0
  4010000000-4016ffffff : 0000:00:02.0
  4017000000-40171fffff : PCI Bus 0000:03
  4017200000-4017200fff : 0000:00:15.0
    4017200000-40172001ff : lpss_dev
      4017200000-40172001ff : i2c_designware.0 lpss_dev
    4017200200-40172002ff : lpss_priv
    4017200800-4017200fff : idma64.0
      4017200800-4017200fff : idma64.0 idma64.0
  4017201000-4017201fff : 0000:00:15.1
    4017201000-40172011ff : lpss_dev
      4017201000-40172011ff : i2c_designware.1 lpss_dev
    4017201200-40172012ff : lpss_priv
    4017201800-4017201fff : idma64.1
      4017201800-4017201fff : idma64.1 idma64.1
  4017202000-4017202fff : 0000:00:15.2
    4017202000-40172021ff : lpss_dev
      4017202000-40172021ff : i2c_designware.2 lpss_dev
    4017202200-40172022ff : lpss_priv
    4017202800-4017202fff : idma64.2
      4017202800-4017202fff : idma64.2 idma64.2
  4020000000-40ffffffff : 0000:00:02.0
  6000000000-6001ffffff : 0000:00:0e.0
  6002000000-6002ffffff : 0000:00:02.0
  6003000000-60030fffff : 0000:00:1f.3
  6003100000-60031fffff : 0000:00:0e.0
    6003102000-60031fffff : VMD MEMBAR2
  6003200000-600320ffff : 0000:00:14.0
    6003200000-600320ffff : xhci-hcd
  6003210000-6003217fff : 0000:00:0a.0
    6003214000-6003214d9f : telem0
    6003214da0-6003214edf : telem1
    60032164d8-60032164e7 : intel_vsec.telemetry.0
    60032164e8-60032164f7 : intel_vsec.telemetry.0
    60032164f8-6003216507 : intel_vsec.telemetry.0
    6003216508-6003216517 : intel_vsec.telemetry.0
  6003218000-600321bfff : 0000:00:1f.3
    6003218000-600321bfff : ICH HD audio
  600321c000-600321ffff : 0000:00:14.3
    600321c000-600321ffff : iwlwifi
  6003220000-6003223fff : 0000:00:14.2
  6003224000-60032240ff : 0000:00:1f.4
  6003225000-6003225fff : 0000:00:16.0
    6003225000-6003225fff : mei_me
  6003229000-6003229fff : 0000:00:14.2

补充一下,QEMU 中观测到的 info mtree 和 guest 中的 /proc/mtree

early_ioremap 是做什么的?

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。