当前位置: 技术问答>linux和unix
linux-0.11内核_段页内存管理问题
来源: 互联网 发布时间:2017-03-23
本文导语: 本帖最后由 h19930608d 于 2012-11-20 13:43:54 编辑 我的疑惑是:intel 80x86 CPU在选择分页机制后,分段是如何实现的?段基址是如何获得的?? 下面是我的理解: intel 80x86 CPU在没有采用分页机制时,是单纯的分段...
下面是我的理解:
intel 80x86 CPU在没有采用分页机制时,是单纯的分段机制,这时的线性地址就是物理地址。此时若为新进程分配内存空间,是可以根据物理空间的使用情况分配的,此时的段基址就是实际的物理地址。
但采用分页机制之后,是分段机制与分页机制共存,地址转换为:逻辑地址 --> 线性地址 --> 物理地址。此时分配内存不是连续的,也就是说所谓的段不是实际的物理段,只是逻辑上(线性地址空间上)的段。此时的分段机制在线性地址空间上为新进程分配段空间之后,然后又经分页机制映射到零碎的物理地址空间(即不连续的页面)。不管分段机制在线性地址空间上如何映射段空间,采取分页机制之后,都是零碎的物理空间,那么分段机制还有什么作用??
在linux-0.11中,是内核作者(linus)直接设定好了几个段基址。若没有事先设定段基址,分配内存时由系统根据线性地址空间使用情况设置段基址,我想这也没有任何意义,而且难以实现(因为还要记录线性地址空间使用情况)。
上面说了那么多,总的就是说,在采取分页机制之后,分段机制是不是多余的??我感觉它没任何意义,且不好实现(因为还要记录线性地址空间使用情况)。
若想一起学习linux-0.11内核源码的,可以联系我,呵呵,,,e9999e@163.com
|
分段是intel x86处理器要求的一种地址转换处理机制
现在的Linux其实只用到了分页机制而巧妙地绕过了分段机制,就是Linux下所有的段的基址都是否0
以最新的kernel code为例, 根据段描述符定义,可以看到四个段基址都为0
struct desc_struct {
union {
struct {
unsigned int a;
unsigned int b;
};
struct {
u16 limit0;
u16 base0;
unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
};
};
} __attribute__((packed));
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
现在的Linux其实只用到了分页机制而巧妙地绕过了分段机制,就是Linux下所有的段的基址都是否0
以最新的kernel code为例, 根据段描述符定义,可以看到四个段基址都为0
struct desc_struct {
union {
struct {
unsigned int a;
unsigned int b;
};
struct {
u16 limit0;
u16 base0;
unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
};
};
} __attribute__((packed));
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },