Creem una carpeta de treball a la home i hi entrem:
$ cd $ mkdir linux_kernel $ cd linux_kernel
Descarreguem uns fitxer per a treballar-hi:
Un kernel de Linux:
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.20.1.tar.bz2
Un fitxer img amb un sistema de fitxers:
$ wget http://www.ac.upc.edu/video/videos/image.img
I uns fitxers de treball:
$ wget http://www.ac.upc.edu/video/videos/base.zip
Descomprimim l'últim fitxer:
$ unzip base.zip
Descomprimim el kernel de Linux:
$ tar jxvf linux-2.6.20.1.tar.bz2
Entrem a la carpeta descomprimida:
$ cd linux-2.6.20.1/
Ara cal configurar el kernel. Podeu fer-ho vosaltres mateixos o utilitzar el fitxer del .config que proporciona el fitxer base.zip:
$ cp ../.config .
Ara executem:
$ make
Aquesta comanda compila el kernel i genera la versió binaria del mateix. El resultat el trobeu a:
arch/i386/boot/bzImage
El procés pot ser llarg...
Ara instal·lem el qemu (emulador de maquinari)
$ sudo apt-get install qemu
Si consulteu el fitxer boot que us ha proporcionar el fitxer base:
$ cat ../boot.sh #!/bin/bash if which qemu then qemu $* -boot c -kernel linux-2.6.20.1/arch/i386/boot/bzImage -hda ./image.img -append "root=/dev/hda clock=pit" else echo No he trobat executable qemu / No he encontrado ejecutable qemu echo Està instal.lat? / ¿Está instalado? echo Està actualitzada la variable PATH? / ¿Está actualizada la variable PATH? fi
Veureu que ja està preparat per executar qemu i el kernel que hem compilat amb el sistema de fitxers (fitxer img) proporcionat.
Executem-lo:
$ cd .. $ ./boot.sh
La instal·lem
$ sudo apt-get install cscope
Anema a la carpeta amb el codi font del kernel:
$ cd linux-2.6.20.1/
Copiem a aquesta carpeta el fitxer cscope.files
$ cp ../cscope.files .
Aquest fitxer és una llista amb els fitxers que indexarà cscope. Aquest índex ens permetrà fer cerques més ràpidament en aquests fitxers. Executem cscope:
$ cscope -k
Busqueu per exemple:
task_struct
a l'opció:
Find this global definition:
Trobarà 15 opcions. Escolliu una (amb les fletxes) i la seleccioneu amb Enter. Us porta directament a la línia de codi. Obrirà l'editor per defecte que és el vi, el podeu modificar canviant la variable d'entorn EDITOR:
$ export EDITOR=joe
Per tornar a fer una cerca cal prémer Tabulador.
Per sortir de cscope cal prémer:
Ctrl+d
Cal crear una carpeta de treball
$ cd $ mkdir modul; cd modul
En aquesta carpeta descarregueu el fitxer base2.zip utilitzant la eina wget:
$ wget http://acacha.dyndns.org/~sergi/altres/base2.zip
I el descomprimiu utilitzant
$ unzip base2.zip
També necessitem el kernel de Linux:
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.20.1.tar.bz2
El Descomprimim amb:
$ tar jxvf linux-2.6.20.1.tar.bz2
Ara cal copiar el fitxer i386_ksyms.c:
$ cp i386_ksyms.c linux-2.6.20.1/arch/i386/kernel/i386_ksyms.c
I tornar a compilar el kernel amb:
$ cd linux-2.6.20.1/ $ make
Després d'una estona el tindrem compilat. L'objectiu d'aquesta compilació és que els mòduls puguin utilitzar els símbols sys_call_table i sys_ni_syscall.
Ara anem a crear una crida de sistema. Utilitzarem el fitxer:
moduls/novacrida/novacrida.c
Que té el següent contingut:
/* * New system call * * Copyright (C) 2007 Enric Morancho * */ #include <linux/module.h> #include <linux/syscalls.h> #include <linux/thread_info.h> MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("New system call"); MODULE_AUTHOR("Enric Morancho"); extern unsigned sys_call_table[]; asmlinkage long sys_newsyscall(void) { printk("Hello world\n"); return(29); } static int __init newsyscall_init(void) { } static void __exit newsyscall_exit(void) { }
Volem que el mòdul realitzi una sèrie de tasques durant la seva instal·lació (funció __init newsyscall_init):
El primer pas és buscar una entrada no utilitzada a la taula sys_call_table. Per fer això cal recórrer la taula sys_call_table que s'inicialitza al fitxer arch/i386/kernel/syscall table.S i buscar alguna entrada amb el valor sys_ni_syscall. Les entrades d’aquesta taula són de tipus unsigned i la taula té NR_syscalls entrades.
Un cop trobada una entrada lliure, mostrar utilitzant la funció printk l'índex corresponent a l’entrada trobada. Aquest índex serà l’identificador que s'associarà a la nova crida del sistema.
Ara cal substituir el contingut de l’entrada no utilitzada de la taula sys_call_table per la direcció de memòria d’una rutina (per exemple, sys nomnovacrida, implementada al mòdul) que ser que doni servei a la nova crida al sistema.
Recursos: