una - Portar el código de espacio de usuario al espacio del kernel
tipos de nucleo (2)
Tengo un gran sistema escrito principalmente en C que se estaba ejecutando en espacio de usuario hasta ahora. Ahora necesito compilar el código como un módulo kernel. Para eso, afaik, al menos debería reescribir el código y reemplazar funciones como malloc
, calloc
, free
, printf
con sus equivalentes de kernel, porque esas son solo funciones de espacio de usuario. El problema es, sin embargo, que no tengo el código fuente para algunas bibliotecas personalizadas que se usan en el sistema, y esas bibliotecas llaman malloc
etc. dentro de sus funciones. Entonces, básicamente, podría necesitar volver a implementar toda la biblioteca.
Ahora la pregunta: ¿será realmente un truco sucio si yo escribiera mi propia implementación de malloc
como envoltorio de kmalloc
, algo como esto?
void *malloc(size_t size) {
return kmalloc(size, GFP_USER);
}
A continuación, vincule esta implementación al código del sistema, que eliminará todo el símbolo Desconocido en los errores del módulo .
En realidad, pensé que este sería un problema común y alguien ya habría escrito un envoltorio de kmalloc, pero he estado buscando en Google por un par de días y no encontré nada útil.
EDITAR: La razón para hacer esto es que el sistema del que estoy hablando es una aplicación en tiempo real que se ejecuta en el sistema operativo VxWorks en tiempo real y ahora queremos portarlo para usarlo en Linux RTAI, donde las aplicaciones se ejecutan principalmente en el kernel. Pero creo que también existe la posibilidad de tener espacio de usuario en tiempo real, entonces, probablemente debería hacer lo que Mike sugirió y separar el código en partes del kernel y del espacio de usuario y comunicarse entre ellos con la memoria compartida.
Al tratar de hacer que mi código RTAI compilable en los espacios tanto del usuario como del kernel (además de trabajar con POSIX), he desarrollado URT, que básicamente hace lo que me pides. Es un nivel de abstracción ligero sobre los sistemas en tiempo real (e incluso sobre las inconsistentes funciones de espacio-usuario frente a las funciones RTAI del kernel-space).
Nunca he visto esto hecho antes. Tuve que hacer algo similar en un trabajo anterior (en nuestros teléfonos, por razones de ahorro de energía, tuvimos que transferir una porción del código del espacio de usuario del kernel) pero así fue como lo hice ... Tomé una parte del código y lo movió, y una pequeña porción en eso.
Cuando lo hice, cambié las llamadas de espacio de usuario a las llamadas al kernel debido a una serie de motivos, dos primarios:
Era menos confuso de esa manera (otros que miraban el código no tenían que preguntarse por qué estaba llamando "malloc" desde el kernel)
malloc
ykmalloc
no funcionan exactamente igual. Lo que quiero decir con eso es2a.
kmalloc
toma un parámetro deflags
, en su ejemplo anterior lo codificó. ¿Qué pasa si luego decides que quieres cambiarlo en algunos lugares y no en otros? (suponiendo que tienes varios lugares diferentes donde obtienes memoria dinámica).2b.
kmalloc
no te da memoria de la misma manera quemalloc
.malloc()
le dará la cantidad de bytes quesize_t size
comosize_t size
.kmalloc()
por otro lado, está en el núcleo y, por lo tanto, se ocupa de la memoria física del sistema, que está disponible solo en fragmentos de tamaño de página; por lo tanto, cuando llame akmalloc()
obtendrá solo ciertas matrices predefinidas de bytes de tamaño fijo. si no está enterado de esto, puede pedir algo más de un fragmento en particular y así obtener mucha más memoria de la que necesita ... un puerto directo de su código no lo protegerá de eso.2c. Los archivos de encabezado tienen que cambiar también. Obviamente, no puede incluir
<stdlib.h>
en el kernel, así que simplemente porque "completó" la llamada malloc, todavía tiene que reemplazar los archivos de encabezado.
ejemplo rápido de mi punto en 2b arriba:
void * stuff;
stuff = kmalloc(1,GFP_KERNEL);
printk("I got: %zu bytes of memory/n", ksize(stuff));
kfree(stuff);
Para mostrar la cantidad real de memoria asignada:
[90144.702588] I got: 32 bytes of memory
de todos modos ... técnicamente, cómo lo describes, debería funcionar bien. Ambos toman size_t
y devuelven un void *
por lo que debería funcionar; pero tenga en cuenta que cuanto más código kmalloc()
en el núcleo, menos deterministas serán las cosas, y que malloc()
<=> kmalloc()
no es tan 1: 1 como parece.