免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4096 | 回复: 23
打印 上一主题 下一主题

LINUX的存储问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-28 08:59 |只看该作者 |倒序浏览
ULK2说(2.4.6节和7.1.6节),LINUX内核不能直接访问1G以上的内存,如果不考虑LINUX的提供非直接访问方法,是不是意味1G以上的RAM也不能被应用进程分配做页帧呀?
换句话说,若进程使用1G以上的内存,也必须经过内核经过间接的映射之后才能使用呀?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-07-28 09:21 |只看该作者

LINUX的存储问题

1、ULK2说(2.4.6节和7.1.6节),LINUX内核不能直接访问1G以上的内存,如果不考虑LINUX的提供非直接访问方法,是不是意味1G以上的RAM也不能被应用进程分配做页帧呀?

linux内核可以访问1G以上的物理内存。内核能够映射的虚拟存储空间是和机器的位数相关的,于实际的物理内存大小没有关系。

2、换句话说,若进程使用1G以上的内存,也必须经过内核经过间接的映射之后才能使用呀?

内核对于存储器的映射属于动态的。系统在引导的时候便获得了内存的大小,为此在GDT,MDT和LDT的长度成员中已经获得了数组的大小,这个大小就是内存页面的个数。系统在引导成功后,便建立了存储器的数据结构(在linux内核中便是几个队列)。应用程序调用只不过是向内核申请页面的过程。

论坛徽章:
0
3 [报告]
发表于 2003-07-28 09:28 |只看该作者

LINUX的存储问题

原帖由 "蓝色键盘" 发表:
1、ULK2说(2.4.6节和7.1.6节),LINUX内核不能直接访问1G以上的内存,如果不考虑LINUX的提供非直接访问方法,是不是意味1G以上的RAM也不能被应用进程分配做页帧呀?

linux内核可以访问1G以上的物理内存。内核能够映射..........
   
首先:我想说LINUX的地址映射有点特殊:希望你把ULK2看完了再帮我想想.而且LINUX/X86确确实实同物理内存的大小有关系,朝过896M以上的RAM,内核不能直接访问了,必须经过一个特殊的机制.
因为LINUX内核地址空间的虚实转换只是减一个常数,实虚转换只是加一个常数(0XC0000000),因此大于1G的时候,就超出了32位的地址范围了,

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2003-07-28 09:36 |只看该作者

LINUX的存储问题

偶觉得x86的intel系列CPU,要看是那个了。

286和386差别很大。286当年曾经只能支持实地址模式。如果你说的是286那么你上面的描述是又道理的。linux内核对此处理的比较复杂。偶压根就没有耐心看。也没有发言的依据。

到了386才算是真正的保护模式。这个估计你比我知道的多。

在386到586之间。intel cpu事实上是36位的。而且intel CPU天生支持段时管理,而linux中属于页式管理,为此做了从段时到页式的转化。

论坛徽章:
0
5 [报告]
发表于 2003-07-28 09:40 |只看该作者

LINUX的存储问题

原帖由 "蓝色键盘" 发表:
偶觉得x86的intel系列CPU,要看是那个了。

286和386差别很大。286当年曾经只能支持实地址模式。如果你说的是286那么你上面的描述是又道理的。linux内核对此处理的比较复杂。偶压根就没有耐心看。也没有发言的依据..........
   
1.286LINUX实际上不支持的,当然在兼容性还是有的.
2.这里同段没有关系,因为这里的虚地址实际上是指X86的线性地址.其实无论是LINUX还是WINDOWS,还是SCO OSR5UNIX都只是支持0:32所谓的平面模式,

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2003-07-28 09:44 |只看该作者

LINUX的存储问题

你认为386能够达到的最大寻址空间时多少?

486和现在的P4呢?

论坛徽章:
0
7 [报告]
发表于 2003-07-28 10:03 |只看该作者

LINUX的存储问题

原帖由 "蓝色键盘" 发表:
你认为386能够达到的最大寻址空间时多少?

486和现在的P4呢?
   
对于X86的存储系统的管理,有三个概念一定要搞清楚:虚地址,线性地址,物理地址.
345都是提供32位的地址总线,PPRO以后的都是36位的地址总线,至于虚地址,是可以认为是46位,物理地址可以认为是36位(6以后),只是线性地址一直都是32位的.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2003-07-28 13:18 |只看该作者

LINUX的存储问题

加入在Linux 中,4GB的虚存需通过32-bit 地址进行寻址。(Linux 中虚拟地址与线形地址为同一概念)虚拟地址被分割成3 个子位段,其中2 个子位段包含10 位, 1 个子位段包含12 位。

3个子位段分别表示不同含义:子位段1 指向被称作页目录(PGD)的一张表,子位段2 指向被称作页表(PTE)的一张表,子位段3 指向页内地址。

在i386机器上Linux的页表结构实际为两级,PGD和PMD页表是合二为一的。所有有关PMD的操作实际上是对PGD的操作。所以原代码中形如*-pgd-*()和*-pmd-*()的函数实现的功能也是一样的。
页目录(PGD) 是一个大小为4K 的表,每一个process只有一个页目录,以4 字节为一个表项,分成1024 个表项(或称入口点);该表项的值为所指页表的始地址。32位虚拟地址的第1 个子位段共10 位,其值的范围从0 到1023,对应于页目录的一个入口点。
页目录(PTE)的每一个入口点的值为此表项所指的一页框(page frame),32位虚拟地址的第2 个子位段共10 位,其值的范围从0 到1023。
页框(page frame)并不是物理页,它指是虚存的一个地址空间。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
9 [报告]
发表于 2003-07-28 13:29 |只看该作者

LINUX的存储问题

好像我们讨论的跑题了,呵呵

看你提出的问题。偶觉得一起看看linux中进程是地址映射过程可能有所帮助。

1、Linus虚存采用动态地址映射方式,即Process的地址空间和存储空间的对应关系是在程序的执行过程中实现的:Process每用到一个地址时, 都需虚存的地址转换机构把虚拟地址转化为内存的实际地址。

2、每一个进程的task_struct中都有一个结构mm_struct,此结构包含了进程中与储存管理相关的大部分信息,其申明如下:
struct mm_struct {
        int count;        // 使用该mm结构的个数,如果是多处理机,则有可能count >; 1
        pgd_t * pgd;         /* 进程页目录的起始地址,如上图所示 */
        unsigned long context;
        unsigned long start_code, end_code, start_data, end_data;
/*start_code、end_code:进程代码段的起始地址和结束地址。
start_data、end_data:进程数据段的起始地址和结束地址。*/
        unsigned long start_brk, brk, start_stack, start_mmap;
        unsigned long arg_start, arg_end, env_start, env_end;
/* arg_start、arg_end:调用参数区的起始地址和结束地址。
env_start、env_end:进程环境区的起始地址和结束地址。*/
        unsigned long rss, total_vm, locked_vm;
                        /* rss:进程内容驻留在物理内存的页面总数。*/
        unsigned long def_flags;
        struct vm_area_struct * mmap;     /* 以双向链表组成的vma模块的首指针。 */
        struct vm_area_struct * mmap_avl;         /* 以avl树结构组成的虚拟空间的首指针。*/
        struct semaphore mmap_sem;
}

3、用户共有4GB的虚存空间,实际可申请的虚存空间为0~3GB。3GB~4GB的虚存空间在用户进程创建时,已由函数fork()将kernel的代码段和数据段映射到3GB~4GB的虚存空间。因而所有进程的3GB~4GB的虚存空间的映象都是相同的,从而以这种方式使所有进程共享kernel的代码段和数据段。

4、进程的虚拟空间通常由一个个vma块组成,这些块的结构如下所示:
struct vm_area_struct {
        struct mm_struct * vm_mm;        /* VM area parameters */
        unsigned long vm_start;                  //该vma块代表的使用虚拟空间的起始地址
        unsigned long vm_end;                 //该vma块代表的使用虚拟空间的结束地址
        pgprot_t vm_page_prot;                  //保护位  
        unsigned short vm_flags;                 //标志位
/* AVL tree of VM areas per task, sorted by address */
        short vm_avl_height;                          //avl树高度
        struct vm_area_struct * vm_avl_left;                         //vma块的左子节点
        struct vm_area_struct * vm_avl_right;                 //vma块的右子节点
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct * vm_next;         /* 在按地址大小排列的单向链表上的下一个指针*/
/* for areas with inode, the circular list inode->;i_mmap */
/* for shm areas, the circular list of attaches */
/* otherwise unused */
        struct vm_area_struct * vm_next_share;
        struct vm_area_struct * vm_prev_share;
/* more */
        struct vm_operations_struct * vm_ops;        //对VMA块进行操作的函数集
        unsigned long vm_offset;                               
        struct inode * vm_inode;                                //该VMA块对应的文件
        unsigned long vm_pte;                        /* shared mem */
};
采用avl树的优点是可以快速找到相关地址所在的vma块。同时,同一个任务的vma块还按前后顺序排成一个线性链表。

5、sys_execve系统调用负责将可执行文件映象载入到内存,与内存相关的操作主要是: 通过调用exit_mmap清除当前进程的所有的虚存块,通过调用clear_page_table清除当前进程的页表项,通过调用flush_old_signals清除当前进程的残留信号,通过调用flush_old_files清除当前进程的已打开文件,从而将当前进程掏空,成为一个空壳。然后系统根据bprm结构更新current进程的控制块,并通过调用两次do_mmap分别将执行文件的代码段和数据段映射到虚存。系统一般只将前两页载入物理内存中,同时分配一页给堆栈,其它的均留在硬盘中通过虚拟内存映射机制映射为虚拟内存。当运行中发生缺页中断时,系统处理缺页中断,将缺页调入物理内存中,如果发生物理内存不足的情况,则由kswapd()选择合适的页调入交换文件中或扔掉(如未发生写操作)。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
10 [报告]
发表于 2003-07-28 13:32 |只看该作者

LINUX的存储问题

可能理解存在不少错误,menp9999兄给予指正。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP