You are on page 1of 44

kernel II - System Calls y Modulos

Explicaci
on de practica 3

Sistemas Operativos
Facultad de Inform
atica
Universidad Nacional de La Plata

2016

Agenda

1 Kernel

2 System Calls

3 M
odulos

Agenda

1 Kernel

2 System Calls

3 M
odulos

Kernel de GNU Linux

2,4 millones de lineas de c


odigo(y contando...)
El 70 % del c
odigo son drivers
Windows: mas del doble de lineas!
Tasa de errores en drivers con respecto al Kernel: 7 veces mas
Fuente:http://pdos.csail.mit.edu/6.097/readings/osbugs.pdf
Comparaci
on con la aerona
utica:
Aislamiento de fallas
Un problema en el toilet no afecta al sistema de navegaci
on!

Kernel Monoltico - Mismo proceso

Todos los componentes del kernel linkeados en un mismo

binario en memoria.
Memoria Compartida(sincronizaci
on!)
Scheduler, Drivers, Memory Manager,etc en un mismo proceso

Kernel Monoltico - Operating System Crash


Que sucede si hay un error en un driver?
Windows: BSD(blue screen of death).
Unix: Kernel Panic.
Un u
nico gran componente linkeado en un mismo espacio de

direcciones implica un m
odulo muy grande y complejo.
La raz
on de tener un u
nico gran componente linkeado en un

mismo espacio de direcciones se debe a cuestiones de


performance por limitaciones de hardware tomadas hace
mucho tiempo.
Hoy en dia la decisi
on seria la misma?

Microkernel - Procesos de usuario

Componentes del kernel en distintos procesos de USUARIO


Kernel minimalista(comunicaci
on con el hard e IPC)
IPC (Computaci
on distribuida!)
Scheduler, Drivers, Memory Manager en distintos procesos de
Usuario
IPC es parte del Kernel(muchos cambios de modo)

Microkernel
Pros
Facilidad para desarrollar servicios del SO.
Los bugs existen y existir
an siempre, entonces deben ser

aislados.
Kernel muy peque
no, entonces mas facil de entender,

actualizar y optimizar.
Contras
Baja performance
La computaci
on distribuida es inheremente mas compleja que
la computaci
on por memoria compartida
No fue adoptado masivamente por la industria(ej. Minix)

Tanembaum Torvalds debate

vs
http://en.wikipedia.org/wiki/Tanenbaum

Agenda

1 Kernel

2 System Calls

3 M
odulos

API del Sistema Operativo


Los SOs proveen un conjunto de interfaces mediante las

cuales un proceso que corre en espacio de usuario accede a un


conjunto de funciones comunes

En UNIX el API principal que provee estos servicios es libc:


Es el API principal del SO
Provee las libreras estandar de C
Es una Interface entre aplicaciones de usuario y las System
Calls(System Call Wrappers).

POSIX APIs
La funcionalidad anterior est
a definida por el estandar POSIX
Su pr
oposito es proveer una interfaz com
un para lograr

portabilidad
En el caso de las System Calls, el desarrollador generalmente

interact
ua con el API y NO directamente con el Kernel
En UNIX por lo general cada funci
on del API se corresponde

con una System Call

System Calls - Repaso

Son llamados al kernel para ejecutar una funci


on especfica

que controla un dispositivo o ejecuta una instruccion


privilegiada
Su pr
oposito es proveer una interfaz com
un para lograr

portabilidad
Su funcionalidad la ejecuta el Kernel
Recordar
Cambio de Modo
Como se pasa de modo usuario a modo Kernel?

Invocando System Calls

Utilizando los wrappers de glibc


int rc = chmod( /etc/passwd , 0444);
Invocaci
on explcita utilizando la System Call syscall provista

por glibc
Definida en la libreria unistd.h
long int syscall (long int sysno, ...)
Ejemplo utilizando syscall:
rc = syscall(SYS chmod, /etc/passwd,
0444);

Ejemplo
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <unistd.h>
#define SYS_gettimeofday 78
void main(void){
struct timeval tv;
/* usando el wrapper de glibc */
gettimeofday(&tv, NULL);
/* Invocaci
on expl
cita del system call */
syscall(SYS_gettimeofday, &tv, NULL);
}

Interrupciones y System Calls


La manera en que una system call es llevada a cabo

dependera del procesador.


Los procesadores x86 se basan en el

mecanismo de interrupciones.
Interrupci
on enmascarable int 0x80 en Linux.
Se usa el vector 0x80 para transferir el
control al kernel. Este vector de
interrupci
on esta inicializado durante el
startup del sistema.
Una librera de espacio de usuario(libc) carga el ndice de la

system call y sus argumentos, la interrupci


on enmascarable
por software 0x80 es invocada, la cual resulta en el cambio de
modo.
A trav
es de la estructura sys call table y el registro eax como
ndice se determina que handler function invocar.

System Calls e Interrupciones


Consideremos el siguiente caso:
#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#define sys_getpid 20
int main(void) {
long ID = syscall(SYS_getpid);
printf ("El pId del proceso es:\n", ID);
}

System Calls e Interrupciones(cont.)


El compilador generara:
_setuid:
subl $4, %exp
pushl %ebx
movzwl 12( %esp), %eax
movl %eax,4( %esp)
movl $20, %eax
movl 4( %esp), %ebx
int $0x80
movl %eax, %edx
testl %edx, %edx
jge L2
negl %edx
movl %edx,_errno
movl $-1, %eax
popl %ebx
addl $4, %esp

System Calls en GNU Linux


Debemos declarar nuestra syscall por un n
umero u
nico(syscall

number).
Agregamos una entrada a la syscall table.
Debemos considerar el sys call number.
Ver que el codigo fuente organizado por arquitectura.
Respetar las convenciones del Kernel(ej. prefijo sys ).

/usr/src/linux-3.8/arch/x86/entry/syscalls/syscall 32.tbl
373
374
375
376
377

i386
i386
i386
i386
i386

shutdown sys shutdown


userfaultfd sys userfaultfd
membarrier sys membarrier
mlock2 sys mlock2
newcall sys newcall

System Calls en GNU Linux(Cont.)


Debemos definir el prototipo de nuestra system call
Los par
ametros a system calls deben ser realizados por medio

del stack
Informamos de esto al compilador mediante la macro
asmlinkage
asmlinkage instruye al compilador a pasar par
ametros por stack

y no por ejemplo en registros

/usr/src/linux-3.8/include/linux/syscalls.h
asmlinkage long sys newcall(int i);

System Calls en GNU Linux(Cont..)


Debemos nuestra syscall en alg
un punto del arbol de fuentes.
Podemos utilizar alg
un archivo existente.
Podemos incluir un nuevo archivo y su correspondiente

Makefile.
Ver apuntes adjuntos

En algun archivo ya incluido en los fuentes del Kernel...


asmlinkage int sys newcall(int a)
printk(calling newcall... );
return a+1;
printk?, porque no printf?

System Calls en GNU Linux(Cont...)

Recompilar el Kernel!
Idem Pr
actica 2

Invocando explcitamente nuestra System Call

#include <linux/unistd.h>
#include <stdio.h>
#define sys_newcall 377
int main(void) {
int i = syscall(sys_newcall,1);
printf ("El resultado es:\n", i);
}

Strace
Reporta las system calls que realiza cualquier programa
man strace
Opci
on u
til -f (tiene en cuenta procesos hijos)

strace a.out (hola mundo)


execve(./a.out, [./a.out], [/* 62 vars */]) = 0
brk(0) = 0x1295000
access(/etc/ld.so.nohwcap, F OK) = -1 ENOENT (No such file
or directory)
mmap(NULL, 8192, PROT READPROT WRITE,
MAP PRIVATEMAP ANONYMOUS, -1, 0) = 0x7f3b70b43000
access(/etc/ld.so.preload, R OK) = -1 ENOENT (No such file or
directory)

DESAFIO

Realizar un parche que contenga los cambios asociados a la

siguiente system call:


Simplemente debe imprimir el texto Hello world a trav
es de

la funci
on printk
Se debe hacer sobre la la 4.4.6

Tips:
Utilizar explicaci
on y practica para guiarse
http://lxr.free-electrons.com/

DESAFIO - Implementacion
D
onde incluir la implementaci
on?:
Dos opciones:
Incluir el c
odigo en un fichero existente
Agregar un nuevo fichero i modificar Makefile existente

Crearemos un nuevo fichero .c bajo el directorio

hsourcei/kernel
#i n c l u d e < l i n u x / s y s c a l l s . h> / * For SYSCALL DEFINEi ( ) * /
#i n c l u d e < l i n u x / k e r n e l . h>
SYSCALL DEFINE0 ( m y s y s c a l l )
{
p r i n t k (KERN DEBUG H e l l o w o r l d \n ) ;
return 0;
}

DESAFIO - Modificar Makefile

#
# Makefile f o r the l i n u x k e r n e l .
#
o b j y = . . .
a s y n c . o r a n g e . o g r o u p s . o smpboot . o m y s y s c a l l . o
...

DESAFIO - Test
#i n c l u d e
#i n c l u d e
#i n c l u d e
#i n c l u d e

< l i n u x / e r r n o . h>
<s y s / s y s c a l l . h>
< l i n u x / u n i s t d . h>
< s t d i o . h>

#d e f i n e

NR MYSYSCALL nums y s c a l l

i n t main ( ) {
p r i n t f ( I n v o c a n d o s y s t e m c a l l \n ) ;
r e t u r n s y s c a l l ( NR MYSYSCALL ) ;
}

$ g c c m y s y s c a l l . c o m y s y s c a l l
$ ./ mysyscall

DESAFIO - Parche

## C r e a r p a r c h e
$ d i f f urpN l i n u x 4 . 4 . 6 l i n u x 4.4.6 m o d i f i c a d o > patch
4.4.6 s o 2 0 1 6

No olvidar ejecutar!:
$ make c l e a n
$ make m r p r o p e r

Agenda

1 Kernel

2 System Calls

3 M
odulos

Que son los Modulos del Kernel?

Pedazos de c
odigo que pueden ser cargados y descargados

bajo demanda
Extienden la funcionalidad del kernel
Sin ellos el kernel sera 100 % monoltico
Monoltico hibrido
No recompilar ni rebootear el kernel

Comandos relacionados
lsmod
Lista los m
odulos cargados (es equivalente a cat
/proc/modules)
rmmod
Descarga uno o m
as m
odulos
modinfo
Muestra informaci
on sobre el m
odulo
insmod
Trata de cargar el m
odulo especificado
depmod
Permite calcular las dependencias de un m
odulo
depmod -a escribe las dependencias en el archivo
/lib/modules/version/modules.emp
modprobe
Emplea la informaci
on generada por depmod e informacion de
/etc/modules.conf para cargar el m
odulo especificado.

Como creamos un modulo?


Debemos proveer dos funciones:
Inicializaci
on: Ejecutada cuando ejecutamos insmod.
Descarga: Ejecutada cuando ejecutamos rmmod.

#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void){
printk(KERN_INFO "Hello world 1.\n");
return 0;
}
void cleanup_module(void){
printk(KERN_INFO "Goodbye world 1.\n");
}

Como creamos un modulo?(cont.)


Tambi
en podemos indicarle otras funciones.
module init
module exit

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int hello_2_init(void){
printk(KERN_INFO "Hello, world 2\n");
return 0;}
static void hello_2_exit(void){
printk(KERN_INFO "Goodbye, world 2\n");}
module_init(hello_2_init);
module_exit(hello_2_exit);

Como compilamos un modulo?


Construimos el Makefile
o b j m += h e l l o . o
all :
make C / l i b / m o d u l e s / $ ( s h e l l uname r ) / b u i l d M=$ ( pwd )
modules
clean :
make C / l i b / m o d u l e s / $ ( s h e l l uname r ) / b u i l d M=$ ( pwd )
clean

Compilamos
$ make

Que son los Dispositivos?


Entendemos por dispositivo a cualquier dispositivo de hard:

discos, memoria, mouse, etc


Cada operaci
on sobre un dispositivo es llevada por codigo

especfico para el dispositivo


Este c
odigo se denomina driver y se implementa como un

modulo
Cada dispositivo de hardware es un archivo (abstracci
on)
Ejemplo: /dev/hda
En realidad no es un archivo.
Si leemos/escribimos desde
el lo hacemos sobre datos crudos
del disco (bulk data).
Accedemos a estos archivos mediante operaciones b
asicas

(espacio del kernel).


read, write: escribir y recuperar bulk data
ioctl: configurar el dispositivo

Que son los Dispositivos? (Cont.)

Podemos clasificar el hard en varios tipos.


Dispositivos de acceso aleatorio(ej. discos).
Dispositivos seriales(ej. Mouse, sonido,etc).
Acorde a esto los drivers se clasifican en:
Drivers de bloques: son un grupo de bloques de datos
persistentes. Leemos y escribimos de a bloques, generalmente
de 1024 bytes.
Drivers de car
acter: Se accede de a 1 byte a la vez y 1 byte
s
olo puede ser ledo por u
nica vez.
Drivers de red: tarjetas ethernet, WIFI, etc.

Dispositivos en UNIX
Major y Minor device number.
Los dispositivos se dividen en n
umeros llamados major device
number. Ej: los discos SCSI tienen el major number 8.
Cada dispositivo tiene su minor device number. Ejemplo:
/dev/sda major number 8 y minor number 0
Con el major y el minor number el kernel identifica un

dispositivo.
kernel code/linux/Documentation/devices.txt
# l s l / dev / hda [1 3]
brwrw 1 r o o t d i s k 3 , 1 Abr 9 1 5 : 2 4 / dev / hda1
brwrw 1 r o o t d i s k 3 , 2 Abr 9 1 5 : 2 4 / dev / hda2
brwrw 1 r o o t d i s k 3 , 3 Abr 9 1 5 : 2 4 / dev / hda3

Archivos de dispositivos en UNIX

Representaci
on de los dispositivos(device files)
Por convenci
on estan en el /dev
Se crean mediante el comando mknod.
mknod[ m<mode >] f i l e [ b | c ] m a j o r

minor

b o c: seg
un se trate de dispositivos de caracter o de bloque.
El minor y el major number lo obtenemos de

kernel code/linux/Documentation/devices.txt

Dispositivos en UNIX

Necesitamos decirle al kernel:


Que hacer cuando se escribe al device file.
Que hacer cuando se lee desde el device file..
Todo esto lo hacemos en un m
odulo.
La struct file operations:
Sirve para decirle al kernel como leer y/o escribir al dispositivo.
Cada variable posee un puntero a las funciones que
implementan las operaciones sobre el dispositivo.

Como creamos un driver?


Mediante la struct file operations especifico que funciones

leen/escriben al dispositivo.
struct file_operations my_driver_fops = {
read: myDriver_read,
write: myDriver_write,
open: myDriver_open,
release: mydriver_release};
En la funci
on module init registro mi driver.

register_chrdev(major_number, "myDriver", &


my_driver_fops);
En la funci
on module exit desregistro mi driver.

unregister_chrdev(major_number, "myDriver");

Como creamos un driver?(Cont..)


Operaciones sobre el dispositivo
Escritura del archivo de dispositivo (Ej. echo hi))
/dev/myDeviceFile)

ssize_t myDriver_write(struct file *filp, char


*buf,size_t count, loff_t *f_pos);
Lectura del archivo de dispositivo (Ej. cat /dev/myDeviceFile)

ssize_t myDriver_read(struct file *filp, char


*buf,size_t count, loff_t *f_pos)

Como creamos un driver?(Cont...)

Par
ametros de las funciones funciones:
Struct file: Estructura del kernel que representa un archivo
abierto.
char *buf: El dato a ledo o a escribir desde/hacia el
dispositivo(espacio de usuario)
size t count: La longitud de buf.
loff t *f pos count: La posici
on manipulada

Preguntas?

You might also like