Linux módulo de desarrollo de pilotos comprensión Makefile &hola instancia del módulo del kernel para explicar

  
 

Para un módulo de unidad de disco, el siguiente Makefile en la constitución clásica: //
------------ --------------- Makefile ------- obj-m: = hello.o KERNELDIR: = /lib /modules /$ (shell uname -r) /construir PWD: = $ (pwd shell) módulos: $ (HAZ) -C $ ( KERNELDIR) M = $ (PWD) módulos # debe tenerse en cuenta que el modules_install frontal pestaña: $ (MAKE) -C $ (KERNELDIR) M = $ (PWD) modules_install # hay que señalar que la pestaña frontal

cada analizar individualmente la siguiente declaración:
obj-m: = hola.o

frase se pretende que tenga un módulo desde el nombre del módulo del archivo necesario hello.o construido, configurado para hello.ko
<. br> KERNELDIR: = /lib /modules /$ (shell uname -r) /construir
define en este documento es una variable KERNELDIR, y asignado a " /lib /modules /$ (shell uname - r) /construcción ".
Este valor se explica sólo una cosa, es decir, $ (shell uname -r):


Podemos tratar de entrar en el terminal en $: uname -r cuál sea el resultado, sin equivocada, este comando obtener la versión actual del kernel, como " 2.6.38.2 y ".
y luego ya veremos " /lib /modules " lo directorio de archivos:

$
: ls /lib /modules /

Resultados:


2.6.38.2 2.6.38-8-generic

modo " /lib /modules /$ (shell uname -r) /construcción " el significado es muy claro, es decir, el directorio actual código fuente del núcleo
PWD: = $ (shell PWD)
KERNELDIR han explicado, creo que esto no quiere decir, es conseguir que el directorio actual. En resumen en la cáscara, $ (shell xxx) xxx es equivalente a ejecutar comandos en el terminal.
$ (HAZ) -C $ (KERNELDIR) M = $ (PWD) módulos
Este es el módulo de traducción: en primer lugar, la opción -C para cambiar la ubicación del directorio especificado (es decir, fuente del núcleo directorio), que sostiene el makefile núcleo superior; m = tienen opción makefile para devolver al módulo de directorio de origen módulos configurados antes de la diana; entonces, modueles orientación módulo variable de set obj-m; anteriormente ejemplo, que establece esta variable se convirtió en hola.o.
(&Mdash; citado P29 ldd3)

ps

en páginas P29 ldd3, el Makefile mencionado, no es un ejemplo:
//Makefile sencillo obj-m: = hola.o

pero módulo de traducción, utilice el siguiente comando: $
: hacer -C ~ /kernel-2.6 m módulos = 'pwd'

en el que " ~ /kernel-2.6 " directorio de fuentes del núcleo, dependiendo de su ubicación y de cambiar, por lo que el comando correspondiente al entorno nativo es: $
: hacer /usr/src/linux-source-2.6 -C. 38 M = $ PWD módulos

resultados finales exactamente de la misma manera y el primero!

Ahora, vamos a comparar estos dos métodos conozca, de hecho, la única diferencia entre ellos no es el mismo que el directorio de origen, respectivamente, " /lib /modules /$ (shell uname -r) /construcción " y " /usr/src/linux-source-2.6.38/" pero cuando se ha compilado el kernel se sabe, que el código fuente está bajo el directorio usr normalmente nuestra propia descarga, descomprimir, y el directorio lib es en tiempo de compilación copiar automáticamente el pasado, tanto la estructura de archivos exactamente lo mismo, así que exactamente el mismo efecto no es sorprendente.
Hola, instancia módulo del núcleo

Cuando el aprendizaje de idiomas C comienza vamos a aprender un programa hola, mundo, creo que todos sentimos y simple, que escribí la siguiente repetición de programa, sentir es redundante:
C ++ código para # include < stdio.h >

  • int ()
    principal {
  • printf (y " hola, mundo /N "); Usa volver 0;
  • }

    pedirle a alguien que ponderar dos preguntas: ¿Por qué tenemos que escribir una función main ()? programa del núcleo principal de C lo necesita?

    Aquí #include < stdio.h > es permitirnos usar printf (), de hecho, son una función de la biblioteca de lenguaje C, que pueden ser utilizados en el núcleo en ella?

    Vamos a responder a estas dos preguntas, la aplicación de lenguaje C debe tener una función main (), porque es la entrada de la solicitud, de por qué esas entradas tienen que ser, sólo tenemos una respuesta: las disposiciones la obligatoria. aplicación de C ha especificado aplicación, tal como se especifica módulo del núcleo tiene un módulo del núcleo, por lo que escribir marco del módulo del kernel, recuerda que esto se especifica en él.

    En cuanto a la segunda pregunta es más importante: la aplicación puede llamar a las funciones de la biblioteca estándar del lenguaje C, y el núcleo será absolutamente imposible, si recuerda que dijimos fopen, es dependiente de la llamada al sistema open mientras que hay una llamada al sistema del kernel para exportar, a continuación, si podemos usar la biblioteca estándar en el programa básico, luego fue trasladado a la y " al final es un pollo y el huevo y " el ciclo.

    El siguiente programa es el marco de los módulos del kernel estándar de Linux (véase por favor, cuando está aprendiendo de los maestros es la forma de escribir el código).
    C ++ código para # include < Linux /module.h >

  • # include < Linux /init.h >
    # include < Linux /kernel.h > //uso printk, requiere incluir este archivo
  • MODULE_LICENSE (y " Dual BSD /GPL y ");
    MODULE_AUTHOR (y " stephanxu @ eetek y ");
  • module_description (y " el primer módulo del núcleo y ")
    hello_init __init static int (void)
  • {
    return 0;
  • }
    static void __exit hello_exit (void)
  • {}

  • module_init (hello_init);
    module_exit (hello_exit);




    este es un hola módulo del núcleo marco, si queremos lograr impresión hola, núcleo, sólo tenemos que modificar hello_init como: hello_init static int __init (void) {printk (y " hola, kernel /N "); return 0;} marco del módulo comprende las siguientes cuatro partes:

    (1) el tiempo de carga módulo module_init a realizar (función), y en module_init () Module_exit función especifica, el módulo se ejecuta cuando se desinstala (función), así como en module_exit (función) como se define en. Si se declara utilizando module_exit (), entonces el módulo no tendrá la función de desinstalación dinámica.

    (2) necesita definir module_init (mediante la función de limpieza () llama a la función de inicialización, y en module_exit). Sólo cuando la función de inicialización devuelve un valor no negativo (como en el núcleo, un valor negativo indica operación falla), los módulos del núcleo que se cargan correctamente, de lo contrario el módulo no se pudo cargar. La función de limpieza de tipo de retorno void. En circunstancias normales, cuando la función de inicialización del módulo se utiliza para cargar los recursos de aplicaciones, y la función de limpieza cuando el módulo se descarga para liberar recursos, algo similar en C ++ constructor y Deconstructor.

    (3) archivos de cabecera, para se refiere módulo del núcleo, es necesario el uso de < Linux /module.h > y < Linux /init.h >. Especial atención se requiere, se utiliza una etiqueta < > para incluir la cabecera, pero está claro que las dos cabezas son no el archivo es una función de los archivos de encabezado estándar, ya que, como se mencionó anteriormente, el módulo principal no puede hacer referencia a la biblioteca estándar función. Aquí $ cabeceras realidad se deriva de la trayectoria de la fuente del núcleo de Linux (KERNELSRC) /include.

    (4) de contenido representado por MODULE_XXX, que se describen en el módulo del núcleo actual, aunque no es necesario, pero en general, o pedirle que rellene algunos, especialmente los problemas de licencia módulo . Por supuesto, usted tiene la oportunidad de hacer un nombre por sí mismos, pero usted tiene la responsabilidad. Tiene una descripción más detallada del módulo será después de depurar errores es útil. Modinfo se puede hacer módulo de identificación más rápido, si es necesario, consulte la LDD (< < dispositivo Linux Drivers > >, fue referido más adelante como LDD) Para obtener más MODULE_XXX en una descripción de macro.

  • Copyright © Conocimiento de Windows All Rights Reserved