标签: memory-mapping

ELF64/x86_64和内存映射段的起始地址(用于共享对象)

我编写了几个程序,发现当在64位编译时,内存映射段(例如共享对象和共享内存保存)总是位于7f9aca84a000-7fff88400000左右但从未完全相同.

我想知道x86_64架构(ELF64)上的内存段是否有固定的起始地址,或者该段的最大和最小范围是多少?

这就是为什么我问这个问题.我们正在将系统从Tru64 UNIX迁移到Linux.该系统使用IPC Sys V共享内存的复杂固定内存映射,并使用链表在该段内从结构转到另一个.由于这段代码的大小和复杂性,以及我们手头有限的时间,我们正在尝试找到一种可靠的方法来修复共享内存的开始(有效地使用带有指定地址的shmat来附加段).对于64位,虚拟地址空间是如此巨大(48位有效可能的地址),选择"安全"固定地址比32位更容易,风险更小.

c linux shared-memory memory-layout memory-mapping

5
推荐指数
1
解决办法
2274
查看次数

映射内存和SSE

我在英特尔开发人员手册中找到了这一段:

从主题"使用SSE3编程,SSSE3,SSE4和AESNI"

不得使用流加载来引用映射到具有副作用的I/O设备的存储器地址,或者对这些设备的读取具有破坏性.这是因为MOVNTDQA本质上是推测性的.

有人可以澄清这个问题吗?

我问,因为我正在考虑将一些SSE程序集应用于OpenGL 映射缓冲区对象,但我担心这个破坏性的单词.这个主题是否适用于映射内存?其实我不知道glMapBuffer调用的背后是什么.

我不认为我的显卡会被破坏(:),但肯定这个词听起来不太好.

assembly sse intel memory-mapping

5
推荐指数
1
解决办法
262
查看次数

内存映射的I / O地址从何而来?

我正在搞一些业余OS开发,并且对内存映射的I / O地址有些困惑。我了解整个内存映射的I / O概念,但是我试图弄清楚开发人员如何获得地址来操纵硬件。

地址是由硬件供应商指定的,还是所有计算机的某种标准地址?例如,用于文本打印的VGA存储器从地址0xB8000开始。每个x86机器都使用该标准吗?如果是这样,谁来设定那个标准?例如,如果我想与以太网卡通讯,我怎么知道它用于通讯的地址或端口?

提前致谢。

osdev memory-mapping

5
推荐指数
1
解决办法
2348
查看次数

从MMF访问SQLite数据库

我正在使用System.Data.SQLitelib访问我的SQLite数据库。我想将数据库文件加载到内存中,并使用MMF(内存映射文件)访问数据库。

使用默认的SQLite库是否可以实现?

编辑:

欢迎提供有关如何拥有内存数据库的替代方法。

c# sqlite memory-mapped-files memory-mapping

5
推荐指数
1
解决办法
1038
查看次数

CPU如何知道PCI地址空间

我知道 PCI 和 PCIe 设备可以由 CPU(通过 BIOS 或 OS 中的代码)配置为通过写入设备配置空间的特定区域来响应某些物理内存地址。
事实上,考虑到设备的许多要求(内存对齐、DMA 功能等),Linux 内核有相当复杂的算法来执行此操作。

看到那个软件似乎可以控制这个内存是否、何时以及在哪里映射,我的问题是:一个软件如何控制物理内存的映射?

在这种配置之后,PCI 设备将知道响应给定的地址范围,但是 CPU 如何知道它应该在 PCI 总线上为那些刚刚动态决定的特定地址?

linux-kernel memory-mapping pci pci-e

5
推荐指数
1
解决办法
2039
查看次数

模拟游戏机的内存映射,根据提供的地址访问不同的位置

我正在为旧游戏机实现模拟器,主要是出于学习目的。

此控制台将ROM和许多其他内容映射到其地址空间内的区域。某些位置也被镜像,因此多个地址可以对应于同一物理位置。我想模仿一下,但是我不确定这样做的好方法(也不知道这个过程叫什么,因此不知道这个通用问题)。

起作用的一件事是一张简单的无序地图。让它包含绝对地址和指向我的数据结构的相应指针。这样,我可以轻松地将所需的所有内容映射到系统的地址空间。这种方法的问题在于,这显然是内存消耗。即使有了小光盘,由于上述镜像,我最终还是获得了近一千万个条目。当然,这不是严峻的事情吗?

任何帮助深表感谢。

编辑:

提供一些有关我如何精确执行此操作的详细信息:

当然,所讨论的系统是SNES。使用此Wiki作为我的主要资源,我实现了上面提到的内容,如下所示:

  • 创建一个 std::unordered_map<uint32,uint8_t*> mMemoryMap;
  • 检查ROM是LoRom还是HiRom
  • 对于ROM中的每个字节
    • 计算应该将其映射到的地址,并在映射中放置该地址和指向该字节的指针
    • 如果该部分需要在其他地方镜像,请重复上述步骤
  • 这将应用于我需要提供的其他任何内容,例如视频或系统内存

如果现在我想访问地址空间内的任何内容,我可以简单地使用系统在内部使用的地址。

c++ emulation low-level memory-mapping

5
推荐指数
1
解决办法
376
查看次数

Linux:在我的进程中管理虚拟内存映射以实现快速仿真

最近我发现很多模拟器都很慢,因为它们不仅需要模拟CPU,还要模拟模拟设备的内存.当设备具有内存映射I/O,虚拟内存或仅未使用的地址空间时,必须在软件中模拟每个内存访问.

如果操作系统通过虚拟内存为我们这样做,我觉得它可能会快得多.为了简单起见,我将使用Game Boy仿真作为示例,但显然这种方法对于更新,更强大的机器会更好.

Game Boy记忆图大致是:

  • 0x0000 - 0x7FFF:映射到盒式ROM
    • 大多数墨盒固定为0x0000 - 0x3FFF,写入0x2000时可将0x4000 - 0x7FFF存储区切换
  • 0x8000 - 0x9FFF:视频RAM(仅在当前未呈现时可访问)
  • 0xA000 - 0xBFFF:映射到盒式磁带(通常由电池供电的RAM)
  • 0xC000 - 0xDFFF:内部RAM(0xD000 - 0xDFFF是GB颜色上的bankwitched)
  • 0xE000 - 0xFDFF:内部RAM的镜像
  • 0xFE00 - 0xFE9F:对象属性存储器(精灵RAM)
  • 0xFEA0 - 0xFEFF:未映射(打开总线或其他东西,不确定)
  • 0xFF00 - 0xFF7F:内存映射I/O(音响系统,视频控制等)
  • 0xFE80 - 0xFFFF:内部RAM

因此,传统的模拟器必须转换每个内存访问,如:

if(addr < 0x4000) return rom[addr];
else if(addr < 0x8000) return rom[(addr - 0x4000) + (0x4000 * cur_rom_bank)];
else if(addr < 0xA000) {
    if(vram_accessible) return vram[addr - 0x8000];
    else return 0xFF;
}
else if(addr < 0xC000) return saveram[addr - 0xA000];
else …
Run Code Online (Sandbox Code Playgroud)

linux memory emulation virtual-memory memory-mapping

5
推荐指数
1
解决办法
693
查看次数

使用mmap进行PCI-e内存空间访问

我在飞思卡尔MPC8308处理器(基于PowerPC架构)上使用PCI-e端口,尝试使用它时遇到一些问题。端点PCI-e设备的内存空间等于256 MB。通过使用“ pciutils”包,我可以轻松读写端点设备的配置空间。

在配置寄存器中写入正确的值并获得访问内存空间的权限后;我试图通过在C语言中使用“ mmap()”函数来访问内存空间,并使用位于以下位置的文件描述符:

“ /sys/devices/pci0000:00/0000:00:00.0/resource0”

这恰好是256 MB(等于端点设备的内存空间),因此看来我在使用正确的文件描述符路径。在这里,您可以使用https://github.com/billfarrow/pcimem中提到的“ mmap()”找到我的代码:

https://github.com/billfarrow/pcimem/blob/master/pcimem.c

但是不幸的是,当我尝试通过使用“ mmap()”函数的返回地址来使用内存空间时;我无法正确读取端点设备的只读寄存器。另外,当我读取大于“ 0x7FFFFFC”的地址时,MPC8308重新启动。考虑到上述情况,我是否错过任何初始化PCI-e接口的步骤?我应该更改Linux内核映像或U-Boot代码中的任何内容吗?通过mmap()使用PowerPC PCI-e有什么不同吗?您是否有任何示例代码可以帮助我读取PCI-e内存空间?

谢谢

linux mmap memory-mapping pci-e

5
推荐指数
1
解决办法
5003
查看次数

为什么我的Rust可执行文件映射到这样的高地址(靠近堆栈)而不是0x400000?

我正在学习x86_64系统上的Linux用户空间内存布局,并希望从某些部分打印一些地址.我使用了这个Rust代码:

fn main() {
    let x = 3;        // should be stored on stack
    let s = "hello";  // should be in the .data section

    println!("stack ? {:p}", &x);
    println!(".text ? {:p}", main as *const ());
    println!(".data ? {:p}", s);


    use std::io;

    let mut f = std::fs::File::open("/proc/self/maps").unwrap();
    let out = io::stdout();
    io::copy(&mut f, &mut out.lock()).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

此代码还将文件打印/proc/self/maps到stdout.我mem.rs简单地编译了这个文件rustc mem.rs.它打印:

stack ? 0x7ffffbf82f2c
.text ? 0x7f45b7c0a2b0
.data ? 0x7f45b7c4d35b

7f45b6800000-7f45b6c00000 rw-- 00000000 00:00 0
7f45b6de0000-7f45b6f9a000 r-x- …
Run Code Online (Sandbox Code Playgroud)

linux memory-mapping rust windows-subsystem-for-linux

5
推荐指数
1
解决办法
283
查看次数

读取内存映射 IO 是否比微控制器上的常规内存花费更长的时间?

我的具体上下文是 STM32 ARM M0,但问题更笼统。

读取或写入内存映射外设(例如 GPIO 端口或串行端口缓冲区)的内容与物理 RAM 中的位置是否需要相同数量的时钟?这是否因架构而异?

arm stm32 memory-mapping

4
推荐指数
1
解决办法
903
查看次数