Este documento apresenta como é o processo de desenvolvimento de um módulo executável (um programa).
Um módulo executável não implementa nenhuma interface e também não fornece funções para outros módulos. Na verdade, é ele que deve usar os módulos biblioteca e os módulos do sistema para fazer algo de útil.
O desenvolvimento de um módulo executável é como o desenvolvimento de um programa em C nos outros sistemas operacionais, com duas particularidades.
A primeira está relacionada com o utilitário que converte os arquivos .o (ELF), gerados pelo compilador GCC, para arquivo de módulo executável. A função que inicia o programa (função main nos programas em C) deve ter um atributo especial. Por exemplo:
void main(int argc, char *argv[], char *envp[]) __attribute__ ((section (".init"))); void main(int argc, char *argv[], char *envp[]) { ... meu código ... }
Esse atributo diz para colocar a função main do exemplo na seção .init do arquivo ELF.
A segunda peculiaridade está relacionada com o uso de módulos biblioteca. Todos os módulos biblioteca usados pelo módulo executável devem ser iniciados antes de serem utilizados e terminados antes do módulo executável terminar.
Um exemplo de módulo executável que usa duas interfaces do usuário:
#include "intermanager.h" #include "usermodmanager.h" #include "textvideo.h" #include "lib/memmanager.h" #include "lib/stringman.h" int (*TV_Write)(const char*); void main(void) __attribute__ ((section (".init"))); void StartLibs(void) { unsigned int i; int (*start)(void); i = 0; while ((start = UserModManager_UGetStartFunctionI(i++))) { if ((unsigned int)start != 0xffffffff && start()) { TV_Write("Error starting lib.\n"); UserModManager_UExit(2); } } } void ShutdownLibs(void) { unsigned int i; int (*shutdown)(void); i = 0; while ((shutdown = UserModManager_UGetShutdownFunctionI(i++))) { if ((unsigned int)shutdown != 0xffffffff && shutdown()) { TV_Write("Error stoping lib.\n"); } } } int GetTVFunction(void) { int ret; char outBuf[256]; InterManager_OutputInfo *outInfo; /* get TextVideo functions */ outInfo = (InterManager_OutputInfo*)outBuf; ret = InterManager_UGetOutputInfo(outInfo, sizeof(outBuf)); if (ret) { return ret; } return UserModManager_UGetFunction(outInfo->names, outInfo->names+outInfo->interSize, TextVideo__UWRITE, UserModManager_SYS_FUNCTION, (void**)&TV_Write); } void main(void) { if (GetTVFunction()) { UserModManager_UExit(1); } StartLibs(); ... meu código ... ShutdownLibs(); UserModManager_UExit(0); }
Como se nota as bibliotecas são iniciadas e no final são terminadas.