1. 概述
关于进程地址空间以前的疑问是:
- 两个进程使用相同的虚拟地址,会不会被映射到同一个物理地址?
不会,每个进程都会有不同的pgd,保证相同的虚拟地址不会被映射到同一个物理地址。
struct task_struct—>mm(struct mm_struct)—>pgd(pgd_t)
2)ELF文件内容是怎么被加载到进程地址空间?
这边文章主要讲:
1)进程的pgd是什么时候分配的?pgd是什么时候被加载到CR3中?
2)进程的地址空间什么时候被分配?
源码版本:2.6.11
2. 分析
2.1 pgd分配
函数调用流程是:
do_fork()--->copy_process()-->copy_mm()-->mm_init()--->mm_alloc_pgd()
2.2 VMA的分配
其他
/**
* kmem_cache_alloc - Allocate an object
* @cachep: The cache to allocate from.
* @flags: See kmalloc().
*
* Allocate an object from this cache. The flags are only relevant
* if the cache has no available objects.
*/
void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
{
return __cache_alloc(cachep, flags);
}
Q:kmem_cache_alloc分配得到的object大小是多大?由哪个参数决定?
A: object大小由cachep参数确定,大小由cachep创建kmem_cache_create中的size指定。
使用例子:
1268 /* SLAB cache for mm_struct structures (tsk->mm) */
1269 kmem_cache_t *mm_cachep;
1270
1271 void __init proc_caches_init(void)
1272 {
...............
1288 mm_cachep = kmem_cache_create("mm_struct",
1289 sizeof(struct mm_struct), 0,
1290 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
1291 }
#define allocate_mm() (kmem_cache_alloc(mm_cachep, SLAB_KERNEL))
通过kmem_cache_create函数创建名叫“mm_struct”,大小为sizeof(struct gamm_struct)的slab缓存。