X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Finclude%2Fmodules.h;h=d72813369ea6f0804559ae13449466536dc087d7;hb=58c7107eb0a5ae254c135f2eaa6263751f1ebe67;hp=68c797be22133feab5a4ae4350c75dda2ff7482b;hpb=95a7eaaa4a1065334125b65130866f8d1048ddb7;p=tpg%2Facess2.git diff --git a/Kernel/include/modules.h b/Kernel/include/modules.h index 68c797be..d7281336 100644 --- a/Kernel/include/modules.h +++ b/Kernel/include/modules.h @@ -2,35 +2,122 @@ * AcessOS 2 * - Module Loader */ +/** + * \file modules.h + * \brief Module Handling and Loader Definitions + * \author John Hodge (thePowersGang) + * + * This file serves two pourposes. First it defines the format for native + * Acess2 modules and the functions to create them. + * Second, it defines the structure and register function for new module + * loaders, allowing Acess to understand many different module / driver + * formats. + * + * Modules are defined by including this file in the module's main source + * file and using the ::MODULE_DEFINE macro to create the module header. + * + * To register a new module loader with the kernel, the loader module must + * create and populate an instance of ::tModuleLoader then pass it to + * ::Module_RegisterLoader + */ #ifndef _MODULE_H #define _MODULE_H +/** + * \brief Module header magic value + */ #define MODULE_MAGIC ('A'|('M'<<8)|('D'<<16)|('\2'<<24)) +/** + * \def MODULE_ARCH_ID + * \brief Architecture ID + */ // IA32 - Architecture 1 -#if ARCH == i386 || ARCH == i586 +#if ARCHDIR == x86 # define MODULE_ARCH_ID 1 // IA64 - Architecture 2 -#elif ARCH == x64 || ARCH == x86_64 +#elif ARCHDIR == x86_64 # define MODULE_ARCH_ID 2 #else -# error "Unknown architecture when determining MODULE_ARCH_ID ('" #ARCH "')" +# error "Unknown architecture when determining MODULE_ARCH_ID ('" #ARCHDIR "')" #endif -#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deinit,_deps...) char *_DriverDeps_##_ident[]={_deps};\ - tModule __attribute__ ((section ("KMODULES"),unused)) _DriverInfo_##_ident=\ - {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,#_ident,_entry,_deinit,_DriverDeps_##_ident} - -typedef struct sModule { - Uint32 Magic; - Uint8 Arch; - Uint8 Flags; - Uint16 Version; - struct sModule *Next; - char *Name; - int (*Init)(char **Arguments); - void (*Deinit)(); - char **Dependencies; // NULL Terminated List -} __attribute__((packed)) tModule; +/** + * \brief Define a module + * \param _flags Module Flags + * \param _ver Module Version + * \param _ident Unique Module Name + * \param _entry Module initialiser / entrypoint + * \param _deinit Module cleanup / unloader + * \param _deps NULL terminated list of this's module's dependencies + * Contains the identifiers of the required modules. + */ +#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deinit,_deps...) \ + const char *EXPAND_CONCAT(_DriverDeps_,_ident)[]={_deps};\ + tModule __attribute__ ((section ("KMODULES"),unused))\ + EXPAND_CONCAT(_DriverInfo_,_ident)=\ + {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,EXPAND_STR(_ident),\ + _entry,_deinit,EXPAND_CONCAT(_DriverDeps_,_ident)} + +/** + * \brief Module header + * \note There is no reason for a module to touch this structure beyond + * using ::MODULE_DEFINE to create it. + */ +typedef struct sModule +{ + Uint32 Magic; //!< Identifying magic value (See ::MODULE_MAGIC) + Uint8 Arch; //!< Achitecture ID (See ::MODULE_ARCH_ID) + Uint8 Flags; //!< Module Flags + Uint16 Version; //!< Module Version in Major.Minor 8.8 form + struct sModule *Next; //!< Next module in list (not to be touched by the driver) + const char *Name; //!< Module Name/Identifier + int (*Init)(char **Arguments); //!< Module initialiser / entrypoint + void (*Deinit)(void); //!< Cleanup Function + const char **Dependencies; //!< NULL terminated list of dependencies +} PACKED tModule; + +/** + * \brief Return values for tModule.Init + */ +enum eModuleErrors +{ + MODULE_ERR_OK, //!< No Error + MODULE_ERR_MISC, //!< Misc Error + MODULE_ERR_NOTNEEDED, //!< Module not needed + MODULE_ERR_MALLOC, //!< Error with malloc/realloc/calloc + + MODULE_ERR_BADMODULE, //!< Bad module (only used by loader) + MODULE_ERR_MAX //!< Maximum defined error code +}; + +/** + * \brief Module Loader definition + * + * Allows a module to extend the loader to recognise other module types + * E.g. EDI, UDI, Windows, Linux, ... + */ +typedef struct sModuleLoader +{ + struct sModuleLoader *Next; //!< Kernel Only - Next loader in list + char *Name; //!< Friendly name for the loader + int (*Detector)(void *Base); //!< Simple detector function + int (*Loader)(void *Base); //!< Initialises the module + int (*Unloader)(void *Base); //!< Calls module's cleanup +} PACKED tModuleLoader; + +/** + * \brief Registers a tModuleLoader with the kernel + * \param Loader Pointer to loader structure (must be persistent) + * \return Boolean Success + */ +extern int Module_RegisterLoader(tModuleLoader *Loader); + +/** + * \brief Initialises (if needed) a named module + * \param Name Module name to initialise + * \return -1 on not existing, 0 if the module initialised (or if it was already initialised) + */ +extern int Module_EnsureLoaded(const char *Name); #endif