arm64 架构允不允许内核运行在比较高的物理地址?

2023-03-07 21:58:22 +08:00
 wniming

我使用 u-boot 加载内核,如果将内核加载到物理地址 2MB 的地方启动没有问题,但如果我加载到比较大的地址,比如 2GB ,启动时内核会报 dma 错误,感觉像是某些设备发出的 dma 会去使用内核代码以及数据的地址。

x86 上内核开启了 kaslr 后,内核是会在整个物理内存范围内随机放置的,并不会和设备的 dma 冲突。

为什么 arm64 架构会有这样的问题? 内核在编译的时候能不能指定最终内核所在的物理地址?

[   10.241360] ------------[ cut here ]------------
[   10.246205] Failed to get suitable pool for soc:firmware
[   10.251665] WARNING: CPU: 2 PID: 226 at kernel/dma/pool.c:279 dma_alloc_from_pool+0x114/0x1b0
[   10.260408] Modules linked in: sdhci_iproc pcie_brcmstb(+) sdhci_pltfm crct10dif_ce bcm2835_wdt sdhci aes_neon_bs
[   10.270942] CPU: 2 PID: 226 Comm: systemd-udevd Tainted: G        W          6.0.7 #1
[   10.278957] Hardware name: Raspberry Pi 4 Model B Rev 1.5 (DT)
[   10.284925] pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   10.292050] pc : dma_alloc_from_pool+0x114/0x1b0
[   10.296783] lr : dma_alloc_from_pool+0x114/0x1b0
[   10.301511] sp : ffff8000083b3160
[   10.304900] x29: ffff8000083b3160 x28: ffff8000083b3228 x27: ffffd25e2dc38000
[   10.312214] x26: ffffd25e2c754780 x25: ffffd25e2eb33000 x24: fffffc0000000000
[   10.319525] x23: ffffd25e2dc38c80 x22: 0000000000001000 x21: 0000000080700000
[   10.326835] x20: ffff800008196000 x19: 0000000000000000 x18: 0000000000000006
[   10.334144] x17: 0000000000000001 x16: 0000000000000004 x15: ffff8000083b2cb8
[   10.341453] x14: 0000000000000000 x13: 657261776d726966 x12: 3a636f7320726f66
[   10.348761] x11: 00000000ffffdfff x10: ffffd25e2e74e6c0 x9 : ffffd25e2c72c6c4
[   10.356069] x8 : 000000000002ffe8 x7 : c0000000ffffdfff x6 : 00000000000affa8
[   10.363377] x5 : ffff67533b72d450 x4 : 0000000000000000 x3 : 0000000000000027
[   10.370685] x2 : 0000000000000023 x1 : ffff675298215a00 x0 : 000000000000002c
[   10.377993] Call trace:
[   10.380495]  dma_alloc_from_pool+0x114/0x1b0
[   10.384874]  dma_direct_alloc+0x84/0x33c
[   10.388892]  dma_alloc_attrs+0x78/0xe0
[   10.392729]  rpi_firmware_property_list+0x64/0x230
[   10.397637]  rpi_firmware_property+0x78/0xc0
[   10.402010]  rpi_reset_reset+0x3c/0x8c
[   10.405855]  reset_control_reset+0x58/0x140
[   10.412961]  xhci_pci_probe+0x70/0x254
[   10.419548]  local_pci_probe+0x48/0xa0
[   10.426081]  pci_call_probe+0x4c/0x130
[   10.432639]  pci_device_probe+0x88/0x100
[   10.439322]  really_probe+0xc8/0x3e0
[   10.445633]  __driver_probe_device+0x84/0x190
[   10.452741]  driver_probe_device+0x44/0x100
[   10.459645]  __device_attach_driver+0xc4/0x160
[   10.466786]  bus_for_each_drv+0x74/0xb4
[   10.473275]  __device_attach+0xa8/0x1c0
[   10.479745]  device_attach+0x1c/0x30
[   10.485949]  pci_bus_add_device+0x58/0xc0
[   10.492574]  pci_bus_add_devices+0x40/0x90
[   10.499280]  pci_bus_add_devices+0x6c/0x90
[   10.505901]  pci_host_probe+0x48/0xd0
[   10.512081]  brcm_pcie_probe+0x254/0x488 [pcie_brcmstb]
[   10.519808]  platform_probe+0x70/0xcc
[   10.525943]  really_probe+0xc8/0x3e0
[   10.531957]  __driver_probe_device+0x84/0x190
[   10.538769]  driver_probe_device+0x44/0x100
[   10.545398]  __driver_attach+0xfc/0x1f0
[   10.551632]  bus_for_each_dev+0x6c/0xac
[   10.557844]  driver_attach+0x2c/0x40
[   10.563773]  bus_add_driver+0x184/0x240
[   10.563797]  driver_register+0x80/0x13c
[   10.563810]  __platform_driver_register+0x30/0x3c
[   10.583207]  brcm_pcie_driver_init+0x2c/0x1000 [pcie_brcmstb]
[   10.583243]  do_one_initcall+0x50/0x2a0
[   10.583258]  do_init_module+0x50/0x1f0
[   10.583276]  load_module+0x990/0xae0
[   10.583288]  __do_sys_finit_module+0x9c/0xfc
[   10.615850]  __arm64_sys_finit_module+0x28/0x34
[   10.615876]  invoke_syscall+0x78/0x100
[   10.615886]  el0_svc_common.constprop.0+0xd4/0xf4
[   10.615896]  do_el0_svc+0x34/0x4c
[   10.615904]  el0_svc+0x34/0x10c
[   10.646417]  el0t_64_sync_handler+0xf4/0x120
[   10.646445]  el0t_64_sync+0x190/0x194
[   10.646459] ---[ end trace 0000000000000000 ]---
[   10.646539] xhci_hcd 0000:01:00.0: enabling device (0000 -> 0002)
[   10.675323] xhci_hcd 0000:01:00.0: xHCI Host Controller
[   10.684365] xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 1

2372 次点击
所在节点    Linux
5 条回复
dode
2023-03-07 22:57:41 +08:00
BIOS 不支持访问高位内存? 内核需要被引导程序放好呀,
AlkaidHe
2023-03-08 01:00:46 +08:00
非专业人士,一家之言,姑且听之

2m 位置开始读好像是大部分芯片或 uboot 约定俗成的。
修改重新编译 uboot ,可能会解决。

uboot 读取 2m 位置的 boot 分区 加载 kernel.img

bios/uefi 读取 ESP/EFI 分区 指向 boot 分区 加载 grub 的 kernel.img 再选择引导 system kernel (如 debian linux 5.15 kernel )

也可以尝试 uboot 读取 2m 位置的 boot 分区 加载 grub kernel.img 再引导 system kernel
AlkaidHe
2023-03-08 01:11:26 +08:00
http://www.wowotech.net/memory_management/441.html
你看一下这篇文章有没有帮助,我对未知事物比较感兴趣,请问这样让内核偏移的作用是什么?仅仅为了安全性?
xy629
2023-03-08 01:49:31 +08:00
试试在启动内核时通过添加内核参数“cma=xxxM”来限制 DMA 内存池的大小。
xiadong1994
2023-03-08 03:41:56 +08:00
可能是某些设备在 device tree 里面映射到了这部分内存

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922037

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX