Está en la página 1de 11

Sistemas de Computación

Laboratorio Nº 4: “Módulos del Kernel”

Facultad de Ciencias Exactas, Físicas y


Naturales
Universidad Nacional de Córdoba

Preparado por:

● Bossa, Celina 43132207 Ing. Electrónica


● Montero, Felipe 95011233 Ing. en Computación
● Olocco, Laureano 40522648 Ing. en Computación

Profesor:

● Jorge, Javier

Soporte Técnico - 2023


Desafío #1 1
¿Qué es checkinstall y para qué sirve? 1
Desafío #2 1
¿Qué funciones tiene disponible un programa y un módulo? 1
Espacio de usuario o espacio del kernel 1
Espacio de datos 2
Drivers. Investigar contenido de /dev 2
Cargar Módulo 3
¿Qué diferencia existe entre un módulo y un programa ? 5
Firmar Módulo 7
Hacer un makefile que compile todos los componentes de la carpeta 10

Desafío #1
¿Qué es checkinstall y para qué sirve?

CheckInstall es un programa de computadora para Sistemas Operativos tipo Unix


que permite la instalación y desinstalación de software compilado desde el código
fuente para ser administrado por un sistema de gestión de paquetes. CheckInstall
crea un registro de los archivos instalados mediante el comando “make install” o
equivalente, luego crea un paquete de instalación binario estándar (.deb, .rpm, .tgz) y
lo instala en el sistema. Esto da la posibilidad de desinstalar el software instalado con
Checkinstall utilizando un sistema de gestión de paquetes como “apt” o “dnf”.

Desafío #2
¿Qué funciones tiene disponible un programa y un módulo?

Un programa normalmente comienza con la función main(), ejecuta una serie de


instrucciones y finaliza una vez terminada la ejecución de estas. Por otro lado, los
módulos siempre comienzan con con init_module o la función que se especifique con
la llamada a module_init y finalizan con la llamada a cleanup_module o con la
función que se especifique con la llamada a module_exit. Fundamentalmente la
diferencia radica en que los programas utilizan funciones que no son definidas todo
el tiempo mientras que en los módulos los símbolos se resuelven al correr insmod o
modprobe. La definición de estos símbolos proceden del mismo Kernel.

Espacio de usuario o espacio del kernel

La diferencia clave entre el espacio de usuario y el espacio de kernel radica en los


privilegios y el nivel de acceso que tienen. El espacio de usuario es donde se

1
ejecutan las aplicaciones de usuario con restricciones de acceso, mientras que el
espacio de kernel es donde se ejecuta el núcleo del sistema operativo con acceso
total a los recursos del sistema. Esta separación ayuda a garantizar la estabilidad y
seguridad del sistema operativo, ya que los programas de usuario no pueden
interferir directamente con el funcionamiento del núcleo o acceder a recursos críticos
del sistema.

Espacio de datos

Cuando un proceso es llamado, el Kernel debe reservar una porción de la


memoría física y asignarla al proceso para ejecutar código, variables, stack, pila,
entre otros. Es importante notar que el espacio de memoria de dos procesos no se
solapan, por lo tanto, cada proceso que quiera acceder a una dirección de memoria
accede en realidad a una dirección de memoria física diferente.
El kernel también tiene su propio espacio de memoria. Dado que un módulo es un
código que se puede insertar y eliminar dinámicamente en el kernel, comparte el
espacio de código del kernel en lugar de tener el suyo propio.

Drivers. Investigar contenido de /dev

Los drivers son una clase particular de un módulo. Ya que en los sistemas unix los
dispositivos se mapean como archivos, a estos los encontraremos en el directorio
/dev. Este directorio contiene archivos de dispositivo para todos los dispositivos de
hardware conectados. Estos archivos se utilizan como una interfaz entre los
dispositivos y los procesos que los utilizan además de proporcionar funcionalidad
para el hardware específico.

2
Cargar Módulo

A continuación se muestran los pasos realizados para cargar el módulo


“mimodulo.ko” en el Kernel.

Figura N° 1. Clonado de repositorio de trabajo, luego de hacer fork a repositorio remoto.

Figura N° 2. Compilación de “mimodulo.ko”, con herramienta make.

Figura N° 3. Carga de “mimodulo.ko”, con herramienta insmod.

Figura N° 4. Mensajes del Kernel observados con dmesg, luego de cargar “mimodulo.ko”.

En la Figura N° 4 se puede observar que luego de cargar el módulo de Kernel


“mimodulo.ko” se loguea el mensaje “Modulo cargado en el kernel” en el buffer de
logueo del kernel. Mediante observación del código fuente del módulo, “mimodulo.c”,
se verifica que el mensaje es generado con la función printk, ejecutada dentro de la
función modulo_lin_init.

Figura N° 5. Función modulo_lin_init dentro de “mimodulo.c”.

3
Figura N° 6. Confirmación de la carga de “mimodulo” con lsmod.

Figura N° 7. Confirmación de la carga de “mimodulo” mediante inspección de /proc/modules/.

En las Figuras N°6 y N°7 se observa que el módulo fue cargado correctamente en
el Kernel. En la Figura N° 6 se muestra el uso de la herramienta lsmod, que lista los
módulos cargados de forma dinámica, mediante el uso de las herramientas insmod o
modprobe. En la Figura N° 7 se inspecciona /proc/modules para localizar el módulo
cargado.

Figura N° 8. remoción de “mimodulo” utilizando rmmod.

Figura N° 9. Mensaje observado con dmesg, luego de remover “mimodulo”.

Al remover el módulo se observa el mensaje de Kernel “Modulo descargado del


kernel”. Nuevamente, mediante inspección del código fuente del módulo,
“mimodulo.c”, se verifica que el mensaje es generado con la función printk, ejecutada
dentro de la función modulo_lin_clean.

Figura N° 10. Función modulo_lin_clean dentro de “mimodulo.c”.

Figura N° 11. Confirmación de remover “mimodulo”.

En las Figura N° 11 se muestra que no es posible localizar el módulo con la


herramienta lsmod o mediante inspección en /proc/modules/ luego de ser removido
con rmmod.

Finalmente, se muestra el uso de la herramienta modinfo para obtener información


de un módulo de Kernel. Se compara la salida de la herramienta para el módulo
“mimodulo” y para “des_generic”.

Figura N° 12. Inspección de “mimodulo” con modinfo.

4
Figura N° 13. Inspección de “des_generic” con modinfo.

A partir de las Figuras N° 12 y N° 13 se puede observar que la diferencia principal


en la información aportada por modinfo para los módulos analizados radica en que el
módulo des_generic cuenta con firma digital, mostrada en el campo signature.

¿Qué diferencia existe entre un módulo y un programa ?

Las principales diferencias entre un módulo y un programa son:


● Un programa es una entidad ejecutable por sí misma y puede ser iniciada
directamente para su ejecución mientras que un módulo no se ejecuta
directamente, sino que es utilizado por otro programa o módulo que lo
importa.
● Un programa tiene un punto de entrada definido, que es donde comienza la
ejecución (main) mientras que un módulo no tiene un punto de entrada
definido sino que proporciona funciones, clases y variables que pueden ser
utilizadas por otros programas o módulos.
● Un programa tiene su propio alcance global, donde las variables y funciones
definidas pueden ser accedidas desde cualquier parte del programa mientras
que un módulo tiene su propio ámbito y espacio de nombres separado. Esto

5
significa que las variables, funciones y clases definidas en un módulo no
están automáticamente disponibles en otros módulos o programas, a menos
que se importen explícitamente.
● Los programas suelen tener objetivos específicos, como realizar una tarea
determinada, resolver un problema o proporcionar una interfaz de usuario
mientras que los módulos tienen como objetivo proporcionar funcionalidades
específicas que pueden ser utilizadas por otros programas o módulos.
● Los programas son entidades independientes y autónomas que se ejecutan
por sí mismas mientras que los módulos se crean con el propósito de ser
reutilizados y pueden ser importados y utilizados en diferentes programas o
módulos para aprovechar las funciones y características que proporcionan.
● Los programas suelen ser archivos únicos que contienen todo el código
necesario para realizar una tarea específica mientras que los módulos se
crean para modularizar y organizar el código en unidades más pequeñas y
especializadas.

6
Firmar Módulo

A continuación se muestra el procedimiento de firmar y cargar el módulo


“mimodulo” en Fedora 37, con secure boot activado.

Figura N° 14. Intento de cargar módulo no firmado.

En la Figura N° 14 se puede observar que insmod genera un error al intentar


cargar el módulo mimodulo.ko al no poseer firma digital.
Para proceder a firmar el módulo, en primer lugar, se generaron un par de llaves
pública y privada con la herramienta openssl. Primero se generó un archivo de
configuración con parámetros para la generación de pares de claves y luego se
ejecutó openssl leyendo los parámetros del archivo de configuración. Se creó el
script keygen.sh con el comando openssl y los argumentos necesarios para la
generación de las llaves pública y privada.

Figura N° 15. Contenido del archivo configuration_file.config.

Figura N° 16. Contenido del script keygen.sh.

7
Figura N° 17. Ejecución del script keygen.sh y creación de llaves.

En la Figura N° 17 se muestra que al ejecutar la herramienta openssl se crean las


llaves pública y privada, my_signing_key.der y my_signing_key.priv.

Teniendo las llaves pública y privada se utilizó la herramienta mokutil para agregar
las llaves a la lista de llave del propietario de la máquina (MOK) y al llavero del
sistema (.builtin_trusted_keys).

Figura N° 18. Ejecución de mokutil para agregar las llaves al llavero del sistema.

8
Figura N° 19. Inscripción de llaves desde la consola UEFI, con aplicación MokManager.efi.

Finalmente, se firmó el módulo con la llave privada, utilizando la herramienta


sign-file.

Figura N° 20. Firma del módulo con herramienta sign-file.

Una vez firmado el módulo, es posible cargarlo utilizando insmod o modprobe. A


continuación se muestra la carga del módulo.

Figura N° 21. Carga del módulo “mimodulo” firmado.

Figura N° 22. Mensaje de “mimodulo” visualizado con dmesg.

En la Figura N° 21 se muestra el uso de lsmod para corroborar que el módulo se


cargó correctamente. En la Figura N° 22 se puede observar el mensaje de Kernel de
carga del módulo, con la herramienta dmesg.

9
Hacer un makefile que compile todos los componentes de la
carpeta

A continuación se muestra el contenido del archivo Makefile que compila todos los
componentes del repositorio

all:
@echo "Compiling module..."
@cd module && $(MAKE) -f Makefile
@echo "Compiling syscalls..."
@cd ../part1/syscalls && $(CC) -c copiar_archivo.c -o
copiar_archivo.o
@cd ../part1/syscalls && $(CC) -c ejemplo_printf.c -o
ejemplo_printf.o

10

También podría gustarte