web-dev-qa-db-fra.com

Comment obtenir la taille de la page du noyau Linux par programme

Je travaille sur un module Linux pour IA64. Mon problème actuel est que le pilote utilise les macros PAGE_SIZE et PAGE_SHIFT pour l'allocation de page dma. Le problème que je rencontre est que la machine compilant le pilote n'est pas celle qui devait l'exécuter. Ainsi, si PAGE_SIZE sur la machine à compiler est 2 ^ 14K et la machine de destination est 2 ^ 16K, le pilote échoue. 

Je ne veux pas transformer cette question en un problème de «bonne pratique» concernant la compilation de modules sur des machines autres que celles qui les exécutent. Je comprends les problèmes à ce sujet. Ce que j'ai trouvé, c'est que les gens utilisent principalement getpagesize () ou sysconf (_SC_PAGE_SIZE). Ces deux options sont hors des en-têtes du noyau ia64, donc je ne peux pas les utiliser. Existe-t-il un autre moyen d'obtenir le runtime PAGE_SIZE?

Options que je regarde:

  • Lire un fichier dans/proc?
  • appel système?
  • Autre fonction qui me permet de calculer PAGE_SIZE par inférence (par exemple, ORDER, getpageshift, etc.)?
  • Autre?
32
Freddy

C'est ce que j'ai finalement fait:

  • Re-travailler mon module actuel pour prendre un nouveau paramètre de module appelé page_shift et l'utiliser pour calculer la PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
  • Création d'un wrapper de chargeur de module qui récupère le système actuel PAGE_SHIFT à l'aide de l'API getconf de libc. Ce wrapper obtient le décalage de la page système actuelle et le transmet en tant que paramètre de module. 

Actuellement, le module est chargé sur différentes architectures avec différentes PAGE_SIZE sans aucun problème.

5
Freddy

Essayez d’utiliser l’utilitaire getconf , qui vous permettra de récupérer facilement le format de page.

getconf PAGESIZE
46
vetri

Une méthode approximative consiste à lire /proc/meminfo et à vérifier Mapped taille (sur le mien, ses 52544 ko à partir de maintenant), puis à vérifier nr_mapped dans /proc/vmstat (sur le mien, son 131136 à partir de maintenant). Enfin PAGE_SIZE = Mapped/nr_mapped. Parfois, cela vous donne une valeur précise (comme dans l'exemple actuel que j'ai cité) et parfois, il est approximatif mais très proche . J'espère que cela vous aidera!

17
Pavan Manjunath

Si vous essayez de construire un module de noyau, vous devez avoir au moins les en-têtes de noyau configurés pour le noyau sur lequel le module sera exécuté. Ceux-ci définiront les macros de taille de page dont vous avez besoin. Si vous n'avez pas les en-têtes correctement configurés, le noyau refusera de charger votre module.

Et il n'y a rien de mal à compiler un module sur une machine pour en exécuter une autre, même s'il s'agit d'une architecture différente. Vous avez juste besoin de construire avec la source de noyau correcte.

6
JayM

Une façon de trouver la taille de la page est de l'obtenir à partir de smaps pour un processus.

Par exemple:

cd /proc/1
grep -i pagesize smaps

KernelPageSize:        4 kB
MMUPageSize:           4 kB
3
ria

Je crains qu'il soit impossible de le faire, car la taille de la page est définie en tant que partie intégrante du noyau. Une connaissance de la taille de la page est nécessaire dans le cas d'une chaîne d'outils que vous utilisez également pour compiler le module du noyau.

Donc, au moins avec l’architecture actuelle du noyau, il est impossible de le faire.

0
kumar

Vous pouvez simplement exécuter un test, créer un fichier avec des décalages différents et visualiser ceux qui échouent. Cela peut être gênant dans un module de noyau, mais peut-être pourriez-vous utiliser un autre test de ce type.

0
Justin Cormack