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


Administration wiki