assembly – 是否可以在不映射内核的情况下将进程映射到内存中?
OSDev wiki说:
那为什么呢?这个过程不能单独映射到内存吗?映射内核有什么好处,这不会浪费空间吗? 此外,是否可以从用户空间访问内核空间,为什么我会这样做? 解决方法
因此,当您进行系统调用时,内核不必更改页表以访问它自己的内存.例如,一直映射所有物理内存会使读取系统调用从页面缓存中的任何位置复制内容变得更便宜.
通常内核会禁用它.页表条目有一个user/supervisor bit,它控制是否可以在不在内核模式时使用它(即我认为是响铃3).因此,内核可以保留其内存映射,同时仍然保护它免受用户空间的读/写. (另见this for a diagram of nesting of page directories.) CPU具有支持这种用例的性能特性:每个PTE中都有一个“全局”位(如果设置)意味着即使CR3发生更改(即跨内核交换机,内核安装时),CPU也可以将其缓存在TLB中一个新的页面表).内核为每个进程中包含的内核映射设置它. 而且,对于那些内核映射,可能只有一个表的物理副本,每个不同的用户空间页表树的顶层页面映射级别4表(PML4)仅指向相同的内核PDPTE结构(大多数/所有这些实际上都是1GiB hugepage映射,而不是指向更多级别的条目).请参阅上面链接的图表. 内核实际上有少量内存允许用户空间读取(和执行):内核将几个4k页面called the VDSO area映射到每个进程的地址空间(位于虚拟内存的最顶端). 对于一些简单但常见的系统调用,如gettimeofday()和getpid(),用户空间可以调用这些页面中的函数(例如运行rdtsc并通过内核导出的常量来扩展结果),而不是使用syscall进入内核模式并在那里做同样的事情.对于现代x86 CPU上的内核模式往返,这可节省50到100个时钟周期,而更多的是在分派到正确的系统调用之前不需要内核中的所有内容的保存/恢复.
通过64位内核上的32位进程,整个4GiB虚拟地址空间可用于用户空间. (除了3个左右的4k VDSO页面.) 否则(当用户空间虚拟地址与内核空间虚拟地址一样宽时)Linux将上半部分用于所有物理内存的内核映射(在x86上使用1G largepages). i386 Linux有一个配置选项,可以分割1:3,IIRC,进一步限制内核,但允许更多的虚拟地址空间用于用户空间进程. IDK,如果这对于其他体系结构上的32位内核或仅x86是常见的.
它占用了一些虚拟地址空间,但你应该拥有比物理内存更多的空间.如果不这样做,则必须支付更频繁地重新映射内存的速度成本. 这就是我们拥有x86-64的原因,因此虚拟地址空间非常庞大. 48位是256 TiB,因此其中一半是128 TiB的地址空间.如果必要/有用,未来的CPU可以为更广泛的虚拟地址实现硬件支持. (The page table format supports up to 52 bit physical addresses.).对于非易失性DIMM而言,这可能会成为一个问题,提供比DRAM更高密度的内存映射存储,以及使用大量这两种地址空间的原因. 如果在单个进程中需要超过2GiB的虚拟地址空间,请使用64位系统. (或者如果你需要一个极好的进程/线程,至少使用一个64位内核.带有PAE的32位内核有时会遇到内存分配问题.请参阅一些https://serverfault.com/问题.) 某人reposted on their blog some of Linus Torvalds’ comments about PAE (Physical Address Extensions)允许在32位x86系统上拥有超过4GB的物理内存.总结:哎呀,即使有一个很好的内核端实现,它肯定比64位内核慢.除了英特尔工程师更有趣的侮辱,他们认为这对于32位操作系统来说是个好主意并解决问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |