안녕하세요 호서대학교 석사(과정) 이우영입니다.


방학이 끝났습니다. 다들 보람찬 방학이였으면 좋겠내요

(학생들만요 ㅎㅎ)


오늘은 메모리 영역에 관련해서 알아보도록 하겠습니다.


메모리 영역


 

커널은 프로세스의 주소공간을 mm_struct 라는 구조체로 정의 했습니다.


여기에는 프로세스가 사용하는 메모리 정보를 모두 포함 하고 있습니다.


include/linux/mm_types.h 에 보면


 190struct mm_struct {
 191        struct vm_area_struct * mmap;           /* list of VMAs */
 192        struct rb_root mm_rb;
 193        struct vm_area_struct * mmap_cache;     /* last find_vma result */
 194        unsigned long (*get_unmapped_area) (struct file *filp,
 195                                unsigned long addr, unsigned long len,
 196                                unsigned long pgoff, unsigned long flags);
 197        void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
 198        unsigned long mmap_base;                /* base of mmap area */
 199        unsigned long task_size;                /* size of task vm space */
 200        unsigned long cached_hole_size;         /* if non-zero, the largest hole below free_area_cache */
 201        unsigned long free_area_cache;          /* first hole of size cached_hole_size or larger */
 202        pgd_t * pgd;
 203        atomic_t mm_users;                      /* How many users with user space? */
 204        atomic_t mm_count;                      /* How many references to "struct mm_struct" (users count as 1) */
 205        int map_count;                          /* number of VMAs */
 206        struct rw_semaphore mmap_sem;
 207        spinlock_t page_table_lock;             /* Protects page tables and some counters */
 208
 209        struct list_head mmlist;                /* List of maybe swapped mm's.  These are globally strung
 210                                                 * together off init_mm.mmlist, and are protected
 211                                                 * by mmlist_lock
 212                                                 */
 213
 214        /* Special counters, in some configurations protected by the
 215         * page_table_lock, in other configurations by being atomic.
 216         */
 217        mm_counter_t _file_rss;
 218        mm_counter_t _anon_rss;
 219
 220        unsigned long hiwater_rss;      /* High-watermark of RSS usage */
 221        unsigned long hiwater_vm;       /* High-water virtual memory usage */
 222
 223        unsigned long total_vm, locked_vm, shared_vm, exec_vm;
 224        unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
 225        unsigned long start_code, end_code, start_data, end_data;
 226        unsigned long start_brk, brk, start_stack;
 227        unsigned long arg_start, arg_end, env_start, env_end;
 228
 229        unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
 230
 231        cpumask_t cpu_vm_mask;
 232
 233        /* Architecture-specific MM context */
 234        mm_context_t context;
 235
 236        /* Swap token stuff */
 237        /*
 238         * Last value of global fault stamp as seen by this process.
 239         * In other words, this value gives an indication of how long
 240         * it has been since this task got the token.
 241         * Look at mm/thrash.c
 242         */
 243        unsigned int faultstamp;
 244        unsigned int token_priority;
 245        unsigned int last_interval;
 246
 247        unsigned long flags; /* Must use atomic bitops to access the bits */
 248
 249        struct core_state *core_state; /* coredumping support */
 250
 251        /* aio bits */
 252        spinlock_t              ioctx_lock;
 253        struct hlist_head       ioctx_list;
 254
 255#ifdef CONFIG_MM_OWNER
 256        /*
 257         * "owner" points to a task that is regarded as the canonical
 258         * user/owner of this mm. All of the following must be true in
 259         * order for it to be changed:
 260         *
 261         * current == mm->owner
 262         * current->mm != mm
 263         * new_owner->mm == mm
 264         * new_owner->alloc_lock is held
 265         */
 266        struct task_struct *owner;
 267#endif
 268
 269#ifdef CONFIG_PROC_FS
 270        /* store ref to file /proc/<pid>/exe symlink points to */
 271        struct file *exe_file;
 272        unsigned long num_exe_file_vmas;
 273#endif
 274#ifdef CONFIG_MMU_NOTIFIER
 275        struct mmu_notifier_mm *mmu_notifier_mm;
 276#endif
 277};


그럼 이 구조체의 필드 값들을 간단하게 출력 해보도록 하겠습니다.

09_mm_struct.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>

int __init module_start( void )
{
	struct task_struct *task;
	struct mm_struct *mm;

	for_each_process(task)
	{
		
		printk("task_id = %d ",task->pid);
		
		if(mm = task->mm)
		{
			printk("start_code = %x ",mm->start_code);
			printk("end_code = %x ",mm->end_code);
			printk("start_data = %x ",mm->start_data);
			printk("end_data = %x \n",mm->end_data);
		}
		else
		printk("kernel task\n");
	}
	return -EBUSY;
}

void __exit module_end( void )
{
}

module_init(module_start);
module_exit(module_end);

MODULE_LICENSE("GPL");

모든 프로세스의 mm_struct의 필드 값을 출력 하였습니다.

간단하게 프로세스의 코그영역과 data 영역을 해보았습니다.

mm_struct.png

커널 프로세스 들은 메모리 영역을 갖지 않기 때문에 출력을 안했습니다.

자세하게 보면 이상한 점이 눈에 보일겁니다

코드 영역의 시작주소가 다 0x8000 번지 입니다. ????

어떻게 모든 프로세스들이 같은 주소에서 시작할 수 있을까요?

그 이유는 MMU 때문입니다. MMU에 의해서 모든 프로세스는 자신들의 고유의 영역에 있다고 생각을 합니다.

그럼 실제 메모리의 영역은 어디에 나타 날까요? 

mm_struct 의 필드 중 struct vm_area_struct *mmap 이 있습니다. 여기에 실제 메모리 주소가 들어 있습니다.

vm_area_struct 는 다음시간에 알아 보도록 하겠습니다.

그럼 다음시간에 만나요~