**** LKM per Solaris 8 ****




struct Dedica {

alla gran gnocca della barista sottocasa:

___o0o_(*)(*)_o0o___
IIIIIIIIIIIIIIIIIIII

};

So gia' quello che vi state chiedendo in questo preciso istante... come cacchio
mi e' venuta l'idea di scrivere LKM per Solaris ??? (Se non ve lo state chiedendo,
per favore, fatelo).Gia'. Perche' ? Be', fondamentalmente i motivi sono 2.
Il primo e' che su Solaris ci lavoro, secondo perche' in effetti questo OS
e' piuttosto ancora sconosciuto, se non in ambiti aziendali. Una ventata di
nuovo, ogni tanto, non fa male! Doveroso e' ringraziare il beb0s perche'
in fondo, senza saperlo e/o volerlo, l'idea degli LKM sotto Solaris me l'ha
lanciata lui... :)

Ma ciancio alle bande e andiamo dunque al subito.

Le funzioni per lo sviluppo degli LKM (non ditemi che non sapete ancora cosa sono...)
sotto Solaris sono sostanzialmente diverse da quelle dei kernel di Linux e *BSD.

Per iniziare scriveremo il nostro primo modulo che chiamero' MySun.
Cominciamo con la serie di include di cui abbiamo bisogno:

<-- MySun - Primo LKM per Solaris -->

#include <sys/ddi.h> /*librerie per device drivers */
#include <sys/sunddi.h> /*servono anche x i moduli */

#include <sys/modctl.h> /*libreria per gli LKM */


/*adesso "grabbiamo" la struct relativa al nostro tipo mi modulo */
extern struct mod_ops mod_miscops;

/* in Solaris i moduli possono essere di diverso tipo, il nostro e' misc, */
/* una sorta di modulo promiscuo, in quanto non e' un vero device driver */

static struct modlmisc modlmisc =
{
&mod_miscops,
"MySun - first LKM for SunOS", /* Questa stringa e' l'info del modulo */
/* poi vedremo dove comparira' */
};

/* Informiamo come dev'essere linkato il nostro modulo */
static struct modlinkage modlinkage =
{
MODREV_1,
(void *) &modlmisc,
NULL
};

/* _init e' la prima funzione ad essere eseguita */
/* cio' che contiene e' abbastanza ovvio (si spera !) */
int _init(void)
{
int i;
if ((i = mod_install(&modlinkage)) != 0)
cmn_err(CE_NOTE, "Inserimento modulo fallito!\n");
else
cmn_err(CE_NOTE, "Modulo inserito!");

return i;
}

/* _info e' la funzione che restituira' le informazioni riguardo */
/* il nostro bel moduletto. */
int _info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}

/* ...e se 2 non fa 3 questa funzione verra' chiamata nel momento in cui */
/* unloaderemo il modulo */
int _fini(void)
{
int i;

if ((i = mod_remove(&modlinkage)) != 0)
cmn_err(CE_NOTE, "Impossibile rimuovere il modulo!\n");
else
cmn_err(CE_NOTE, "Modulo rimosso");

return i;
}


<-- EOF -->

Eccoci qua! MySun e' completo, pronto per essere compilato. Sara' utile scriversi
un Makefile, in quanto le options passate al gcc sono lunghette..

<-- Makefile -->
CC=gcc
LD=ld
CFLAGS=-O2
COPTS=-g -D_KERNEL -DSVR4 -DSOL2 -DDEBUG

LIBCARCHIVE=/lib/libc.a
LIBCOBJECTS=memmove.o memcpy.o strstr.o

MODULES=MySun

MySun: MySun.o
$(LD) -o $@ -r MySun.o


MySun.o: MySun.c
$(CC) $(COPTS) $(CFLAGS) -c MySun.c

clean:
rm -rf $(MODULES)

<-- EOF -->

Bene, adesso lanciamo finalmente make!

ethera# make
gcc -g -D_KERNEL -DSVR4 -DSOL2 -DDEBUG -O2 -c MySun.c
ld -o MySun -r MySun.o
ethera#

La compilazione e' andata a buon fine. Adesso carichiamo il modulo:

ethera# modload MySun
ethera#

Ovviamente lo stdout del kernel non e' lo stesso in user-land, quindi se vogliamo
visualizzare eventuali messaggi dovremo leggere nel file adatto, in questo caso
syslogd "stora" i messaggi dal kernel in /var/adm/messages

ethera# tail /var/adm/messages
[...]
Jan 25 11:15:32 ethera MySun: [ID 344368 kern.notice] NOTICE: Modulo inserito!

Perfetto, tutto e' andato bene (senno' mica scrivevo l'articolo :P )
Adesso verifichiamo che il nostro modulo sia nella lista di tutti i moduli caricati
nel sistema:

ethera# modinfo
Id Loadaddr Size Info Rev Module Name
5 fe8ec000 389a 1 1 specfs (filesystem for specfs)
7 fe8f0c16 2334 1 1 TS (time sharing sched class)
[...]
133 fe99d095 e2c 21 1 ptem (pty hardware emulator)
134 fe98dc6f 1bc 22 1 redirmod (redirection module)
135 fe971d85 d58 23 1 bufmod (streams buffer mod)
136 feac383a 191 - 1 MySun (MySun - first LKM for SunOS)

Ehehe, c'e' ! Come vedete ci sono tutte le info: Id, indirizzo di memoria nel quale
risiede, dimensione, nome e descrizione, per il resto: man modinfo.

Inutile dire che questo modulo non fa assolutamente nulla, d'altronde, questo non e' che
l'inizio anche per il sottoscritto ma assicuro che il prossimo spacchera'.

Adesso unloadiamo il modulo:

ethera# modunload -i 136
ethera#

E leggiamo il log:
ethera# tail /var/adm/messages
[...]
Jan 25 12:46:43 ethera MySun: [ID 431183 kern.notice] NOTICE: Modulo rimosso

Tutto come da copione.

-- Considerazione acara --

Il modo piu' semplice per nascondere agli occhi dell'admin il nostro modulo e'
modificare la stringa contenuta in struct modlmisc, se infatti inseriamo due apici
senza nulla dentro ("" per intenderci) il modulo non apparira' con modinfo;
il compito di verificare lo lascio a voi.

Attenzione pero'. Gli Id dei moduli, in Solaris, sono sequenziali, quindi, se
l'admin carica un modulo e con modinfo legge:

135 fea0dffa 963 23 1 ptm (Master streams driver 'ptm')
137 fe99d095 e2c 21 1 admm (Admin module)

che fine ha fatto il modulo 136 ?? Se l'admin e' un tipo sgamato arrivera' da solo
alla conclusione...

...e con questo e' tutto!

by darko

darko@autistici.org



struct Riferimenti {

-man dei comandi utilizzati;
-Il sito della Sun (www.sun.com);
-Plasmoid/THC
-Solaris 8 (ISBN 0-7821-2816-5);

};

struct Saluti && Ringraziamenti {

-megabug per avermi dato una solida formazione sul C (puahahah!!!);
-il LOA hacklab di Milano e tutti coloro che lo frequentano (www.ecn.org/loa);
-beb0s per l'autismo di cui e' capace e per avermi inspirato in questo progetto;
-GiPOCO perche' e' mentalmente insano almeno quanto me;
-Il mitico Google, senza il quale saremmo tutti nel /dev/random piu' totale (www.google.com);

};

by darko


1