Ejercicio de práctica de VMA

En el último artículo, aprender el diseño de memoria de los programas de espacio de usuario basados ​​en el bloqueo involucra operaciones relacionadas con VMA. En esta sección, se usa un ejemplo simple para aprender profundamente qué es VMA y cómo está organizado.

 

Primer vistazo a la estructura de VMA

struct vm_area_struct {
	/* The first cache line has the info for VMA tree walking. */

	unsigned long vm_start;		/* Our start address within vm_mm. */
	unsigned long vm_end;		/* The first byte after our end address
					   within vm_mm. */

	/* linked list of VM areas per task, sorted by address */
	struct vm_area_struct *vm_next, *vm_prev;

	struct rb_node vm_rb;

	/* Second cache line starts here. */
	struct mm_struct *vm_mm;	/* The address space we belong to. */
	pgprot_t vm_page_prot;		/* Access permissions of this VMA. */
	unsigned long vm_flags;		/* Flags, see mm.h. */

	/*
	 * For areas with an address space and backing store,
	 * linkage into the address_space->i_mmap interval tree.
	 *
	 * For private anonymous mappings, a pointer to a null terminated string
	 * in the user process containing the name given to the vma, or NULL
	 * if unnamed.
	 */
	union {
		struct {
			struct rb_node rb;
			unsigned long rb_subtree_last;
		} shared;
		const char __user *anon_name;
	};

} ;
  • vma_start representa la dirección de inicio de este vma
  • vma_end representa la dirección final de este vma
  • Debido a que vma se vinculará a través de una lista doblemente vinculada, habrá punteros vm_next y vm_prev
  • Al mismo tiempo, para encontrar la comodidad, vma también está organizada por árboles rojos y negros, vm_rb es el nodo de árbol rojo y negro de vma
  • vm_mm es la estructura mm_struct a la que pertenece este vma
  • vm_page_prot significa el permiso correspondiente a este vma, ya sea legible, editable, ejecutable, etc.

Todavía tomamos prestada esta imagen, puede ver los miembros mmp y mmp_rb en mm_struct en task_struct. 

struct mm_struct {
	struct {
		struct vm_area_struct *mmap;		/* list of VMAs */
		struct rb_root mm_rb;
		u64 vmacache_seqnum;                   /* per-thread vmacache */

        ......

Después de comprender los datos de la organización de VMA, todavía utilizamos el ejemplo de ayer para obtener la información de cada segmento de VMA a través del módulo del controlador

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

static int mpid=1;

static void print_vma(struct task_struct *task)
{
        struct mm_struct *mm;
        struct vm_area_struct *vma;
        int count=0;

        mm = task->mm;
        printk("This mm_struct has %d vma\n", mm->map_count);

        for(vma = mm->mmap; vma; vma=vma->vm_next){
                printk("vma number %d: \n", ++count);
                printk("Start address 0x%lx, End address 0x%lx\n", vma->vm_start, vma->vm_end);
        }

        printk("Code 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 vma_start()
{
        struct task_struct *task;
        printk("Got the process id =%d\n", mpid);

        for_each_process(task) {
                if(task->pid == mpid){
                        printk("%s[%d]\n", task->comm, task->pid);
                        print_vma(task);
                }
        }
        return 0;
}

static void vma_exit()
{
        printk("print segment info module exit!\n");
}

module_init(vma_start);
module_exit(vma_exit);
module_param(mpid, int, 0);

Obtenemos el pid de la aplicación y luego pasamos los parámetros del módulo al módulo del controlador. Si coincide el mismo pid, se imprimen el nombre del proceso (campo de comunicación) y el campo PID (pid). Al mismo tiempo, obtenga cuántos vma tiene el proceso actual, imprima la dirección de inicio y la dirección final de cada vma.

Obtenga la información vma del proceso a través del comando de mapas

root:/data # cat /proc/4766/maps
00400000-0047c000 r-xp 00000000 103:23 6918                              /data/vma
0048b000-0048e000 rw-p 0007b000 103:23 6918                              /data/vma
0048e000-0048f000 rw-p 00000000 00:00 0
38382000-383a4000 rw-p 00000000 00:00 0                                  [heap]
78941af000-78941fb000 rw-p 00000000 00:00 0
78941fb000-78941fc000 r--p 00000000 00:00 0                              [vvar]
78941fc000-78941fd000 r-xp 00000000 00:00 0                              [vdso]
7fc0ed3000-7fc0f9d000 rw-p 00000000 00:00 0                              [stack]

Mire la información de impresión de nuestro controlador nuevamente

[ 2432.979096] Got the process id =4766
[ 2432.979495] vma[4766]
[ 2432.979500] This mm_struct has 8 vma
[ 2432.979504] vma number 1:
[ 2432.979508] Start address 0x400000, End address 0x47c000
[ 2432.979511] vma number 2:
[ 2432.979515] Start address 0x48b000, End address 0x48e000
[ 2432.979518] vma number 3:
[ 2432.979522] Start address 0x48e000, End address 0x48f000
[ 2432.979525] vma number 4:
[ 2432.979529] Start address 0x38382000, End address 0x383a4000
[ 2432.979532] vma number 5:
[ 2432.979536] Start address 0x78941af000, End address 0x78941fb000
[ 2432.979539] vma number 6:
[ 2432.979543] Start address 0x78941fb000, End address 0x78941fc000
[ 2432.979547] vma number 7:
[ 2432.979551] Start address 0x78941fc000, End address 0x78941fd000
[ 2432.979554] vma number 8:
[ 2432.979558] Start address 0x7fc0ed3000, End address 0x7fc0f9d000
[ 2432.979564] Code segment start=0x400000, end=0x47b76f 
               Data Segment start=0x48b770, end=0x48d348
               Stack segment start=0x7fc0f9ba00

A través de este ejemplo, entendemos claramente que cada vma se usa para describir cada segmento, y la información de cada segmento se describe en detalle a través de la estructura vm_area_struct. Y cada vma está vinculada a través de una lista doblemente vinculada. La función principal de la lista vinculada es facilitar la eliminación y la adición; otra forma de organización del árbol rojo y negro es facilitar la búsqueda.

 

 

187 artículos originales publicados · ganó 108 · 370,000 visitas

Supongo que te gusta

Origin blog.csdn.net/longwang155069/article/details/105413152
Recomendado
Clasificación