Pregunta

Tengo problemas para cargar un módulo de núcleo, hay una gran estructura de datos, alrededor del tamaño de 2 GB de memoria, ya sea que prealloco la tabla (para que se muestre en .BSS cuando lo hago. size -A module.ko o intentar vmalloc() En el momento de la carga, la carga del módulo falla con insmod: error inserting 'module.ko': -1 Cannot allocate memory.

Intenté depurar el problema en Usermode Linux, pero obtengo un montón de Segfaults (que se puede continuar en GDB, pero termino con un mensaje de consola overflow in relocation type 10 val <value in the ball park of 6G> y 'module' likely not compiled with -mcmodel=kernel. Supongo que con Kbuild la -mcmodel Debería tener razón, ¿verdad?

Entonces las preguntas son:

  1. ¿Existe un límite genérico de 2G para el tamaño del módulo del núcleo Linux?
  2. ¿Existe un límite 2G específico para los módulos de núcleo en UserNode Linux (I pensar que en el pasado he notado que un módulo de núcleo grande necesita un bloque de memoria limpio y continuo ...)
  3. ¿Puedo especificar? -mcmodel=large ¿Para un módulo de núcleo y espera que funcione?

He probado esto en Debian Squeeze, 64 bits, 2.6.32-5-amd64 (host) con 8 GB de memoria y 2.6.32 en UML con memoria 4G, por lo que esto debería no ser un problema ordinario fuera de la memoria.

Crédito adicional por trabajar alrededor del límite, si existe dicho límite :)

¿Fue útil?

Solución 3

Si defino la tabla como static - La carga del módulo fallará - Esto probablemente se deba al límite de 1.5 g mencionado en la respuesta por Andrew Aylett

Sin embargo, si hago dinámico vmalloc() Llamadas, pude obtener hasta 7680 MB en un host con 8 GB de memoria (hasta que el núcleo mató un proceso crucial y mi X ahorcado).

Entonces, para responder a mis preguntas:

  1. Sí, pero solo para datos que se compilan en static
  2. No lo parece.
  3. No hay necesidad de hacer eso.

Crédito adicional: solo haz vmalloc()

Esto solo funciona en los núcleos de Linux más nuevo de 2.6.10 - Antes de eso, el vmalloc() El límite fue de 64 MB.

Otros consejos

En cuanto a su primera pregunta: el límite en el módulo en sí es de 64 megabytes. El cargador del módulo rechazará cargar un módulo que exceda este tamaño. De kernel/módulo.c:

if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
        return ERR_PTR(-ENOMEM);

Esto es cierto tanto para 2.6.32 como para los núcleos más nuevos también, hasta 3.3.

Editar: en el núcleo versión 3.4, el límite de 64 MB fue removido. Ahora el límite real depende solo de la cantidad de memoria vmalloc() puede asignar.

Recuerde que la memoria del espacio del núcleo es diferente de la memoria del espacio de usuario: en Linux de 32 bits, el kernel tiene solo 1 GB de espacio de direcciones. Hay un registro más espacio de dirección de espacio para el núcleo en Linux de 64 bits, pero documentación del núcleo sugiere que solo 1536 MB está disponible para módulos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top