虚拟内存中 0x400000 下面是什么?
What's under 0x400000 in virtual memory?
在学习Linux操作系统时,我知道以下几点:
- 实模式将使用 0x10000 以下的地址
- 保护模式32bit使用4G,用户space可以使用2/3G
- 程序的虚拟内存将从 0x40000 开始到更高
那么,0x400000下面是保留的吗?
So, what's under 0x400000, is it reserved?
这是没有映射任何物理内存的虚拟地址 space。有关详细信息,请参阅 page table。
您可以查看进程的虚拟地址 space 映射:
cat /proc/<pid>/maps
0x400000
的基地址有些随意,地址 space 随机化(默认启用)在每个 运行 的不同地址加载可执行文件。您可以通过 运行ning cat /proc/self/maps
两次观察地址 space 随机化的效果,并观察到 cat
可执行文件被加载到每个 运行 上的不同虚拟地址(前提是cat
是可执行文件而不是 shell 内置文件)。
最小虚拟地址由vm.mmap_min_addr
sysctl
变量控制。在 Ubuntu 18.04.5 LTS 上,其默认值为 65536
(十六进制的 0x10000
)。
正如 Maxim 所说,它只是未映射。该区域中的页面在 CPU 的页表中被标记为“不存在”,因此访问它们会导致页面错误;并且内核知道它们没有任何物理内存、文件或交换 space 支持,因此将通过向进程传递分段错误信号 (SIGSEGV) 来处理此类页面错误,通常会杀死它。
至少要取消映射程序虚拟地址 space 的最低页,这样访问地址 0(空指针取消引用)将导致分段错误,而不是允许有错误的程序继续 运行。保留较大的区域未映射也很好,例如,如果程序尝试访问 p[i]
,其中 p
是空指针且 i
略大于 4096,程序将再次出现段错误。在 32 位模式下,值 0x400000
很方便,因为这是 4 MB 并且对应于页目录中的一个条目。有关 x86 分页的介绍,请参阅 https://wiki.osdev.org/Paging。
在学习Linux操作系统时,我知道以下几点:
- 实模式将使用 0x10000 以下的地址
- 保护模式32bit使用4G,用户space可以使用2/3G
- 程序的虚拟内存将从 0x40000 开始到更高
那么,0x400000下面是保留的吗?
So, what's under 0x400000, is it reserved?
这是没有映射任何物理内存的虚拟地址 space。有关详细信息,请参阅 page table。
您可以查看进程的虚拟地址 space 映射:
cat /proc/<pid>/maps
0x400000
的基地址有些随意,地址 space 随机化(默认启用)在每个 运行 的不同地址加载可执行文件。您可以通过 运行ning cat /proc/self/maps
两次观察地址 space 随机化的效果,并观察到 cat
可执行文件被加载到每个 运行 上的不同虚拟地址(前提是cat
是可执行文件而不是 shell 内置文件)。
最小虚拟地址由vm.mmap_min_addr
sysctl
变量控制。在 Ubuntu 18.04.5 LTS 上,其默认值为 65536
(十六进制的 0x10000
)。
正如 Maxim 所说,它只是未映射。该区域中的页面在 CPU 的页表中被标记为“不存在”,因此访问它们会导致页面错误;并且内核知道它们没有任何物理内存、文件或交换 space 支持,因此将通过向进程传递分段错误信号 (SIGSEGV) 来处理此类页面错误,通常会杀死它。
至少要取消映射程序虚拟地址 space 的最低页,这样访问地址 0(空指针取消引用)将导致分段错误,而不是允许有错误的程序继续 运行。保留较大的区域未映射也很好,例如,如果程序尝试访问 p[i]
,其中 p
是空指针且 i
略大于 4096,程序将再次出现段错误。在 32 位模式下,值 0x400000
很方便,因为这是 4 MB 并且对应于页目录中的一个条目。有关 x86 分页的介绍,请参阅 https://wiki.osdev.org/Paging。