Linux sur CompactFlash
De MicElectroLinGenMet.
Sommaire |
Description
Test d'un Linux minimum sur CompactFlash (8Mo) sur carte mère Pentium 133 / 96Mo.
Je me suis inspiré de plusieurs articles sur "LinuxMag Hors-Série n°24 et 25" concernant les systèmes embarqués à base de Linux.
A partir d'une ancienne carte mère Asus P55T2P4 Pentium 133 (sans ventilateur),96Mo et faire comme un PC mais une "carte électronique" dédié à une fonction à l'image des routeur comme le NetGear qui tourne sur un Linux embarqué.
Ci-dessous l'adaptateur CF/IDE:
Préparation de la carte CF
j'ai utilisé un PC avec lecteur USB de compactflash comme celui-ci pour préparé la CF à recevoir un linux.
- Création de la partition
Pour le test, une seule partition est crée:
fdisk /dev/sda (sda, ici car vu ici comme phériphérique usb-storage sur le PC d'install.) mke2fs /dev/sda1
- Installation grub
Montage de la partition
mount /dev/sda1 /mnt/cf mkdir -p /mnt/cfboot/grub
Copie des fichier grub sur la CF
cp /lib/grub/i386-pc/stage1 /mnt/cf/boot/grub cp /lib/grub/i386-pc/stage2 /mnt/cf/boot/grub cp menu-cf.lst /mnt/cf/boot/menu.lst
Ci-dessous le menu-cf.lst
color white/black black/red timeout 3 default 0 serial --unit=0 --speed=115200 (Port série ttyS0 configuré en port console) terminal serial title DomiX embedded Linux 2.4.32-CF Pentium 133 root (hd0,0) kernel /boot/vmlinuz-2.4.32-CF root=/dev/hda1 ro console=ttyS0
Lancement de grub pour l'installation dans MBR
grub grub> root (hd2,0) Filesystem type is fat, partition type 0x1 (hd2 correspond à ma CF, mais dépend du système, taper "root (hd [ TAB ]" pour faire afficher la liste des disques vus.) grub> setup (hd2) Checking if "/boot/grub/stage1" exists... yes Checking if "/boot/grub/stage2" exists... yes Checking if "/boot/grub/fat_stage1_5" exists... no Running "install /boot/grub/stage1 (hd2) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded Done. grub>quit
La CF est maintenant bootable.
Installation du noyau
Compilation du kernel-2.4.32 avec le .config de l'auteur de l'article Denis Bodor.
- Rajout. module carte réseau (via-rhine).
- Rajout support USB uhci + module mass-storage.
- Rajout support i2c + modules interface parallèle.
- Rajout option packetip/filterip (car pas de dhcp possible).
- Rajout option CONFIG_RAMFS=y pour monter /dev/ram0.
Voir le fichier de configuration du noyau config-2_4_32-CF
# cd /usr/src/linux # make menuconfig # make dep # make clean # make bzImage # make modules # make modules_install
(Rajouter option make HOSTCC=gcc-3.3 CC=gcc-3.3 ... pour le noyau 2.4
=> Le Kernel compilé se trouve dans arch/i386/boot/bzImage
Copie du noyau compilé sur le PC d'install dans /mnt/cf/boot ainsi que les modules dans /mnt/cf/lib/modules
Premier test de boot du noyau ok avec CF de 8Mo.
Installation du système
Pour alléger le système au maximum, utilsation de l'utilitaire busybox qui rassemble dans un seul binaire la plupart des commandes unix de base + des fonctions réseaux.Voir article dans LinuxMag Hors-Série n°24
Le programme se configure comme un noyau linux avec une commande "make menuconfig" avec la possibilté de choisir les commandes à inclure dans le binaire.
Compilation Busybox (inclu init, crond, syslogd ...) à partir des sources.
- init: Voir inittab en exemple. seul rcS est utilisé + console série.
- syslogd: syslogd -O /var/log/syslog -R vesta:514 -L 'Utilise /dev/log en r/w'
- crond: crond -c dir /var/crontab
- udhcpc: (script à prendre dans 'examples' fourni avec source)
- wget:
- apache:
Aprés la copie du binaire "busybox" dans /mnt/cf/bin ainsi que les librairies associées dans /mnt/cf/lib, il faut créer les liens de chaque comandes gérées par busybox:
root@domix# ls -l /bin lrwxrwxrwx 1 root root 7 May 5 15:16 [ -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 [[ -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 ash -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 awk -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 basename -> busybox -rwxr-xr-x 1 root root 447064 May 13 22:08 busybox lrwxrwxrwx 1 root root 7 May 5 15:16 cat -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 chgrp -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 chmod -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 chown -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 clear -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 cp -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 crond -> busybox lrwxrwxrwx 1 root root 7 May 5 15:16 crontab -> busybox
Pour info. la commande ldd permet de connaitre les librairies associées à un programme:
# ldd busybox linux-gate.so.1 => (0xffffe000) libcrypt.so.1 => /lib/tls/libcrypt.so.1 (0xa7f7c000) libm.so.6 => /lib/tls/libm.so.6 (0xa7f57000) libc.so.6 => /lib/tls/libc.so.6 (0xa7e24000) /lib/ld-linux.so.2 (0xa7fc4000)
Fichiers de configuration
- /etc/fstab
/dev/hda1 / ext2 errors=remount-ro 0 1 /dev/ram0 /var ext2 defaults 0 0 proc /proc proc defaults 0 0
- /etc/init.d/modules
#via-rhine (Module carte réseau dlink, désactivé car remplacée par wifi) prism2_usb (Module clef wifi USB )
Installation modules + binaires wlang-ng pour clef NetGear MA111.
J'ai du rajouter les lignes suivantes dans /lib/modules/2.4.32-CF/modules.dep sinon les modules wlan-ng ne sont pas chargés:
/lib/modules/2.4.32-CF/linux-wlan-ng/p80211.o: /lib/modules/2.4.32-CF/linux-wlan-ng/prism2_usb.o: /lib/modules/2.4.32-CF/linux-wlan-ng/p80211.o
- /etc/init.d/rcS
#! /bin/sh # Activation du ramfs /sbin/mkfs.ext2 -vm0 /dev/ram0 4096 mount -t proc /proc mount -a mkdir -p /var/tmp /var/log /var/run /var/crontab /var/dev ln -s /etc/www /var/www /bin/hostname -F /etc/hostname # Lien /dev/log vers /var/dev/log sinon syslog ne démarre pas. /sbin/syslogd -O /var/log/syslog -R vesta:514 -L >> /var/log/boot.log 2>&1 /etc/init.d/modules /sbin/ifconfig lo 127.0.0.1 #/sbin/ifconfig eth0 192.168.0.219 # Activation de la clef wifi /etc/init.d/wlan start sleep 3 /sbin/udhcpc -b -i wlan0 -s /etc/udhcpc.script # Lancement daemon /sbin/crond -c /var/crontab /sbin/inetd /etc/inetd.conf /sbin/httpd -c /etc/httpd.conf -h /var/www # Chargement clavier français /bin/loadkmap < /etc/french.kmap # Lance programme thermomètre i2c /bin/ds1621 &
- /etc/inittab
::sysinit:/etc/init.d/rcS ::respawn:/sbin/getty -L ttyS0 115200 vt100 Console sur port série ::restart:/sbin/init ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
- etc/inetd.conf
telnet stream tcp nowait root /sbin/telnetd /sbin/telnetd
Boot vu de la console série
Booting 'DomiX embedded Linux 2.4.32-CF Pentium 133' root (hd0,0) Filesystem type is ext2fs, partition type 0x83 kernel /boot/vmlinuz-2.4.32-CF root=/dev/hda1 ro console=ttyS0 [Linux-bzImage, setup=0x1400, size=0xdf39e] domix login:
Premier connexion
- telnet
dan@vesta:bin$ telnet domix Trying 192.168.0.2... Connected to domix. Escape character is '^]'. domix login: root BusyBox v1.1.2 (2006.05.07-22:23+0000) Built-in shell (ash) Enter 'help' for a list of built-in commands. root@domix#
- Busybox
Si vous entrer la commande busybox, celle-ci vous renvoie la liste des commandes intégrées.
root@domix# busybox
BusyBox v1.1.2 (2006.05.07-22:23+0000) multi-call binary
Usage: busybox [function] [arguments]...
or: [function] [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as!
Currently defined functions:
[, [[, ash, awk, basename, busybox, cat, chgrp, chmod, chown, clear, cp, crond, crontab, cut, date, dd, df, dirname,
dmesg, du, dumpkmap, e2fsck, echo, egrep, env, expr, false, fgrep, find, free, fsck.ext2, fsck.ext3, ftpget, ftpput,
fuser, getty, grep, halt, head, hostname, httpd, ifconfig, ifdown, ifup, inetd, init, insmod, kill, klogd, ln,
loadkmap, logger, login, ls, lsmod, md5sum, mesg, mkdir, mke2fs, mkfifo, mkfs.ext2, mkfs.ext3, mknod, modprobe,
more, mount, mv, netstat, nohup, ping, poweroff, ps, pwd, reboot, rm, rmdir, rmmod, route, run-parts, sed, sh,
sleep, sort, stty, sync, syslogd, tail, tar, telnet, telnetd, test, tftp, top, touch, true, tty, udhcpc, umount,
uname, uptime, vi, wc, wget
- List des process
Les quelques prrocess qui tournent:
root@domix# ps ax
PID Uid VmSize Stat Command
1 root 572 S init
2 root SW [keventd]
3 root SWN [ksoftirqd_CPU0]
4 root SW [kswapd]
5 root SW [bdflush]
6 root SW [kupdated]
7 root SW [khubd]
18 root 668 S /sbin/syslogd -O /var/log/syslog -R vesta:514 -L
112 root 620 S /sbin/udhcpc -b -i wlan0 -s /etc/udhcpc.script
114 root 556 S /sbin/crond -c /var/crontab
116 root 648 S /sbin/inetd /etc/inetd.conf
118 root 524 S /sbin/httpd -c /etc/httpd.conf -h /var/www
122 root 512 S /sbin/getty -L ttyS0 115200 vt100
123 root 420 S /sbin/telnetd
124 root 684 S -sh
141 root 728 R ps ax
Utilisation du "Linux Embarqué"
Exemple simple de démonstration de notre carte Linux.
Utilisation du port parallèle comme interface i2c de type Velleman
Rajout d'un circuit i2c thermomètre DS1621.
Ce qui donne la fonction thermomètre (de luxe) à notre carte.
Pour gérer cette interface i2c, il nous faut
- charger les modules i2c suivants
Module Size Used by Not tainted i2c-velleman 1224 0 i2c-algo-bit 6932 1 [i2c-velleman] i2c-dev 3376 0 i2c-core 12868 0 [i2c-algo-bit i2c-dev]
Les modules à rajouter dans /etc/modules:
root@domix# cat /etc/modules #via-rhine prism2_usb i2c-dev i2c-velleman
- Copie du binaire i2c-detect
(package lm-sensors.)
- Création du device i2c
mknod /dev/i2c-0 c 89 0
- Vérification
root@domix# i2cdetect -l
i2c-0 i2c Velleman K8000 Bit-shift algorithm
root@domix# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n]
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: XX XX XX XX XX XX XX XX XX XX XX XX XX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 4f
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
70: XX XX XX XX XX XX XX XX
Le circuit DS1621 est détecté à l'adresse 04Fh.
Voici le source ds1621_domix.c du programme permettant d'accéder au DS1621.
Le programme lit toute les 60 secondes la t° fourni par le circuit DS1621 et l'envoi vers la syslog.
Aug 13 14:15:53 domix syslog.info -- MARK -- Aug 13 14:35:53 domix syslog.info -- MARK -- Aug 13 14:51:40 domix user.info ds1621[211]: Démarrage ... Aug 13 14:51:42 domix user.info ds1621[211]: Température: 19.2° Aug 13 14:52:42 domix user.info ds1621[211]: Température: 19.2° Aug 13 14:53:42 domix user.info ds1621[211]: Température: 19.3° Aug 13 14:54:42 domix user.info ds1621[211]: Température: 19.3° Aug 13 14:55:42 domix user.info ds1621[211]: Température: 19.3° Aug 13 14:55:53 domix syslog.info -- MARK -- Aug 13 14:56:42 domix user.info ds1621[211]: Température: 19.3°
Le daemon syslog de DomiX étant configuré pour renvoyer sa log sur le Linux Desktop "vesta", je la retouve dans sa log.
dan@vesta:kernel-i2c$ tail -20 /var/log/syslog Aug 13 14:58:10 domix ds1621[211]: Température: 19.3° Aug 13 14:58:26 vesta in.qpopper[20774]: connect from 192.168.0.210 (192.168.0.210) Aug 13 14:58:26 vesta in.qpopper[20774]: (v4.0.5) POP login by user "daniel" at (vesta) 192.168.0.210 [pop_log.c:244] Aug 13 14:59:01 vesta CRON[20848]: (pam_unix) session opened for user dan by (uid=0) Aug 13 14:59:01 vesta /USR/SBIN/CRON[20849]: (dan) CMD (/home/dan/bin/ws2300/maj-mysql2300.sh) Aug 13 14:59:05 vesta CRON[20848]: (pam_unix) session closed for user dan Aug 13 14:59:10 domix ds1621[211]: Température: 19.3° Aug 13 14:59:26 vesta in.qpopper[20905]: connect from 192.168.0.210 (192.168.0.210) Aug 13 14:59:26 vesta in.qpopper[20905]: (v4.0.5) POP login by user "daniel" at (vesta) 192.168.0.210 [pop_log.c:244] Aug 13 15:00:01 vesta CRON[21024]: (pam_unix) session opened for user dan by (uid=0) Aug 13 15:00:01 vesta CRON[21026]: (pam_unix) session opened for user dan by (uid=0) Aug 13 15:00:01 vesta /USR/SBIN/CRON[21027]: (dan) CMD (/home/dan/bin/ws2300/maj-mysql2300.sh) Aug 13 15:00:01 vesta /USR/SBIN/CRON[21025]: (dan) CMD (/home/dan/bin/ws2300/rrd/rrd-update-ws2300_2.pl) Aug 13 15:00:01 vesta CRON[21024]: (pam_unix) session closed for user dan Aug 13 15:00:05 vesta CRON[21026]: (pam_unix) session closed for user dan Aug 13 15:00:10 domix ds1621[211]: Température: 19.3° Aug 13 15:00:26 vesta in.qpopper[21079]: connect from 192.168.0.210 (192.168.0.210) Aug 13 15:00:26 vesta in.qpopper[21079]: (v4.0.5) POP login by user "daniel" at (vesta) 192.168.0.210 [pop_log.c:244] Aug 13 15:01:01 vesta CRON[21198]: (pam_unix) session opened for user dan by (uid=0) Aug 13 15:01:01 vesta /USR/SBIN/CRON[21199]: (dan) CMD (/home/dan/bin/ws2300/maj-mysql2300.sh)
Voici à quoi cela ressemble (cliquez pour agrandir):
Le montage (testé sur plaquette d'essais) est juste composé des 74LS125 et DS1621 reliés au port parallèle par 4 fils.
(Un fusible 100mA a été rajouté pour éviter de faire passer les 20A des 5V de l'alim. du PC en cas de court-circuit.)
Il existe de nombreux CI I2C comme les circuits eeprom (24C65), d'entrée/sortie (PCF8574), converstisseur analogique/numérique (PCF8591, MAX128), afficheur 4 digits (SAA1064), décodeur télétext (Saa5246) ...
Conclusion
Cela semble un peu lourd pour réaliser un simple thermomètre (un simple uControleur de type AT89C2051 ou PIC pouvait faire l'affaire)
Mais le but était de montrer la réalisation d'un ensemble électronique tournant sous Linux avec du matériel de récupération offrant de nombreuses interfaces sur l'extérieur (WIFI, RS232, USB, I2C) en utilisant des outils de développement gratuits et disponibles rapidement puisque l'architecture reste du i386.
10 août 2006
