为了记录下自己学习Linux内核的历程,决定通过写博客来激励自己。
逻辑地址:是相对于段而言的,需要段描述符和段内偏移来组成。所有段都从0x00000000开始,只需关注段内偏移即可。而段内偏移的值恰好等于线性地址的值。
线性地址:是进程使用的地址,虚拟的地址。人为抽象出一大片地址空间给进程使用,为了方便32位地址总线存取,linux内核定义为了4G。
物理地址:是采用32位总线存取物理内存某个字节时,地址总线上电位的高低。
分段单元将逻辑地址转换成线性地址,分页单元将线性地址转换成物理地址。此处着重分析后者。
页表:是和进程的线性地址挂钩的,有其对应的线性地址。常规分页情况下,一个页表项就代表着4G线性地址中特定的4KB空间。
页:一个数据块,可以存放在任何页框或磁盘中,它是页表项所代表的4KB空间中的数据。
页框:主存的一部分,物理内存的第一个4KB就是一个页框,有其对应的物理地址。
页框描述符:内核用于记录每个页框当前的状态。
4G内任意一个线性地址,查看其前20位可以定位到页表项,通过页表项可以定位到页框,一个页框是4KB大小,正好存放一个页的数据。描述页框对应的页描述符存放在mem_map数组中,页框号对应着该数组的下标。
virt_to_page宏:根据线性地址得到页描述符。可以根据以下方式获取:线性地址=》页表项=》映射页框物理地址=》页框号pfn=》&mem_map[pfn]。
page_address函数:根据页描述符得到线性地址。需要分两种情况讨论:
1. 如果页框不在高端内存,则通过如下公式获取页框映射的线性地址:
__va((unsigned
long)(page – mem_map) << 12)
页描述符地址减去页描述符数组名得到数组下表,也就是页框号,页框号左移12位得到页框物理地址,再通过__va转换成线性地址。
2. 如果页框在高端内存,查询page_address_htable散列表,如果在散列表中找到页框,则返回线性地址;如果没有找到,则返回NULL。
阅读(1295) | 评论(0) | 转发(0) |