LINUX embarqué
Grands Principes de l’embarqué avec LINUX
Démarrage et Services
Auteur
Jean-François Casquet
Editeur : AZERTY Microsystem
2004 - 2017 © Tous droits réservés
copie interdite
[Link]/stage/
1 LINUX embarqué / Edition AZERTY Microsystem
Démarrage Système LINUX
Le BIOS donne l'entité de démarrage (boot device)
Sur le disque dur, le Boot secteur (MBR MasterBoot Record) possède le programme qui va charger le programme de démarrage (512 octets
seulement). C'est la partie GRUB qui la lire le fichier /boot/grub/[Link]
Chargement du système de fichier InitRamDisk (initrd)
ensuite le noyau monte le système de fichier racine (le "/"),
puis il initialise la console initiale (clavier écran du PC) en consultant le contenu des fichiers /etc/init
Ensuite, il lance la première tâche : "init" (processus n°1)
et qui va lancer les services (daemons)
Le programme init est à la fois la première tâche que le noyau Linux exécute lorsqu'on boote un ordinateur et la dernière tâche présente
avant l'arrêt de l'ordinateur.
2 LINUX embarqué / Edition AZERTY Microsystem
InitRD (sur INTEL)____________________________________________________________________________________________
Le principe est d’utiliser directement le fichier initrd pour y placer tout le nécessaire !
# copions d’abord notre Initrd pour le modifier
mkdir /INITRD ; cd /INITRD/
cp /boot/initrd-*.img ./[Link]
# décompressons l’initrd
gunzip -S .img [Link]
cpio -imdF initrd
rm initrd
# plaçons dans notre arborescence les commandes nécessaires au dépannage
cp /bin/* /sbin/* /INITRD/bin/
cp /lib/* /INITRD/lib/
# changeons le démarreur pour qu’il s’arrêt au bon moment
vim init
Modifications à apporter (pour ne pas charger le systeme réel) - et lancer un BASH local sans disque uniquement en Ramdrive
# setuproot
# loadpolicy
# echo Switching to new root and running init.
# switchroot
# echo Booting has failed.
# sleep -1
/bin/bash ……
# recréons l’Initrd
find ./ | cpio -H newc -o > /initrdDEBUG
gzip /initrdDEBUG
mv /[Link] /[Link]
3 LINUX embarqué / Edition AZERTY Microsystem
Kernel ____________________________________________________________________________________________________
Sous LINUX, les demandes systèmes sont faites à
MATERIELS des applications (ressources) qui demandent TOUT
Associe au noyau.
et libère
les zones toutes Le mode protégé du processeur empêche l'accès à
un processus de toucher au matériel.
les
x
mode protégé
LINUX Demande zones
Les pirates, les virus ou les administrateurs
de mémoire mémoires passent par les commandes du noyau pour
attribuées accéder aux fonctions - comme tout le monde.
Accès Direct : virus … aux
processus Sous Linux, la gestion de la mémoire est faite par
le noyaux lui-même. Si un programme s'arrête, sa
mémoire est libérée par le noyau - l'application
n'a pas besoin de faire le ménage (d'autant plus si
l'application est morte inopinément).
APPLICATIONS
zones mémoires
Les noyaux que l’on peut choisir (ou distribution) sont directement liés au matériel physique de la machine sous linux.
Par exemple, RaspBian permet de gérer le bus GPIO sans être obligé d’installer des drivers et solutions complexes.
4 LINUX embarqué / Edition AZERTY Microsystem
Runlevel___________________________________________________________________________________________________
Avant tout, Comment connaître mon INIT ?
runlevel ou who -r (ou sur Raspberry : 2 par défaut)
Fichier contenant le runlevel : /etc/init/[Link] (DEBIAN) ou /etc/inittab (REDHAT)
cd /etc/rc2.d/ ............................................................................. rc2.d car nous sommes en INIT 2
ln -s /etc/init.d/monservice S90monservice
C’est un dossier qui contient les liens vers les services à Starter ou à Killer .
Les noms des services est particulier, car il respecte une norme :
Premier caractère : S = Start K = Kill
Second : 00..99 ordre de lancement
La suite : le nom du service (ou n’import quoi puisque c’est un lien)
BOOT
KERNEL
init
RUNLEVEL
/etc/rc2.d/ <liens>
ATTENTION : le script de lancement du service (dans
/etc/init.d/script de lancement
/etc/init.d) doit être exécutable : chmod +x <lancement> start ou stop
<daemon> Lieu où se trouve
le “daemon”
Il est possible aussi de placer un fichier de configuration dans /etc/init/ mais il doit répondre à une norme particulière.
Sélectionner les services utiles ________________________________________________________________________________
Sélectionnons les fichiers utiles (services) dans le dossier /etc/rc2.d/
Enlevons les services inutiles et ajoutons les services utiles…
5 LINUX embarqué / Edition AZERTY Microsystem
Services et démarrages sous LINUX
Création d’un service à sémaphore ______________________________________________________________________________
Un service est un processus lancé par le système (au démarrage)… et doit fonctionner en tâche de fond.
Ici, créons un script qui attend la suppression d’un sémaphore /run/[Link]
cat > /BACKUP/[Link] << DOG
#!/bin/bash
[ -d /run ] || mkdir /run
touch /run/[Link]
while [ -f /run/[Link] ] ; do
echo -n "." ; sleep 1
done
DOG
Tant que /run/[Link] existe, le service affiche un « . » puis « . » puis « . » ...
Vérifions notre service à sémaphore _____________________________________________________________________________
Pour tester notre service, lançons-le … Mais attention, il NE SERA PAS lancé par le KERNEL (init de initr). Il sera lancé par un lanceur de
service. Donc, il peut être sans droit d’exécution
chmod 755 /BACKUP/[Link]
lançons-le pour vérifier :
./BACKUP/[Link]
Pour l’arrêter :
rm /run/[Link]
6 LINUX embarqué / Edition AZERTY Microsystem
Création du lanceur de service à sémaphore ______________________________________________________________________
Les lanceurs de services se trouvent dans /etc/init.d/ ….
cat > /etc/init.d/monservice << DOG
#!/bin/bash
case '$1' in
start)
. /BACKUP/[Link] &
;;
stop)
rm /run/[Link]
;;
restart)
rm /run/[Link]
sleep 2
. /BACKUP/[Link] &
;;
status)
[ -f /run/[Link] ] && echo "Service OK" || echo "Service HS"
*)
echo "Attention, synthaxe : monservice start ou stop ou status"
;;
esac
DOG
chmod 755 /etc/init.d/monservice
/etc/init.d/monservice start
7 LINUX embarqué / Edition AZERTY Microsystem
Création d’un service à PID ____________________________________________________________________________________
Un service est un processus lancé par le système (au démarrage)… et doit fonctionner en tâche de fond.
Ici, créons un script qui attend la suppression d’un sémaphore /run/[Link]
cat > /BACKUP/[Link] << DOG
#!/bin/bash
while true ; do
echo -n "." ; sleep 1
done
DOG
Le service affiche un « . » puis « . » puis « . » ...
Vérifions notre service à PID ___________________________________________________________________________________
Pour tester notre service, lançons-le … Mais attention, il NE SERA PAS lancé par le KERNEL (init de initr). Il sera lancé par un lanceur de
service. Donc, il peut être sans droit d’exécution
chmod 755 /BACKUP/[Link]
lançons-le pour vérifier :
./BACKUP/[Link]
Pour l’arrêter :
Kill %1
8 LINUX embarqué / Edition AZERTY Microsystem
Création du lanceur de service à PID_____________________________________________________________________________
Les lanceurs de services se trouvent dans /etc/init.d/ ….
cat > /etc/init.d/monservice2 << DOG
#!/bin/bash
[ -d /tmp ] || mkdir /tmp
touch /tmp/[Link]
case '$1' in
start)
[ -f "/proc/$(cat /tmp/[Link])/status" ] && (echo "service deja lancé" ; return 1)
./BACKUP/[Link] &
echo $! > /tmp/[Link] ;;
stop)
kill $(cat /tmp/[Link]) ;;
restart)
kill $(cat /tmp/[Link])
./BACKUP/[Link] &
echo $! > /tmp/[Link] ;;
status)
[ -f "/proc/$(cat /tmp/[Link])/status" ] && echo "service OK" || echo "service HS"
*) echo "Attention, synthaxe : monservice2 start ou stop ou status"
;;
esac
DOG
chmod 755 /etc/init.d/monservice2
/etc/init.d/monservice2 start
9 LINUX embarqué / Edition AZERTY Microsystem
Mise au boot________________________________________________________________________________________________
ln -s /etc/init.d/monservice2 /etc/rc2.d/S90monservice2
ou
/etc/[Link]
Gérer les Down des services ___________________________________________________________________________________
Voici un script qui détecte un service arrêté
while true ; do
for i in atd sshd monservice2
do
[ -f "/proc/$(cat /run/$[Link])/status" ] || echo service $i arrete
done
sleep 1
done
/etc/default et /etc/init _______________________________________________________________________________________
Le fichier /etc/init/[Link] contient le lancement du logiciel de gestion d’ouverture de session texte : /sbin/getty
exec /sbin/getty -8 38400 tty1
ajoutons une connexion automatique : exec /sbin/getty -a azerty -8 38400 tty1
ainsi, nous pourrons lancer un programme qui attend une saisie clavier numérique (USB)
Dans le fichier /etc/passwd, nous pouvons ainsi remplacer le shell par un programme (ou script) ou placer le lancement du script dans le
fichier .bashrc de l’utilisateur choisi pour cette fonction.
10 LINUX embarqué / Edition AZERTY Microsystem
Inscription d’interruption sur SIGNAL
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void derouter_interuption(int signum){
printf("il y a eu une exception (signum = %d) !!!!! oups oups ^^ \n",signum);
exit(EXIT_FAILURE); /* en enlevant cette ligne – proc. Ne s’arrêtera jamais */
}
int main(){
struct sigaction nouvelle_action;
int a=1, b=0,c;
nouvelle_action.sa_handler = derouter_interuption;
sigemptyset(&nouvelle_action.sa_mask);
sigaction(SIGFPE, &nouvelle_action, NULL);
while (1) { delay(50) ; } ; /* boucle infinie pour ne pas être swappé */
c = a/b; /* instruction jamais lancée – sauf si on enlève le while(1) */
return EXIT_SUCCESS;
}
Installation de gcc : apt-get install gcc
Compilation : gcc –o sig sig.c
Provoquons le signal à partir du noyau sur SIGFPE (signal 8)
kill -8 numeroDeProcess
Dans les applications temps-réel, nous détournons les signaux pour ne pas être arrêté par des aléas …
11 LINUX embarqué / Edition AZERTY Microsystem
Chargement de Driver en mode Kernel – inutile en RASPBERRY ________________________________________________________
IRQ IRQ
/dev /dev
Noyau Noyau
Périphériques module
Périphériques while (1)
Dans notre exemple, nous sommes en forme de module (appelé par le noyau). Nous ne consommons pas de CPU durant l’attente.
vim module.c
#define KERN_EMERG "<0>" /* système inutilisable */
#define KERN_ALERT "<1>" /* action à effectuer immédiatement*/
#define KERN_CRIT "<2>" /* conditions critiques */
#define KERN_ERR "<3>" /* conditions d'erreurs */
#define KERN_WARNING "<4>" /* message d'avertissement */
#define KERN_NOTICE "<5>" /* normal mais significatif */
#define KERN_INFO "<6>" /* informations */
#define KERN_DEBUG "<7>" /* messages de débugging */
#include <linux/module.h>
#include <linux/init.h>
12 LINUX embarqué / Edition AZERTY Microsystem
static int __init mon_module_init(void)
{
printk(KERN_DEBUG "Hello World !\n");
return 0;
}
static void __exit mon_module_cleanup(void)
{
printk(KERN_DEBUG "Goodbye World!\n");
}
module_init(mon_module_init);
module_exit(mon_module_cleanup);
nano Makefile (attention, avec un « M » majuscule)
obj-m += module.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Attention, devant le mot « make » dans le fichier, IL FAUT une tabulation.
Ajouter la commande « make » : apt-get install make
Mise à jour du noyau : apt-get install linux-headers-$(uname –r)
13 LINUX embarqué / Edition AZERTY Microsystem
Compilation du module
make
Chargement du module dans les drivers
insmod ./[Link]
Vérification que le module est bien chargé
lsmod
Déchargement du module
rmmod [Link]
Vérification des logs systèmes – voir nos textes
dmesg
Mettre en place les informations sur module : modinfo [Link]
#define MODULE
MODULE_AUTHOR("Mon module");
MODULE_DESCRIPTION("exemple de module");
MODULE_SUPPORTED_DEVICE("none");
MODULE_LICENSE("none");
14 LINUX embarqué / Edition AZERTY Microsystem
Passage de paramètres lors du chargement du module : insmod ./[Link] param=2
#include <linux/module.h>
#include <linux/init.h>
MODULE_AUTHOR("Mon module");
MODULE_DESCRIPTION("exemple de module");
MODULE_SUPPORTED_DEVICE("none");
MODULE_LICENSE("none");
static int param;
module_param(param, int, 0);
MODULE_PARM_DESC(param, "Un paramètre de ce module");
static int __init mon_module_init(void)
{
printk(KERN_DEBUG "Hello World !\n");
printk(KERN_DEBUG "param=%d !\n", param);
return 0;
}
static void __exit mon_module_cleanup(void)
{
printk(KERN_DEBUG "Goodbye World!\n");
}
module_init(mon_module_init);
module_exit(mon_module_cleanup);
15 LINUX embarqué / Edition AZERTY Microsystem
Chargement d’un module en mode Caractères – périphérique dans /dev/
Avant tout, les drivers sont associés à un « canal » qui permet de savoir sur quel driver il sera « connecté ». Il s’agit de l’association MAJOR
/ MINOR qui se trouvent dans le dossier /dev/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
MODULE_AUTHOR("Mon module");
MODULE_DESCRIPTION("premier driver");
MODULE_SUPPORTED_DEVICE("none");
MODULE_LICENSE("none");
static int major = 60;
module_param(major, int, 0);
MODULE_PARM_DESC(major, "major number");
static ssize_t my_read_function(struct file *file, char *buf, size_t count, loff_t *ppos)
{ printk(KERN_DEBUG "read()\n");
return count; }
static ssize_t my_write_function(struct file *file, const char *buf, size_t count, loff_t *ppos)
{ printk(KERN_DEBUG "write()\n");
return count; }
static int my_open_function(struct inode *inode, struct file *file)
{ printk(KERN_DEBUG "open()\n");
return 0; }
static int my_release_function(struct inode *inode, struct file *file)
{ printk(KERN_DEBUG "close()\n");
return 0; }
16 LINUX embarqué / Edition AZERTY Microsystem
static struct file_operations fops =
{
read : my_read_function,
write : my_write_function,
open : my_open_function,
release : my_release_function /* correspond a close */
};
static int __init mon_module_init(void)
{ int ret;
ret = register_chrdev(major, "mydriver", &fops);
if(ret < 0) {
printk(KERN_WARNING "Probleme sur le major\n");
return ret;
}
printk(KERN_DEBUG "mydriver chargé avec succès\n");
return 0;
}
static void __exit mon_module_cleanup(void)
{ unregister_chrdev(major, "mydriver");
printk(KERN_DEBUG "mydriver déchargé avec succès\n");
}
module_init(mon_module_init);
module_exit(mon_module_cleanup);
17 LINUX embarqué / Edition AZERTY Microsystem
nano Makefile
obj-m += mydriver.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Compilation du module
make
Chargement du module dans les drivers
insmod ./[Link]
Création d’un périphérique de type caractère sur le même MAJOR/MINOR
mknod /dev/mydriver c 60 0
Vérification que le module est bien chargé
lsmod
more /proc/modules
Vérification du bon fonctionnement du driver / module
echo bonjour > /dev/mydriver
dmesg
18 LINUX embarqué / Edition AZERTY Microsystem
Devices de type caractères
Périphérique Nom N° majeur N° mineur
Port parallèle 0 /dev/lp0 ou /dev/par0 6 0
Port parallèle 1 /dev/lp1 ou /dev/par1 2 1
Premier port série /dev/ttyS0 4 64
Second port série /dev/ttyS1 4 65
Lecteur de cassettes IDE /dev/ht0 37 0
Premier lecteur de cassettes SCSI /dev/st0 9 0
Second lecteur de cassettes SCSI /dev/st1 9 1
Console système /dev/console 5 1
Premier terminal virtuel /dev/tty1 4 1
Second terminal virtuel /dev/tty2 4 2
Terminal du processus courant /dev/tty 5 0
Carte son (oss) /dev/audio 14 4
Devices de type Bloc
Périphérique Nom N° majeur N° mineur
Premier lecteur de disquettes /dev/fd0 2 0
Second lecteur de disquettes /dev/fd1 2 1
Contrôleur IDE primaire, maître /dev/hda 3 0
Contrôleur IDE primaire partition 1 /dev/hda1 3 1
Contrôleur IDE primaire, esclave /dev/hdb 3 64
Contrôleur IDE second partition 1 /dev/hdb1 3 65
Premier lecteur SCSI /dev/sda 8 0
Premier lecteur SCSI, partition 1 /dev/sda1 8 1
Second lecteur SCSI /dev/sdb 8 16
Second lecteur SCSI, partition 1 /dev/sdb1 8 17
19 LINUX embarqué / Edition AZERTY Microsystem
Protocole de communication entre le driver et le système ___________________________________________________________
Si nous souhaitons allumer et éteindre une LED à partir d’un dev : echo 1 > /dev/led ou echo 0 > /dev/led
fichier led.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
MODULE_AUTHOR("Module LED");
MODULE_DESCRIPTION("Raspberry LED");
MODULE_SUPPORTED_DEVICE("none");
MODULE_LICENSE("none");
static int major = 61;
module_param(major, int, 0);
MODULE_PARM_DESC(major, "major number");
static ssize_t my_read_function(struct file *file, char *buf, size_t count, loff_t *ppos)
{ return count; }
static ssize_t my_write_function(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
return count; }
static int my_open_function(struct inode *inode, struct file *file)
{ return 0; }
static int my_release_function(struct inode *inode, struct file *file)
{ return 0; }
20 LINUX embarqué / Edition AZERTY Microsystem
static struct file_operations fops =
{
read : my_read_function,
write : my_write_function,
open : my_open_function,
release : my_release_function /* correspond a close */
};
static int __init mon_module_init(void)
{ int ret;
ret = register_chrdev(major, "mydriver", &fops);
if(ret < 0) {
printk(KERN_WARNING "Probleme sur le major\n");
return ret;
}
printk(KERN_DEBUG "mydriver chargé avec succès\n");
return 0;
}
static void __exit mon_module_cleanup(void)
{ unregister_chrdev(major, "mydriver");
printk(KERN_DEBUG "mydriver déchargé avec succès\n");
}
module_init(mon_module_init);
module_exit(mon_module_cleanup);
nano Makefile
obj-m += led.o
21 LINUX embarqué / Edition AZERTY Microsystem
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Compilation du module
make
Chargement du module dans les drivers
insmod ./[Link] param=61
Si nous souhaitons allumer une LED, nous pourrions créer un device :
mknod /dev/led c 61 0
puis à partir du système : allumons la led
echo 1 > /dev/led
éteignons la led
echo 0 > /dev/led
22 LINUX embarqué / Edition AZERTY Microsystem
Gestion de l’Embarqué à distance – connexion RESEAU
Services Réseaux ____________________________________________________________________________________________
Le paramétrage réseau se fait par un fichier – adresse IP dhcp pour eth0 et adresse IP fixe pour eth1 (par exemple)
cat > /etc/network/interfaces << FIN_SCRIPT
# The loopback network interface
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address [Link]
netmask [Link]
FIN_SCRIPT
Pour recharger la configuration réseau
/etc/init.d/networking restart
La description des cartes réseaux et leur association avec les adresse MAC se trouve dans un fichier
/etc/udev/rules.d/[Link]
En l’effaçant, LINUX, oublie la relation entre MAC et ethx
Gestion par périphériques _____________________________________________________________________________________
La plupart des périphériques branchés sur embarqué se fait maintenant par USB. Rapide, stable, efficace, interchangeable et reconnu à
chaud, l’USB s’impose depuis des années et, depuis l’USB 3, devient totalement incontournable.
lsusb pour voir les périphériques USB connectés avec les contrôleurs
23 LINUX embarqué / Edition AZERTY Microsystem
Web Services (en PHP)________________________________________________________________________________________
Pour lancer des commandes ROOT sans être ROOT, il est possible de se servir du StickyBit. Faisons un exemple.
Ainsi, APACHE pourra lancer des commandes root !
# Création d'un fichier en langage C
cat > chmod4111.c << FIN_SCRIPT
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
extern char **environ;
extern int errno;
int main (int argc, char **argv) {
setreuid(0,0);
execve(argv[1], NULL, environ); printf ("Error : %d\n", errno);
return errno; }
FIN_SCRIPT
# en tant que root - installer gcc et activation du mode root
apt-get update
apt-get install gcc
gcc -o chmod4111 chmod4111.c
chmod 4111 chmod4111
# plaçons cet exécutable dans le dossier WEB (pour faciliter l’exercice)
mv chmod4111 /var/www/
24 LINUX embarqué / Edition AZERTY Microsystem
LINUX embarqué
Interconnexion avec Raspberry
Partie II
Auteur
Jean-François Casquet
Editeur : AZERTY Microsystem
2004 - 2017 © Tous droits réservés
copie interdite
[Link]/stage/
25 LINUX embarqué / Edition AZERTY Microsystem
A partir de PHP (apache), créons un fichier avec lançons-le en mode ROOT
# créons un fichier [Link] sur la dossier principal de notre serveur WEB afin de lancer une commande LINUX dans cette page.
rm /var/www/[Link]
cat > /var/www/[Link] << FIN_SCRIPT
<? exec ('echo "#!/bin/bash" > script ');
exec ('echo "set PATH=/usr/bin:/usr/sbin:/usr/local/sbin:/sbin:/bin" >> script ');
exec ('echo "w " >> script '); exec ('chmod 777 script'); exec('./chmod4111 script', $a); ?>
<table width="100%" border="1" cellspacing="0" cellpadding="0"><tr><td><table width="100%">
<? $bgcolor= -1;
for ($index = 0; $index < count($a); $index ++) { ?>
<tr bgcolor="<? if($bgcolor == 1){ echo "#FFFFFF";} else {echo "#E1FFE1";}; $bgcolor = $bgcolor * (-1); ?>"><td>
<? $a[$index] = preg_replace("/</", "$lt;", $a[$index]);
$a[$index] = preg_replace("/>/", "$gt;", $a[$index]);
$a[$index] = preg_replace("/\\s/", "#TAB#", $a[$index]);
for ($z = 0 ; $z < 10; $z ++ ) { $a[$index] = preg_replace("/#TAB##TAB#/", "#TAB#", $a[$index]); }
$a[$index] = preg_replace("/#TAB#/", "</td><td>", $a[$index]);
echo $a[$index]."<br></td></tr>";
} /* end for */
?>
</table></td></tr></table>
FIN_SCRIPT
Interconnexion avec le matériel ________________________________________________________________________________
Mettre en page une informations dans une page Web
26 LINUX embarqué / Edition AZERTY Microsystem
Installation de WIRINGPI pour accéder au port GPIO en C – connexion direct au noyaux LINUX
apt-get install wiringpi
apt-get update
apt-get install gcc
Interactions matérielles
Gestion des devices sur Raspberry : fichier 1.c_____________________________________________________________________
#include <wiringPi.h>
#include <softPwm.h>
#include <stdio.h>
#define uchar unsigned char
#define LedPinRed 0
#define LedPinGreen 1
void ledColorSet(uchar r_val, uchar g_val) {
softPwmWrite(LedPinRed, r_val);
softPwmWrite(LedPinGreen, g_val);
}
int main(void) {
int i;
if(wiringPiSetup() == -1){ printf("setup wiringPi failed !"); return 1; }
softPwmCreate(LedPinRed, 0, 100);
27 LINUX embarqué / Edition AZERTY Microsystem
softPwmCreate(LedPinGreen,0, 100);
while(1){
delay(500); ledColorSet(0xff,0x00); //red
delay(500); ledColorSet(0x00,0xff); //green
delay(500); ledColorSet(0xff,0x45);
delay(500); ledColorSet(0xff,0xff);
delay(500); ledColorSet(0x7c,0xfc);
}
return 0;
}
gcc -o 1 1.c -lwiringPi
28 LINUX embarqué / Edition AZERTY Microsystem
TP de déclenchent d’une LED par un interrupteur sur le réseau
Détournement d’interruption GPIO de Raspberry _____________________________________________________________
# fichier /home/pi/interrupteur.c
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#define Interrupteur 1
void myISR(void) {
printf("Interrupteur OK !\n"); exit (0); // sortie direct du processus
}
int main(void)
{
if(wiringPiSetup() == -1){ printf("setup wiringPi failed !\n"); return 1; }
if(wiringPiISR(Interrupteur, INT_EDGE_FALLING, &myISR)){
// Détournement d’interruption / signal
printf("Initialisation KO !\n");
return 1;
}
while(1){ delay(50000); }
}
cd /home/pi
gcc interrupteur.c -o interrupteur -lwiringPi
29 LINUX embarqué / Edition AZERTY Microsystem
Créons un SCRIPT qui attend que l’on appuie sur le bouton _____________________________________________________
Le bash qui va déclencher le second raspberry – ici : adresse IP : [Link]
Fichier : /home/pi/[Link]
#!/bin/bash
cd /home/pi
while ./interrupteur ; do # lance le programme C et attend sa fermeture
wget "[Link] -O /tmp/detruire –q # ouvre la page « [Link] » sur l’autre Raspberry
done
echo "ALERTE : Le programme qui teste l interrupteur ne fonctionne pas"
Créons un SERVICE qui lance le script ______________________________________________________________________
cat > /etc/init.d/monservice << DOG
#!/bin/bash
[ -d /tmp ] || mkdir /tmp
touch /tmp/[Link]
case '$1' in
start)
[ -f "/proc/$(cat /tmp/[Link])/status" ] && (echo "service deja lancé" ; return 1)
/home/pi/[Link] &
echo $! > /tmp/[Link] ;;
stop)
kill $(cat /tmp/[Link]) ;;
restart)
kill $(cat /tmp/[Link])
30 LINUX embarqué / Edition AZERTY Microsystem
/home/pi/[Link] &
echo $! > /tmp/[Link] ;;
status)
[ -f "/proc/$(cat /tmp/[Link])/status" ] && echo "service OK" || echo "service HS"
*) echo "Attention, synthaxe : monservice2 start ou stop ou status"
;;
esac
DOG
chmod 755 /etc/init.d/monservice
/etc/init.d/monservice start
Lançons le service au démarrage __________________________________________________________________________
cd /etc/rc2.d/ .......................................................................... rc2.d car nous sommes en INIT 2
ln -s /etc/init.d/monservice S90monservice
En plaçant le lien S90monservice dans le dossier /etc/rc2.d/ le service sera lancé à chaque démarrage.
31 LINUX embarqué / Edition AZERTY Microsystem
SUR LE SECOND RASPBERRY
Allumer une LED _______________________________________________________________________________________
Fichier led.c
#include <wiringPi.h>
#include <stdio.h>
#define Led 4
int main(void)
{
if(wiringPiSetup() == -1){ printf("setup wiringPi failed !"); return 1; }
pinMode(Led, OUTPUT);
digitalWrite(Led, HIGH);
delay(500);
digitalWrite(Led, LOW);
delay(500);
return 0;
}
gcc led.c -o led -lwiringPi
32 LINUX embarqué / Edition AZERTY Microsystem
Permettre à APACHE de devenir Root ______________________________________________________________________
cat > chmod4111.c << FIN_SCRIPT TP déclencher un LED par un interrupteur en réseau
#include <unistd.h>
INTERRUPTEUR en réseau
#include <errno.h> 1ier Raspberry
#include <stdio.h>
#include <sys/types.h>
extern char **environ;
extern int errno;
int main (int argc, char **argv) {
setreuid(0,0);
execve(argv[1], NULL, environ); printf ("Error : %d\n", errno);
return errno; }
FIN_SCRIPT LED déclenchée par réseau
# en tant que root - installer gcc et activation du mode root 2nd Raspberry
gcc -o chmod4111 chmod4111.c
chmod 4111 chmod4111
Création du fichier [Link] dans /var/www/html/ ____________________________________________________________
7:gnd
8:led
<?php exec("./chmod4111 ./led") ; ?>
33 LINUX embarqué / Edition AZERTY Microsystem
Configuration réseau du second Raspberry __________________________________________________________________
cat > /etc/network/interfaces << FIN_SCRIPT
# The loopback network interface
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address [Link]
netmask [Link]
FIN_SCRIPT
/etc/init.d/networking restart
Explication finale du déclenchement d’une LED en réseau
- le Raspberry 1 lance un service au démarrage
- le service boucle en attendant la « mort » du programme qui attend que l’on appuie sur le bouton poussoir
- Dès que l’on appuie sur le bouton, la commande WGET charge la page PHP du second Raspberry
- Pour cela, le second Raspberry doit avoir une adresse IP fixe : [Link] (par exemple)
- Le second, puisque APACHE et PHP sont lancés au démarrage, ouvre la page [Link] réclamée
- cette page possède un ordre EXEC qui va lancer un programme pour que la lumière s’allume
- Mais, comme APACHE n’est pas ROOT, il nous a fallu créer un programme CHMOD4111 qui le permet
- le programme LED est donc lancé par « ROOT » gràce à APACHE et PHP
34 LINUX embarqué / Edition AZERTY Microsystem
Récupération de données de position JoyStick sur Raspberry _________________________________________
#include <wiringPi.h>
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define ADC_CS 0
#define ADC_CLK 1
#define ADC_DIO 2
#define JoyStick_Z 3
uchar get_ADC_Result(uchar xyVal)
{
//10:CH0
//11:CH1
uchar i;
uchar dat1=0, dat2=0;
digitalWrite(ADC_CS, 0);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2); //CH0 10
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
35 LINUX embarqué / Edition AZERTY Microsystem
if(xyVal == 'x'){
digitalWrite(ADC_DIO,0); delayMicroseconds(2); //CH0 0
}
if(xyVal == 'y'){
digitalWrite(ADC_DIO,1); delayMicroseconds(2); //CH1 1
}
digitalWrite(ADC_CLK,1);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0);
digitalWrite(ADC_DIO,1); delayMicroseconds(2);
for(i=0;i<8;i++)
{
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
pinMode(ADC_DIO, INPUT);
dat1=dat1<<1 | digitalRead(ADC_DIO);
}
for(i=0;i<8;i++)
{
dat2 = dat2 | ((uchar)(digitalRead(ADC_DIO))<<i);
digitalWrite(ADC_CLK,1); delayMicroseconds(2);
digitalWrite(ADC_CLK,0); delayMicroseconds(2);
}
36 LINUX embarqué / Edition AZERTY Microsystem
digitalWrite(ADC_CS,1);
pinMode(ADC_DIO, OUTPUT);
return(dat1==dat2) ? dat1 : 0;
}
int main(void)
{
uchar tmp;
uchar xVal = 0, yVal = 0, zVal = 0;
if(wiringPiSetup() == -1){
printf("setup wiringPi failed !");
return 1;
}
pinMode(ADC_CS, OUTPUT);
pinMode(ADC_CLK, OUTPUT);
pinMode(JoyStick_Z, INPUT);
pullUpDnControl(JoyStick_Z, PUD_UP);
while(1){
pinMode(ADC_DIO, OUTPUT);
xVal = get_ADC_Result('x');
if(xVal == 0){
tmp = 1; //up
}
37 LINUX embarqué / Edition AZERTY Microsystem
if(xVal == 255){
tmp = 2; //down
}
yVal = get_ADC_Result('y');
if(yVal == 0){
tmp = 3; //left
}
if(yVal == 255){
tmp = 4; //right
}
zVal = digitalRead(JoyStick_Z);
if(zVal == 0){
printf("Button is pressed !\n");
}
//printf("x : %d y : %d z : %d\n", xVal, yVal, zVal);
switch(tmp){
case 1: printf("up\n"); break;
case 2: printf("down\n"); break;
case 3: printf("right\n"); break;
case 4: printf("left\n"); break;
default:
break;
}
//delay(500);
}
return 0;
}
38 LINUX embarqué / Edition AZERTY Microsystem
Barrière infrarouge sur Raspberry _______________________________________________________________________________
#include <wiringPi.h>
#include <stdio.h>
#define IR 0
int cnt = 0;
void myISR(void)
{
printf("Recevied infrared. cnt = %d\n", ++cnt);
}
int main(void)
{
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
printf("setup wiringPi failed !");
return 1;
}
if(wiringPiISR(IR, INT_EDGE_FALLING, &myISR) == -1){
printf("setup ISR failed !");
return 1;
}
//pinMode(IR, INPUT);
while(1){ delay(5000) ; }; // Attention, il faut mettre le processus en SLEEP pour éviter la chauffe du processeur inutilement
return 0;
}
39 LINUX embarqué / Edition AZERTY Microsystem
Charger les sources noyaux de Raspberry _________________________________________________________________________
[Link]
cd
mkdir rpi-kernel && cd rpi-kernel
git clone --depth=1 [Link]
apt-get install bc
cd linux
KERNEL=kernel7
make bcm2709_defconfig
make -j4 zImage modules dtbs
sudo make modules_install
sudo cp arch/arm/boot/dts/*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
sudo scripts/mkknlimg arch/arm/boot/zImage /boot/$[Link]
Installation à la main des packages noyaux
git clone [Link] rpi-kernel
cd rpi-kernel
# il faut s’assurer que le package et la distribution sont identiques
head Makefile
uname -r
zcat /proc/[Link] > ./.config ou make bcmrpi_defconfig
apt-get install bc
40 LINUX embarqué / Edition AZERTY Microsystem
make /* dure des heures */
make modules
ln -s /home/pi/rpi-kernel/tools/build /lib/modules/$(uname -r)/build
cd /home/pi/rpi-kernel/tools/
make install
make all
cd /home/pi/rpi-kernel/
make modules_install
cd /home/pi/rpi-kernel/tools/build
rpi-update f406502f5628d32e6ca5dadac34ff7ca59f8e27f
rpi-update a16f516e5d058eaa9a2d22288576c58f24db6137 # le bon
apt-get install linux-headers-4.4.0-1*
make
enfaisant : make modules_install
il est possible de créer un nouveau noyau à compiler.
cp /boot/[Link] /boot/[Link]
cp arch/arm/boot/zImage /boot/[Link]
reboot
41 LINUX embarqué / Edition AZERTY Microsystem
Le monde du tactile
Linux en mode graphique _____________________________________________________________________________________
raspi-config -> agrandir la partition
apt-get update
aptitude install xautomation # installation du gestionnaire clavier/souris/ écran de veille
apt-get install unclutter # installation de l’effaceur de souris
echo "" > /etc/xdg/lxsession/LXDE-pi/autostart # menu démarrer du mode graphique sans mise en veille
cat > /home/pi/.config/lxsession/LXDE-pi/autostart << FIN_SCRIPT
@xset s off
@xset -dpms
@xset s noblank
@/home/pi/[Link]
FIN_SCRIPT
cat > /home/pi/[Link] << FIN_SCRIPT
sudo -u pi epiphany-browser -a -i --profile ~/.config [Link] --display=:0 &
sleep 15s;
xte "key F11" -x:0
FIN_SCRIPT
chmod 755 /home/pi/[Link]
apt-get install apache2 php5 php5-gd # pour installer les package de gestion graphique en PHP
42 LINUX embarqué / Edition AZERTY Microsystem
Gérer les connexions avec des éléments analogiques en lecture « série »
Comment lire une information analogique ________________________________________________________________________
Les Raspberry permettent de parler vers des circuits en mode
asynchrone. Par exemple, au travers du MCP3008.
Ainsi, nous pouvons lire la valeur analogique trouvée sur le
Chanel (0 à 8) .
Il faut se mettre en mode SPI (Serial Peripheral Interface)
ATTENTION : ce circuit fonctionne en 3.3volts ! ! !
/* readMcp3008.c:
* Requires: wiringPi ([Link]
* Copyright (c) 2015 [Link]
*********************************************************************** */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <wiringPi.h>
43 LINUX embarqué / Edition AZERTY Microsystem
#include <wiringPiSPI.h>
#define TRUE (1==1)
#define FALSE (!TRUE)
#define CHAN_CONFIG_SINGLE 8
#define CHAN_CONFIG_DIFF 0
static int myFd ;
char *usage = "Usage: mcp3008 all|analogChannel[1-8] [-l] [-ce1] [-d]";
// -l = load SPI driver, default: do not load
// -ce1 = spi analogChannel 1, default: 0
// -d = differential analogChannel input, default: single ended
void loadSpiDriver() {
if (system("gpio load spi") == -1) {
fprintf (stderr, "Can't load the SPI driver: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
} }
void spiSetup (int spiChannel) {
if ((myFd = wiringPiSPISetup (spiChannel, 1000000)) < 0) {
fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
} }
int myAnalogRead(int spiChannel,int channelConfig,int analogChannel) {
if(analogChannel<0 || analogChannel>7)
return -1;
unsigned char buffer[3] = {1}; // start bit
buffer[1] = (channelConfig+analogChannel) << 4;
wiringPiSPIDataRW(spiChannel, buffer, 3);
return ( (buffer[1] & 3 ) << 8 ) + buffer[2]; // get last 10 bits
}
44 LINUX embarqué / Edition AZERTY Microsystem
int main (int argc, char *argv []) {
int loadSpi=FALSE; int analogChannel=0; int spiChannel=0; int channelConfig=CHAN_CONFIG_SINGLE;
if (argc < 2) {
fprintf (stderr, "%s\n", usage) ;
return 1 ;
}
if((strcasecmp (argv [1], "all") == 0) )
argv[1] = "0";
if ( (sscanf (argv[1], "%i", &analogChannel)!=1) || analogChannel < 0 || analogChannel > 8 ) {
printf ("%s\n", usage) ;
return 1 ;
}
int i;
for(i=2; i<argc; i++) {
if (strcasecmp (argv [i], "-l") == 0 || strcasecmp (argv [i], "-load") == 0)
loadSpi=TRUE;
else if (strcasecmp (argv [i], "-ce1") == 0)
spiChannel=1;
else if (strcasecmp (argv [i], "-d") == 0 || strcasecmp (argv [i], "-diff") == 0)
channelConfig=CHAN_CONFIG_DIFF;
}
//
if(loadSpi==TRUE) loadSpiDriver();
wiringPiSetup () ;
spiSetup(spiChannel);
//
if(analogChannel>0) {
printf("MCP3008(CE%d,%s): analogChannel %d = %d\n",spiChannel,(channelConfig==CHAN_CONFIG_SINGLE)
?"single-ended":"differential",analogChannel,myAnalogRead(spiChannel,channelConfig,analogChannel-1));
} else {
for(i=0; i<8; i++) {
printf("MCP3008(CE%d,%s): analogChannel %d = %d\n",spiChannel,(channelConfig==CHAN_CONFIG_SINGLE)
?"single-ended":"differential",i+1,myAnalogRead(spiChannel,channelConfig,i));
} }
close (myFd) ;
return 0;
}
45 LINUX embarqué / Edition AZERTY Microsystem
Gérer les connexions avec des éléments actifs SERVO
Comment envoyer des fréquences vers un servo moteur par PWM______________________________________________________
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <softPwm.h>
#define PIN_0 0 // pin GPIO 17
int main(int argc, char *argv[]){
int pos =0; char reponse = ' ';
if(wiringPiSetup() == -1){ printf("Bug\n"); exit(1); }
pinMode(PIN_0,OUTPUT); //définition de la gpio de sortie
digitalWrite(PIN_0,LOW); //son etat initial est à l état bas
softPwmCreate(PIN_0,0,500); //creation de la pwm
do{
printf("Position à 0°:\n"); softPwmWrite(PIN_0,25); delay(2000);
printf("Position à 90° :\n"); softPwmWrite(PIN_0,16); delay(2000);
printf("Position à 180° : \n"); softPwmWrite(PIN_0,8); delay(2000);
//les positions sont arbitraires
do{
printf("Voulez-vous continuer (0/N)\n"); scanf("%c",&reponse);
} while(reponse != 'O' && reponse !='N');
}while(reponse == 'O');
printf("Bye\n");
return 0;
}
gcc -o servo servo.c -lwiringPi
46 LINUX embarqué / Edition AZERTY Microsystem
Gérer un écran à cristaux liquides
Comment envoyer du texte sur un écran LCD ______________________________________________________________________
#include <wiringPi.h>
#include <softPwm.h>
#include <stdio.h>
#include <lcd.h>
#define uchar unsigned char
#define D7 1 // 22
#define D6 4 // 23
#define D5 5 // 24
#define D4 6 // 25
#define RS 3 // 29
#define OK 0 // 28
#define true 1
#define false 0
#define LCD_CMD 0
#define LCD_CHR 1
#define LCD_LINE_1 0x80
#define LCD_LINE_2 0xC0
int main(int argc, char **argv)
{
if(wiringPiSetup() == -1){ printf("setup wiringPi failed !"); return 1; }
int lcd; lcd = lcdInit(2, 16, 4, RS, OK, D4, D5, D6, D7, 0, 0, 0, 0);
lcdClear (lcd); lcdPosition(lcd, 0,0 ); lcdPrintf(lcd, argv[1], argv[2]);
}
Les cercles noir et rouge, représentent des potentiomètres pour
gcc lcd.c -o lcd -lwiringPi –lwiringPiDev
./lcd "bonjour" régler la luminosité du fond d’écran et du texte.
47 LINUX embarqué / Edition AZERTY Microsystem
Utilisation du shell : Préparer l’écran à cristaux liquides. Respecter
les couleurs
vide=' ' Brochage : noir / blanc / - / gris / - / violet
premiereligne=$( ifconfig eth0 | grep Bcast | sed "s/[ ]*Bcast/:/g" | cut -d: -f2 )$vide
secondeligne="Adresse IP"$vide
./lcd "${premierelign[Link]}${secondelign[Link]}"
Pour réussir facilement les soudure, il suffit de reculer légèrement Faire exactement pareil sur la seconde partie de la nappe.
les bout de câble et de les plier comme indiqué sur les photos Mais, attention, le câble ROUGE ne doit pas être soudé.
Brochage : Bleu / vert / jaune / orange / - / marron
48 LINUX embarqué / Edition AZERTY Microsystem
Soudures propres Couper la patte du potentiomètre qui est à coté de l’autre
En retournant l’écran, placer le potentiomètre comme indiqué Dans l’autre sens dépassent les pattes du potentiomètre
Entre le Blanc et le Gris / entre le Gris et le Violet
49 LINUX embarqué / Edition AZERTY Microsystem
Couper une patte d’une résistance et la plier comme suit Souder la patte de position 1 avec position 5
Placer le potentiomètre patte centrale sur la position 16 et le câble
Couper la patte du potentiomètre rouge sur l’autre patte
50 LINUX embarqué / Edition AZERTY Microsystem
Il va falloir brancher les cordons sur le Raspberry pour tester l’écran.
51 LINUX embarqué / Edition AZERTY Microsystem
Testons le nombre de connexions REELLES à apache par un SERVICE tous les secondes
cat > /[Link] << FIN_SCRIPT
# !/bin/bash
touch « /var/run/alerte » # créons un point de sortie – tant que le fichier existe le DAEMONS boucle
while [ -f /var/run/alerte ] ; do # boucle – arrêt dès que le fichier sera supprimer par le daemon
if [ $(netstat –anpe | grep « apache2 » | wc –l) –gt « 1 » ] ; then # testons le nombre de connexions réelles (sup à 1)
if [ -f /var/spool/alerte ] ; then # si le fichier alerte existe c est que nous etions deja en overflow
[ $count –eq 10 ] && echo $(date) « : ESCALADE connexions » >> /var/log/[Link] # si 10 alertes alors LOG
[ $count –eq 20 ] && echo $(date) « : ESCALADE SOS « >> /var/log/[Link] # si 20 alertes alors LOG
((count++)) # incrémentons le compteur pour les escalades
else # sinon : si le fichier alerte n existe pas – c est que c est la premiere alerte
touch /var/spool/alerte # creons le fichier qui dit que nous entrons en alerte
echo $(date) « : Alerte nb connexions » >> /var/log/[Link] # log de la premiere alerte
count=0 # le compteur est mis ou remis a zero pour compter les escalades
fi
else # si le nombre de connexion est en dessous du seuil
if [ -f /var/spool/alerte ] ; then # le fichier alerte existe – donc nous etions en alerte
rm –f /var/spool/alerte # effacons le fichier d’alerte pour retourner en etat normal sans alerte
echo $(date) « : FIN alerte nb connexions » >> /var/log/[Link] # retour en etat sans alerte – prevenons
fi
fi
sleep 1 ; # attente d 1 seconde entre chaque test – si nous testions toutes les minutes : utilisons un CRON
done
FIN_SCRIPT
52 LINUX embarqué / Edition AZERTY Microsystem
Vérifier le remplissage des disques avant l’alerte ___________________________________________________________________
#!/bin/bash
# fichier /BACKUP/[Link]
df -P | grep -v "Sys. de fi" | sed 's/%//g' |
while read mountage a b c taille dossier ; do
if [ $taille -gt 20 ]; then
echo $mountage " a un remplissage de " $taille " %"
fi
done
Créons une barre de remplissage pour navigateur __________________________________________________________________
En php nous faisons appel à une fonction shell qui va créer un fichier PHP qui contient une variable php avec la valeur qui vient du système.
Puis, il suffit d’importer le fichier PHP et d’afficher la page en tenant compte de la valeur de la variable PHP.
Fichier : [Link]
free -b | grep "Mem" | awk '{print "<?php $valeurmaxi=" $2 "; $valeur=$valeurmaxi - " $3 "; ?>"}'
Fichier : [Link]
<? shell('chmod4111 [Link] > [Link]'); include ("[Link]");?>
<img src="[Link]">
<img src="jogepleine<?php if ((($valeur/ $valeurmaxi)) > 0.8){echo "rouge";}; ?>.jpg"
width="<?php echo (($valeur / $valeurmaxi) * $taille) ; ?>" height="23">
<img src="[Link]" width="<?php echo ((1-($valeur / $valeurmaxi)) * $taille) ; ?>" height="23">
<img src="[Link]">
53 LINUX embarqué / Edition AZERTY Microsystem
Archiver les dates anciennes d’un LOG ___________________________________________________________________________
#!/bin/bash
ok=0
cat /var/log/messages | while read mois jour a ; do
if [ "$mois $jour " = "May 11 " ]; then ok=1 ; fi
if [ "$ok" -eq 1 ]; then
echo "$mois $jour $a" >> /var/log/messages2
fi
done
mv /var/log/messages "/var/log/messages $(date)"
mv /var/log/messages2 /var/log/messages
54 LINUX embarqué / Edition AZERTY Microsystem
Sauvegarde avec un décalage hebdo/mensuel…
#!/bin/sh
cat > /tmp/s1 << END_SCRIPT
user LOGIN MOTDEPASSE
lcd /BACKUP
mkdir %SEMAINE%
cd %SEMAINE%
put [Link]
put [Link]
put [Link]
quit
END_SCRIPT
case $1 in
semaine) cat /tmp/s1 | sed `echo 's/%SEMAINE%/semaine_'$(date "+%w")'/g'` > /tmp/s2 ;;
mois) cat /tmp/s1 | sed `echo 's/%SEMAINE%/mois_'$(date "+%m")'/g'` > /tmp/s2 ;;
*) cat /tmp/s1 | grep -v "%SEMAINE%" > /tmp/s2
tar -cjf /BACKUP/[Link] /etc/
tar -cjf /BACKUP/[Link] /var/lib/mysql/
tar -cjf /BACKUP/[Link] /WEB/
;;
esac
ftp -n [Link] < /tmp/s2
cd /BACKUP
date > /tmp/[Link]
echo $1 >> /tmp/[Link]
55 LINUX embarqué / Edition AZERTY Microsystem
echo "[Link] `tar -tf [Link] | wc -l` fichiers" >> /tmp/[Link]
echo "[Link] `tar -tf [Link] | wc -l` fichiers" >> /tmp/[Link]
echo "[Link] `tar -tf [Link] | wc -l` fichiers" >> /tmp/[Link]
ls -lah /BACKUP/*.tar >> /tmp/[Link]
mail jf@[Link] < /tmp/[Link]
cp /BACKUP/[Link] /WEB/
cp /BACKUP/[Link] /WEB/
Actions lancée par site internet
<?
$socket = connectTo("[Link]", 4864);
sendTo('cgsmsg "'.$_SERVER[REMOTE_ADDR].' sur ADMIN LINUX"', $socket);
socket_close($socket);
?>
<html><body>
<p align="center">Administration Serveur LINUX</p>
<p><font size="1" face="Verdana, Arial, Helvetica, sans-serif">
| <a href="?cmd=ifconfig">Ifconfig</a>
| <a href="?cmd=route">Route</a>
| <a href="?cmd=iptunnel">Ip Tunnel</a>
| <a href="?cmd=df">Partitions</a>
| <a href="?cmd=netstat">Netstat</a>
| <a href="?cmd=lsmod">Drivers</a>
| <a href="?cmd=/sbin/iptables -L">Ip Tables</a>
| <br>
| <a href="?cmd=who">Who</a>
56 LINUX embarqué / Edition AZERTY Microsystem
| <a href="?cmd=ps -aux">PS</a>
| <a href="?cmd=cat /proc/cpuinfo">Processeur</a>
| <a href="?cmd=cat /proc/version">Version LINUX</a>
| <a href="?cmd=cat /proc/meminfo">Mémoire</a>
| <a href="?cmd=cat /proc/ioports">Ports IO</a>
| <a href="?cmd=date">Heure Locale</a>
| <a href="?cmd=cat /proc/net/arp">ARP</a>
| <br>
| <a href="?cmd=whois">Who Is</a>
| <a href="?cmd=host -t mx">DNS MX</a>
| <a href="?cmd=nslookup -type=mx">Champs MX</a>
| <a href="?cmd=host -a">Ref DNS</a>
| <br><br> Services
| <a href="?service=httpd¶m=status">Apache</a>
| <a href="?service=squid¶m=status">Squid</a>
| <a href="?service=firewall¶m=status">Firewall</a>
| <a href="?service=smb¶m=status">Samba</a>
| <a href="?service=mysqld¶m=status">Mysql</a>
| </font></p>
57 LINUX embarqué / Edition AZERTY Microsystem
<?
echo "<HR>";
echo '<font size="3" face="Verdana, Arial, Helvetica, sans-
serif"><strong>'.$_GET[service].$_GET[cmd].'</strong></font>';
echo '<BR><PRE>';
if ($_GET[cmd] != ""){
if (($_GET[cmd] == "whois") || ($_GET[cmd] == "host -t mx") || ($_GET[cmd] == "host -a") || ($_GET[cmd] ==
"nslookup -type=mx")){
if ($_POST[serveur] ==""){
echo '<form action="?cmd='.$_GET[cmd].'" method="post"><input name="serveur"
type="text"><input name="envoyer" type="submit" value="envoyer"></form>';
} else {
exec ($_GET[cmd]." ".$_POST[serveur], $test);
}
} else {
exec ($_GET[cmd],$test);
}
for ($index = 0; $index < count($test); $index++){
if (strpos($test[$index], "root") == FALSE ){
echo $test[$index] ."<BR>";
} else {
echo "<font color='red'>". $test[$index] ."</FONT><BR>";
}
}
} else {
/* zone autre que les commandes */
if ($_GET[service] != "") {
58 LINUX embarqué / Edition AZERTY Microsystem
echo '<p>';
echo '<font size="1" face="Verdana, Arial, Helvetica, sans-serif">| <a
href="?service='.$_GET[service].'¶m=status">Status</a>| <a href="?service='.$_GET[service].'¶m=stop">Stop</a>| <a
href="?service='.$_GET[service].'¶m=start">Start</a>| <a href="?service='.$_GET[service].'¶m=restart">Restart</a>
|</font><p><BR>';
exec ('echo "/etc/init.d/'.$_GET[service].' '.$_GET[param].'" > /tmp/AZERTY_cmd', $dummy);
exec ('/sbin/AZERTY_cmd /etc/init.d/'.$_GET[service].' '.$_GET[param],$test);
for ($index = 0; $index < count($test); $index++){
if (strpos($test[$index], "root") == FALSE ){
echo $test[$index] ."<BR>";
} else {
echo "<font color='red'>". $test[$index] ."</FONT><BR>";
}
} /* end for */
}
} /* endif */
echo "<BR><HR><BR></PRE>";
?>
</body>
</html>
59 LINUX embarqué / Edition AZERTY Microsystem
Surveiller le remplissage de Dossiers
#!/bin/bash
touch /var/run/partage
while [ -f /var/run/partage ] ; do
if [ $(du /SERVEUR/PARTAGE | tail --line 1 | awk '{print $1}') -gt "300" ] ; then
if [ -f /var/spool/partage ] ; then # si le fichier alerte existe c est que nous etions deja en overflow
[ $count –eq 10 ] && echo $(date) « : ESCALADE partage » >> /var/log/[Link] # si 10 alertes alors LOG
((count++)) # incrémentons le compteur pour les escalades
else # sinon : si le fichier alerte n existe pas – c est que c est la premiere alerte
touch /var/spool/partage # creons le fichier qui dit que nous entrons en alerte
echo $(date) « : Alerte pb taille » >> /var/log/ [Link] # log de la premiere alerte
count=0 # le compteur est mis ou remis a zero pour compter les escalades
fi
else # si le nombre de connexion est en dessous du seuil
if [ -f /var/spool/partage ] ; then # le fichier alerte existe – donc nous etions en alerte
rm –f /var/spool/partage # effacons le fichier d’alerte pour retourner en etat normal sans alerte
echo $(date) « : FIN de pb taille » >> /var/log/[Link] # retour en etat sans alerte – prevenons
fi
sleep 1
done
Configurer le serveur MAIL sous Ubuntu
dpkg-reconfigure postfix
60 LINUX embarqué / Edition AZERTY Microsystem