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.