我在某处读到(至少从 Linux v. 2.6 开始)所有用户空间代码都放置在虚拟内存地址空间中的加载地址 0x8048000 处。
我自己的观察证实了这一点。我做了一个
cat /proc/......../maps
Run Code Online (Sandbox Code Playgroud)
对于多个进程,进程'程序的第一部分text总是从'0x8048000'开始。
此外,C 库启动代码和所有其他运行时好东西似乎都映射在此默认值之后。
这构成了近 128 M 的地址空间,考虑到 0xC0000000 - 0x8048000 仍然是用户空间内容的几乎 3G 地址空间,这并不多。
所以我的问题是为什么?
我们正在处理虚拟地址,与其他程序的干扰或重叠是由 VM 工作方式的定义排除的。
0x00000000 到 0x8048000 范围内是否有一些固定/默认映射?
除了默认起始地址落在页面边界这一事实之外,选择这个数字而不是任何其他值的理由是什么?
我试图了解大页面大小与数据实际写入 RAM 的方式之间的关系。
当进程使用 1GB 大页面时会发生什么 - 写入是否发生在 1GB 块中?我猜我对这个假设完全错误?
我在一个嵌入式系统上(来自 Xilinx 的 Zynq。它使用 ARMv7、Cortex-A9),并运行 Linux。我需要确保一定的物理内存范围内没有访问过发,无论是意外内核空间或用户。我可以发出信号、数据中止或其他任何事情,但这种硬件尝试不能超过 MMU。
在裸机模式和 U-Boot 中,我可以直接访问 TLB 的位置,并且可以通过将 MMU 配置为在发生任何读或写访问时中止数据来限制硬件级别的内存访问。我想在 Linux 中这样做,即使是 mmap() 也会引发数据中止。
推理:
在 Zynq 中,2GB 的地址空间被分配给一个可能永远不会在硬件级别响应的范围。ARM 的 AXI/AMBA 协议说主机永远不能“放弃”访问地址的尝试,即使那里什么都没有。如果我取消引用一个没有硬件驻留的指针,整个芯片就会挂起。
我知道我可以“只是不给 sudo”或“只是编写好的驱动程序”,但这甚至在那个级别之前。我想在早期启动时将 MMU 的 TLB 设置为如果我的超级用户进行了一些错误的编码,则数据完全中止。我宁愿不 hack boot.S,而是直接修改 TLB,然后使用 API 来刷新它。
用户空间地址空间有很好的文档记录,其中包括堆、堆栈、.text、.bss 等段。但没有足够的内核地址空间文档。由于内核空间中使用了某些虚拟地址,我想知道内核空间是如何构建的?
PS:听说有内核栈段,但是找不到更系统的内核地址空间介绍。
感兴趣的平台是 x86_64 和 Linux 3-*
大多数字段都是可以理解的,但有人可以向我解释“页面调入”和“页面换入”之间的区别吗?。我很确定交换是将整个过程移入硬盘驱动器上的交换空间,而分页是将某些页面移入交换空间。那么这是否意味着“页面调入”是属于移入主内存的进程部分的页面,而“换入页面”是属于整个进程移入主内存的页面?有人可以在这里说明一下吗?如果您有关于其他领域的其他信息,那也会很棒。我已阅读手册,但没有找到有关此特定选项的命令的有用信息。命令输出示例:
vmstat -s
131072 K total memory
125700 K used memory
59836 K active memory
49268 K inactive memory
5372 K free memory
0 K buffer memory
101984 K swap cache
0 K total swap
0 K used swap
0 K free swap
18594 non-nice user cpu ticks
0 nice user cpu ticks
17990 system cpu ticks
108464145 idle cpu ticks
1121 IO-wait cpu ticks
0 IRQ cpu ticks
0 softirq cpu ticks
0 stolen cpu ticks
123672 pages paged …Run Code Online (Sandbox Code Playgroud) 我需要知道两个进程之间共享的内存量,即它们共享内存的交集。
有任何想法吗?
我们使用 Linux 应用程序已经有一段时间了(我们的旅程始于十年前的 RHEL 4)。我们最近在 RHEL 7.9 上运行我们的应用程序,现在正在迁移到 RHEL 8.4。
我们总是将 vm.swappiness 设置为 1,以便在仍然有大量可用内存(页面缓存中的 GIG 页面)时尽可能避免发生交换:是的,我们更喜欢先吃页面缓存:-)
这在 RHEL 7.x 上一直运行得很好:我们从未见过在可用内存超过 500MB 左右时发生交换。我们的系统通常具有 16 到 64 GB 的 RAM。
在 RHEL 8.4 上,我很确定我亲眼目睹了在有大量(几 Gig)可用内存的情况下发生的几次交换。在 RHEL 7 上的类似情况下从未发生过这种情况。
因此,我想从交换“攻击性”的角度了解 RHEL 7 和 RHEL 8 之间发生了什么变化,或者也许我应该从哪里开始更好地描述/排除故障/理解为什么要做出这种交换决定。
你们对我如何实现这一目标有一些了解/建议吗?
提前谢谢了。++西里尔
我试图了解运行操作系统时物理地址是如何分配的。
我的问题是,当内核分配一些内存(假设使用 kmalloc)时,谁决定应该为该虚拟内存范围映射什么物理内存地址范围?
我知道内核将创建页表来将映射从虚拟转换为物理,并且 MMU 将使用它。但在此之前,应该有人分配/指派一些要映射的物理页面。这是由内核本身完成的还是 MMU 会让内核知道可以使用的特定物理地址范围?
如果内核本身分配物理地址,那么它如何跟踪哪些物理地址已被使用以及哪些是空闲的(待使用)?
virtual-memory ×10
linux ×6
memory ×4
linux-kernel ×2
swap ×2
arm ×1
elf ×1
pager ×1
performance ×1
process ×1
profiling ×1
ram ×1
rhel ×1