Linux Embedded

Le blog des technologies libres et embarquées

Utiliser Kconfig dans ses projets

Lorsqu'un projet gagne en ampleur et se diversifie, de plus en plus de directives de compilation apparaissent (#ifdef, ...). Il devient alors difficile de savoir quelle action effectue chaque directive surtout si elles ont des dépendances entre elles.

L'exemple typique est la compilation d'un noyau linux. En effet, le noyau 3.8.0 contient plus de 4000 symboles. Heureusement, il existe une interface simple permettant la configuration de ces symboles. Elle est appelée par la commande

make menuconfig

make menuconfig

Nous allons voir ici comment utiliser cette même interface pour nos propres projets.

L'utilitaire kconfig présent dans le noyau linux n'existe pas en tant que projet autonome. Pour pouvoir l'utiliser, il faut soit l'extraire des sources du kernel, soit faire appel à des projets qui ont fait ce travail pour nous. C'est cette deuxième solution qui a été choisie pour cet article.

Le projet kconfig-frontends (http://ymorin.is-a-geek.org/projects/kconfig-frontends) extrait des sources du kernel l'utilitaire kconfig et adapte le système de build. L'intérêt de ce projet par rapport à un autre est que le code est régulièrement réaligné sur les releases du kernel.

Afin de profiter de toutes les interfaces graphiques offertes par cet utilitaire, il faut au préalable installer les dépendances suivantes: ncurses et qt4.

Une fois l'archive téléchargée (depuis http://ymorin.is-a-geek.org/download/kconfig-frontends/) et extraite, il suffit de faire:

$> ./configure && make

On retrouve les différents utilitaires dans le répertoire frontends/:

  • conf configuration en ligne
  • mconf configuration à travers une interface ncurses
  • qconf configuration à travers une interface graphique

On peut donc ajouter les règles suivantes dans le Makefile:

.PHONY: menuconfig
menuconfig:
   ifneq ($(MCONF),)
   $(MCONF) Kconfig
endif

.PHONY: config
config:
ifneq ($(CONF),)
   mkdir -p include/
   mkdir -p include/config include/generated
   $(CONF) --silentoldconfig Kconfig
endif

La règle menuconfig va appeler l'utilitaire mconf et générera un fichier .config.

La règle config va appeller l'utilitaire conf. Avec l'option --silentoldconfig, cet utilitaire va traduire le fichier .config en un fichier include/generated/autoconf.h. (NOTE: il est possible de changer le nom et l'emplacement de ce fichier en exportant la variable KCONFIG_AUTOHEADER).

Le fichier autoconf contient une suite de #define représentant la configuration choisie.

Attention! Tous les symboles définis dans le fichier Kconfig seront préfixés par CONFIG_

/*
*
* Automatically generated file; DO NOT EDIT.
* Linux/i386 3.8.0-rc3 Kernel Configuration
*
*/
#define CONFIG_HAVE_ARCH_SECCOMP_FILTER 1
#define CONFIG_KERNEL_GZIP 1
#define CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK 1
#define CONFIG_INOTIFY_USER 1
#define CONFIG_X86_MINIMUM_CPU_FAMILY 5
#define CONFIG_X86_TSC 1
#define CONFIG_ARCH_SUSPEND_POSSIBLE 1
#define CONFIG_HAVE_KERNEL_BZIP2 1
#define CONFIG_UEVENT_HELPER_PATH ""
#define CONFIG_STEP_WISE 1

Il ne reste plus qu'à inclure ce fichier dans vos sources.

Le dernier aspect de cet article concerne l'écriture des fichiers Kconfig.

La syntaxe de ces fichiers est décrite dans la Documentation du noyau linux.

Les principales commandes sont

  • source Importe un autre Kconfig
    source "submodule1/kconfig"
    source "submodule2/kconfig"
  • config Créer une entrée
    config MY_SYMBOL
  • menu Créer une sous section. Le contenu sera affiché dans une nouvelle page.
    menu "DEBUG option"
    config DEBUG_OPTION1
    config DEBUG_OPTION2
    endmenu
  • choice Permet de sélectionner une valeur
    choice "Do a choice"
    config CHOICE_1
    config CHOICE_2
    endchoice

Les entrées peuvent être de différents types:

  • bool Booléen
  • string Une chaine de caractères
  • hex Une valeur hexadécimale
  • int Une valeur entière
  • tristate Peut valoir 'n', 'y' ou 'm'. Ce type est principalement utilisé dans la configuration du kernel: non, statique ou module

Chaque entrée peut également avoir plusieurs options:

  • prompt Label qui sera affiché pour ce symbole
  • help Texte qui sera affiché lors de la demande d'aide sur ce symbole
  • default Valeur par défaut du symbole
  • range Intervalle de valeur pour des entrées de type hex ou int
  • depends on Cette entrée ne sera affichée que si la dépendance est vérifiée
  • select Force une valeur pour un autre symbole (dépendance inverse) A utiliser avec précaution!

Il est également possible d'effectuer un affichage conditionnel suivant la valeur des symboles:

if FOO
  config BAR
  bool
  prompt "about BAR"
endif

Je terminerai cet article par un exemple de fichier Kconfig:

# un commentaire

config BASE_ADDR
hex
prompt "Base address"

menu "Duration config"

choice "Time unit"
config TIME_MS
bool
prompt "Time in ms"

config TIME_S
bool
prompt "Time in s"

endchoice

config MAIN_LOOP
int
default 10
prompt "Duration of main loop"
help
Set the duration of main loop.
The unit is defined in Time unit

config OTHER_LOOP
int
prompt "Duration of other loop"

endmenu

menu "Debug option"
config DEBUG
bool
prompt "Allow debug"

config DEBUG_WARNING
bool
prompt "Debug warning"
depends on DEBUG

endmenu

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.