2015-01-02 8 views
4

Насколько я понимаю управление памятью в ядре Linux, в каждом процессе есть структура mm_struct, отвечающая за адресное пространство. Одной из важных областей памяти является стек. Это должно быть идентифицировано областью памяти vm_area_struct, а сам mm_struct имеет указатель mm_struct-> stack_start, который является адресом стека.Почему mm_struct-> start_stack и vm_area_struct-> start не указывают на один и тот же адрес?

Я пришел по коду ниже, и я не могу понять, почему любой из адресов начала/конца области памяти не равен значению mm_struct-> stack_start. Любая помощь в понимании этого была бы очень оценена. Благодаря

Некоторые из результатов загрузки скомпилированного модуля ядра:

VMA номер 14: Начало в 0x7fff4bb68000, заканчивается в 0x7fff4bb8a000 VMA номер 15: Начало в 0x7fff4bbfc000, заканчивается в 0x7fff4bbfe000 VMA номера 16: Запускается в 0x7fff4bbfe000, заканчивается в 0x7fff4bc00000 начальный код Сегмент = 0x400000, конец = 0x400854 начало сегмента данных = 0x600858, конец = 0x600a94 Stack начало сегмента = 0x7fff4bb88420

Можно обнаружить, что начало сегмента стека (0x7fff4bb88420) относится к номеру vma 14, но я не знаю, что адреса разные.

исходный код модуля ядра:

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

static int pid_mem = 1; 

static void print_mem(struct task_struct *task) 
{ 
     struct mm_struct *mm; 
     struct vm_area_struct *vma; 
     int count = 0; 
     mm = task->mm; 
     printk("\nThis mm_struct has %d vmas.\n", mm->map_count); 
     for (vma = mm->mmap ; vma ; vma = vma->vm_next) { 
       printk ("\nVma number %d: \n", ++count); 
       printk(" Starts at 0x%lx, Ends at 0x%lx\n", 
          vma->vm_start, vma->vm_end); 
     } 
     printk("\nCode Segment start = 0x%lx, end = 0x%lx \n" 
       "Data Segment start = 0x%lx, end = 0x%lx\n" 
       "Stack Segment start = 0x%lx\n", 
       mm->start_code, mm->end_code, 
       mm->start_data, mm->end_data, 
       mm->start_stack); 
} 

static int mm_exp_load(void){ 
     struct task_struct *task; 
     printk("\nGot the process id to look up as %d.\n", pid_mem); 
     for_each_process(task) { 
       if (task->pid == pid_mem) { 
         printk("%s[%d]\n", task->comm, task->pid); 
         print_mem(task); 
       } 
     } 
     return 0; 
} 

static void mm_exp_unload(void) 
{ 
     printk("\nPrint segment information module exiting.\n"); 
} 

module_init(mm_exp_load); 
module_exit(mm_exp_unload); 
module_param(pid_mem, int, 0); 

MODULE_AUTHOR ("Krishnakumar. R, [email protected]"); 
MODULE_DESCRIPTION ("Print segment information"); 
MODULE_LICENSE("GPL"); 

ответ

1

Похоже start_stack это начальный указатель стека адрес. Он вычисляется ядром при выполнении программы и основан на адресе секции стека, указанном в исполняемом файле. Я не думаю, что после этого он будет обновляться. Система использует start_stack хотя бы в одном экземпляре: для определения того, какой vma представляет «стек» (при предоставлении/proc // maps), так как vma, содержащий этот адрес, будет содержать (основной) стек.

Но учтите, что это только стопка для «основной» (начальной) нити; многопоточная программа будет иметь и другие стеки - по одному на поток. Поскольку все они имеют одинаковое адресное пространство, все потоки будут показывать один и тот же набор vmas, и я думаю, вы обнаружите, что все они имеют одинаковое значение start_stack. Но только указатель стека основного потока будет находиться в главном стеке vma. Остальные потоки будут иметь свой собственный стек vmas - это значит, что стек каждого потока может расти независимо.

1

В общем, есть один mm_struct для процесса, но многие vm_area_struct и каждый отвечает за mmaped области.

Например, в 32-разрядной системе процесс имеет виртуальное адресное пространство 4 ГБ, все из которых указываются мм_страница. Однако в пределах 4 ГБ может быть много регионов. Каждая из областей отмечена vm_area_struct, и эта область ограничена концом vm_area_struct-> start и vm_area_struct->. Итак, очевидно, что структура mm_struct содержит список vm_area_struct.

Here - подробно введение.