2012-04-04 7 views
7

Digamos que tenemos un struct page del espacio de direcciones de un archivo de la página en caché.¿Cómo obtener la dirección física de los datos asociados desde una página de estructura?

¿Cómo podríamos obtener la dirección física inicial de los datos de 4KB de este struct page?

Supongo que debería haber algo como el puntero data dentro de struct sk_buff, pero no lo encontré.


EDITAR

Gracias Mat y llya por las respuestas.

Después de mirar las respuestas, creo que el primer problema es identificar si el struct page se encuentra en ZONE_NORMAL o ZONE_HIGHMEM.

Durante un archivo de E/S, cuando no encontramos la página en caché, al principio asignaremos una nueva página usando page_cache_alloc_cold(). page_cache_alloc_cold() finalmente llama a alloc_pages() que parece que usará el ZONE_HIGHMEM (que en x86, es el área de memoria del kernel que comienza en PAGE_OFFSET + 896M) para su trabajo.

Así

  • creo que la respuesta de Mat es adecuado para las páginas en ZONE_NORMAL
  • Supongamos que utilizamos kmap() para encontrar la dirección física a partir de los datos de 4 KB asociada a la página de estructuras, ¿es correcto que debemos use (unsigned long)(&page)-PAGE_OFFSET para encontrar la dirección física donde almacena la estructura en sí misma?

Corrija.

+0

Piensa en 'page' como un elemento en la matriz' mem_map'. –

Respuesta

1

tendrá que asignar un page en la memoria del núcleo de la siguiente manera: (. this ver enlace por ej) se requiere

void * mapping = kmap_atomic(page, KM_USER0); 
// work with mapping... 
kunmap_atomic(mapping, KM_USER0); 

Este truco ya que no es un concepto HighMemory en Linux.

UPD: Puede usar kmap en lugar de kmap_atomic en contextos no atómicos.

+1

El OP dice que ya tiene una 'struct page', ¿por qué debería necesitar mapearla exactamente? (Por cierto: http://lwn.net/Articles/356378/, ese segundo argumento para kmap_atomic se fue en algún momento en 2009 afaict) – Mat

+0

Bueno, hay algunas limitaciones cuando se trata de HighMemory. El kernel genérico de 32 bits puede ver solo 1G de memoria (después de 0xc000000). Entonces imagina que tienes más de 4G de RAM. ¿Cómo se accede desde el kernel? –

Cuestiones relacionadas