关于内存映射的一些疑问

xiaoxiao2021-02-28  39

http://www.cnblogs.com/hanyan225/archive/2010/10/25/1860730.html http://wenku.baidu.com/link?url=lpFmJHGfdAQlaEO6zsW6W_11hK7FuCGcuSn9rnJJHwaZIDK7oNi14KK4pQ1KMnfQRHNjPG3eJ85wwJ10-OMZ37fUG7C1B-kofVYewdOVU0O http://www.cnblogs.com/dyllove98/archive/2013/06/12/3132940.html http://wenku.baidu.com/view/df65b66527d3240c8447ef14.html 1.虚拟地址的4G大小和物理地址的4G大小怎么来的? 虚拟地址的大小是由这个系统可以表示地址的变量来决定的,及指针的长度,32位的系统指针有4个字节即32位,那么这个变量的可寻址空间就是0x0-0xffffffff(2^32/4G) 物理地址的大小是由cpu的地址总线个数来决定的,32位的cpu有32个地址总线,此时这个地址总线可以组成的地址空间就是0x0-0xffffffff(2^32/4G) 2.一般前896M内存和虚拟地址的3G+896M是一一映射关系,若是2G的物理内存,剩余的2G-896M被谁映射? 在32位系统上,高于896M的物理内存称为高端内存。内核地址空间为 3G-4G。3G ~ 3G+896M为直接映射区,也就是说物理地址和内核虚拟地址只差3G的偏移量, 比如说,内核中某个变量地址为3G+24M,那么这个变量所在的物理地址必然是24M。内核还剩下128M的地址空间,这些是干什么用的呢?因为物理地址可能高于1G, 高于1G的地方在内核里无法直接寻址,那怎么办的,这128M就是用来映射高于896M部分的内存的 内核地址空间的后128MB专门用于映射高端内存,否则,没有线性地址的高端内存不能被内核所访问。这些高端内存的内核映射显然是暂时映射的, 否则也只能映射128MB的高端内存。当内核需要访问高端内存时就临时在这个区域进行地址映射,使用完毕之后再用来进行其他高端内存的映射。 http://nxlhero.blog.51cto.com/962631/711805/ http://wenku.baidu.com/link?url=lpFmJHGfdAQlaEO6zsW6W_11hK7FuCGcuSn9rnJJHwaZIDK7oNi14KK4pQ1KMnfQRHNjPG3eJ85wwJ10-OMZ37fUG7C1B-kofVYewdOVU0O 3.现在知道我们访问一个内存地址时候是访问一个虚拟地址,然后由mmu翻译为物理内存地址去访问。如果要访问总线上除过挂载物理内存的那片地址以外的地址需要怎么访问? 一个条件,开启mmu后,在内核态要访问外设地址,需要将外设地址映射到虚拟地址的内核空间中预留的专们用于映射外设地址的地址空间,而映射方式就两种: (1)静态映射:先建立映射表,然后按照映射表的地址安排去操作映射的外设的虚拟地址(可使用io_address)(2)动态映射ioremap 程序中的的数据段代码段等等在编译的时候都安排好了地址,这个地址是虚拟地址,如果要访问总线上的其他寄存器则需要使用ioremap(动态)也可静态的去将这个地址映射到虚拟内核的 虚拟地址空间(3G-4G这一段是内核虚拟地址空间,1G-3G是用户虚拟地址空间)才可以访问。ioremap的作用是:将一个IO地址空间映射到内核的虚拟地址空间方便访问。 4.linux中在【【【用户态】】】采用了延迟分配物理内存的策略,对于进程的内存分配请求,系统先为进程分配一以页为单位大小(虚拟内存和物理内存的最小单位均为页,一页的大小是4K)的虚拟内存,等到程序实际用到这块内存的时候才去产生一个缺页(page fault )在物理内存上分配这块物理内存。但是在【【【内核态】】】他是必须立刻满足该申请内存的请求 ,并且这个请求一定是正确合理的,直接给分配物理内存,不会等到用的时候才去分配 在内核态申请内存比在用户态申请内存要更为直接,它没有采用用户态那种延迟分配内存技术。内核认为一旦有内核函数申请内存,那么就必须立刻满足该申请内存的请求, 并且这个请求一定是正确合理的。相反,对于用户态申请内存的请求,内核总是尽量延后分配物理内存,用户进程总是先获得一个虚拟内存区的使用权, 最终通过缺页异常获得一块真正的物理内存。 5.如果物理内存超过896M,那虚拟地址的3G-(3G+896M)一一映射完物理内存的896M,剩余的128M虚拟地址空间将映射剩余的物理内存,此时这些内存是高端内存, 那什么样的场景下才会用到高端内存? 用户态的程序分配内存时,都优先从高端内存分配。 内核中,主要就是教科书上说的:vmalloc、固定映射、临时映射等。 6.内核空间会线性映射前896M的物理内存,内核中的地址会直接线性映射过来,那么此时用户空间中程序的代码段,数据段,等等他们会映射到物理内存的哪块地址?/用户空间是如何使用 /映射物理内存的? 应用程序的布局, 除了首先搜索HIGHMEM,用户空间的映射关系也不是直接建立,而是通过缺页异常(page fault)来实现的。比如代码段是通过缺页异常而读取文件并完成映射的, 数据段通过 mmap或 brk 首先来完成虚拟内存分配,然后通过缺页异常来完成物理内存的映射。每个 mm都有个vma链表用来记录此进程中用户空间虚拟地址分配的状态和权限。 当发生缺页异常并且引起缺页异常的地址是在用户空间时, 内核会查找当前任务mm中的 vma 链表来判断是访问越界还是需要申请物理页面和添加映射。如果存在 vma 和访 问权限有效,【【【内核首先会在 HIGHMEM ZONE 】】】(此为高端内存)的 buddy 系统中请求可用的物理页。如果请求成功,则请求成功并进行相应的映射, 如果没有,则在【【【Normal Zone】】】(低端内存即内核空间映射的物理内存) 的 buddy 系统中继续申请。 7.vmalloc是将物理内存的高端内存上与虚拟地址空间的3G+896M-4G这128M虚拟内存空间进行映射,那么如何物理内存小于896M即没有高端物理内存时,vmalloc这个操作向哪块物理内存 申请空间呢? 8.内核有多种内核分配机制/分配器,根据内核【【【函数调用接口】】】将启用不同的内存分配器 9.重点看这个http://wenku.baidu.com/view/6b4ced30770bf78a64295431.html?re=view 基于ARM CPU的Linux物理内存管理-更新 http://wenku.baidu.com/link?url=nxOvIzeXAV2GWzbTSR-Lk-XfKVsPy23GCJaqtIRPkT84nAE-dQqA3lWElWuK5kLQcvJ29JLpzhed4huh0d6hUeDH5o97vebNaWYrtWIw04u需要打印 http://wenku.baidu.com/link?url=lpFmJHGfdAQlaEO6zsW6W_11hK7FuCGcuSn9rnJJHwaZIDK7oNi14KK4pQ1KMnfQRHNjPG3eJ85wwJ10-OMZ37fUG7C1B-kofVYewdOVU0O需要打印 http://www.cnblogs.com/dyllove98/archive/2013/06/12/3132940.html需要打印 10.为什么就可以使用*0xxxxx这样的操作直接去设置一个总线上非预留给物理内存的的寄存器地址? 当未开启mmu时,*0xxx这样的操作代表操作的是物理地址 当开启mmu时,*0xxx这样的操作代表操作的是虚拟地址 再开启的情况下我们使用*0xxx,这个地址一定是经过IO_address映射过而得到的一个虚拟地址,或者是类似IO_address这种我们自己封装的接口, IO_address的实现是将这些外设地址映射到内核空间的io内存区/ioremap区。但是在调用这个宏之前需要先做一个静态映射表,需要注册一个相关的结构体, 即将外设地址和内核空间中预留的IO空间一一映射起来,以表示映射关系已经建立好,否则我们直接调用IO_address这个宏,它内部偏移得到的虚拟地址怎么找到正确的外设地址呢?是找不到的。 所以,静态映射比较浪费内存空间(因为是一一映射),反之ioremap的这种动态映射就比较省虚拟空间 一般使用*0xxxx的操作是适用于静态映射的虚拟地址 使用动态映射的虚拟地址一般用专用的writel/readl这种api。 11.ioremap可以将外设物理地址映射到虚拟地址的内核空间,这个映射是怎么实现的?使用静态映射内存的方式将外设地址映射到内核空间的宏io_address在使用前是不是应该确保前提是I/O静态映射完成? 但是在调用这个宏之前需要先做一个静态映射表,需要注册一个相关的结构体 12。如果物理内存小于896M,那么虚拟地址空间是如何映射的? 全部固定映射为内核空间

转载请注明原文地址: https://www.6miu.com/read-2629761.html

最新回复(0)