来源:
http://bbs.chinaunix.net/thread-2058683-1-1.html
1. 创建一个vm_area_struct; 2. 圈定一个虚用户空间,将其起始结束地址(elf段中已设置好)保存到vm_start和vm_end中; 3. 将磁盘file句柄保存在vm_file中; 4. 将对应段在磁盘file中的偏移值(elf段中已设置好)保存在vm_pgoff中; 5. 将操作该磁盘file的磁盘操作函数保存在vm_ops中; 6. 注意这里没有为对应的页目录表项创建页表,更不存在设置页表项了; § § § +------§->+--------------+ § | § | Disk file | § | § | | § +----------------+ | +---§->|--------------| § | vm_area_struct | | | § | Seg Content | § |----------------| | | § |--------------| +----------------+<-§-------- vm_start | | | § | | | 圈定了一个未映 | § +----- vm_end | | | § | | | 射到物理内存的 | § | | vm_file--------+ | § +--------------+ | vm_area_struct | § | | vm_pgoff ---------+ § +----------------+<-§--+ | vm_ops --------+ § § | | | § § +----------------+ | § § | § § +----------------------+ § § | § § +->+-----------------------+ § § | file_private_map | § § |-----------------------| § § | nopage:filemap_nopage | § § | ..... | § § +-----------------------+ § user space § kernel § disk [ 本帖最后由 frank_seng 于 2008-5-6 15:45 编辑 ] |
|
|
|
|
| |
帖子
-
228
主题
-
94
精华
-
2
可用积分
-
252
专家积分
-
0
在线时间
-
53 小时
注册时间
-
2007-07-17
最后登录
-
2013-04-12
论坛徽章:
-
0
|
回复 #1 frank_seng 的帖子
从上文中可知elf_map时并没有将文件内容读入内存,假设现在程序中有一条指令需要读取上面vm_start---vm_end之间的某内容,例如mov [0x08000011], %eax,那么将会执行如下序列: * CPU依据CR3(current->pgd)找到0x08000011地址对应的pgd[ i ],由于该pgd[ i ]内容保持为初始化状态即为0,导致CPU异常; * do_page_fault被调用,在该函数中,为pgd[ i]在内存中分配一个页表,并让该表项指向它,如下图所示: pgd +-----+ |-----| pt | i |--->+-----+ |-----| |-----| | | | j | +-----+ |-----| | | +-----+ 注意:这里i为0x08000011高10位,j为其中间10位,此时pt表项全部为0(pte[j]也为0); * 为pte[j]分配一个真正的物理内存页面,依据vm_area_struct中的vm_file、vm_pgoff和vm_ops,调用filemap_nopage将磁盘file中vm_pgoff偏移处的内容读入到该物理页面中,如下图所示: +-------------+ | Disk file | | | |-------------| | Seg Content----+ |-------------| | pgd | | | +-----+ | | |② |-----| pt +-------------+ | | i |--->+-----+ | |-----| |-----| ① page | | | | j |------->+-----+<---+ +-----+ |-----| | | | | | | +-----+ | | +-----+ ①.分配物理内存页面; ②.从磁盘文件中将内容读取到物理内存页面中; |
|