深入解析Linux进程虚拟地址空间(VAS)与内存映射
1. 进程VAS中的glibc映射
在进程的虚拟地址空间(VAS)里,glibc被映射到用户虚拟地址(UVA),其值为0x00007feb7b85b000。不过要注意,这个地址是运行时依赖的,并且会因地址空间布局随机化(ASLR)机制而有所不同。出于安全考虑,尤其是在x86以外的架构上,使用objdump(1)工具来查找这类详细信息会更好。对“Hello, world”二进制可执行文件执行strace(1)命令,会看到大量的mmap()系统调用,这些调用用于映射glibc和其他段。
2. 超越printf() API
我们知道,printf(3) API会转换为write(2)系统调用,该调用会将“Hello, world”字符串写入标准输出(默认是终端窗口或控制台设备)。由于write(2)是系统调用,当前运行此代码的进程(即进程上下文)必须切换到内核模式,运行write(2)的内核代码。但这里有个问题,write(2)的内核代码位于内核VAS中,如果内核VAS在“盒子”之外,我们该如何调用它呢?
一种方法是将内核放在一个单独的4GB VAS中,但这种方法会导致上下文切换非常缓慢,所以通常不会采用。实际上,用户和内核的VAS处于同一个“盒子”里,也就是可用的VAS。具体做法是按照一定的用户:内核(User:Kernel :: u:k)比例划分可用地址空间,这被称为VM分割(VM split),比例u:k通常以GB、TB甚至PB为单位表示。
例如,在运行Linux的ARM - 32系统上,常见的是2:2 GB的VM分割,即4GB的进程VAS被划分为2GB的用户空间和2GB的内核空间
超级会员免费看
订阅专栏 解锁全文
66

被折叠的 条评论
为什么被折叠?



