OS modules: Add basic procfs support. A module registry that will eventually be used to support lsmod
This commit is contained in:
parent
a908a61c5a
commit
795ddd7e80
@ -11237,5 +11237,6 @@
|
||||
just the ELF module support with name changes (2015-12-10).
|
||||
* configs/samv71-xult/module: Add configuration for testing OS
|
||||
modules (2015-12-12).
|
||||
* sched/module: Add an implementation of rmmod() (2015-11-12).
|
||||
|
||||
* sched/module: Add an implementation of rmmod() (2015-12-12).
|
||||
* sched/module and fs/procfs: Add some basic module procfs support
|
||||
(2015-12-12),
|
||||
|
2
configs
2
configs
@ -1 +1 @@
|
||||
Subproject commit 050dca048e92cec8f8d04075553d75025a31f2d4
|
||||
Subproject commit 4a56b7ba643607bbfadaef3628a7322b642ffa3f
|
@ -32,6 +32,13 @@ config FS_PROCFS_EXCLUDE_PROCESS
|
||||
This will reduce code space, but then giving access to process info
|
||||
was kinda the whole point of procfs, but hey, whatever.
|
||||
|
||||
config FS_PROCFS_EXCLUDE_MODULE
|
||||
bool "Exclude module information"
|
||||
depends on MODULE
|
||||
default n
|
||||
---help---
|
||||
Causes the module information to be excluded from the procfs system.
|
||||
|
||||
config FS_PROCFS_EXCLUDE_UPTIME
|
||||
bool "Exclude uptime"
|
||||
default n
|
||||
|
@ -77,6 +77,7 @@
|
||||
|
||||
extern const struct procfs_operations proc_operations;
|
||||
extern const struct procfs_operations cpuload_operations;
|
||||
extern const struct procfs_operations module_operations;
|
||||
extern const struct procfs_operations uptime_operations;
|
||||
|
||||
/* This is not good. These are implemented in other sub-systems. Having to
|
||||
@ -119,6 +120,10 @@ static const struct procfs_entry_s g_procfs_entries[] =
|
||||
{ "cpuload", &cpuload_operations },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MODULE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
|
||||
{ "modules", &module_operations },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FS_SMARTFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
|
||||
//{ "fs/smartfs", &smartfs_procfsoperations },
|
||||
{ "fs/smartfs**", &smartfs_procfsoperations },
|
||||
|
@ -60,10 +60,6 @@
|
||||
# define CONFIG_MODULE_ALIGN_LOG2 2
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MODULE_STACKSIZE
|
||||
# define CONFIG_MODULE_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MODULE_BUFFERSIZE
|
||||
# define CONFIG_MODULE_BUFFERSIZE 128
|
||||
#endif
|
||||
@ -72,6 +68,8 @@
|
||||
# define CONFIG_MODULE_BUFFERINCR 32
|
||||
#endif
|
||||
|
||||
#define MODULENAME_MAX 16
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -114,25 +112,12 @@ typedef CODE int (*mod_uninitializer_t)(FAR void *arg);
|
||||
typedef CODE int (*mod_initializer_t)(mod_uninitializer_t *uninitializer,
|
||||
FAR void **arg);
|
||||
|
||||
/* This describes the file to be loaded. */
|
||||
#ifdef __KERNEL__
|
||||
/* This is the type of the callback function used by mod_registry_foreach() */
|
||||
|
||||
struct symtab_s;
|
||||
struct module_s
|
||||
{
|
||||
/* Information provided to insmod by the caller */
|
||||
|
||||
FAR const char *filename; /* Full path to the binary to be loaded */
|
||||
FAR const struct symtab_s *exports; /* Table of exported symbols */
|
||||
int nexports; /* The number of symbols in exports[] */
|
||||
|
||||
/* Information provided from insmod (if successful) describing the
|
||||
* resources used by the loaded module.
|
||||
*/
|
||||
|
||||
mod_uninitializer_t uninitializer; /* Module uninitializer function */
|
||||
FAR void *arg; /* Uninitializer argument */
|
||||
FAR void *alloc; /* Allocated kernel memory */
|
||||
};
|
||||
struct module_s;
|
||||
typedef CODE int (*mod_callback_t)(FAR struct module_s *modp, FAR void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
@ -154,9 +139,22 @@ extern "C"
|
||||
* Verify that the file is an ELF module binary and, if so, load the
|
||||
* module into kernel memory and initialize it for use.
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* filename - Full path to the module binary to be loaded
|
||||
* modulename - The name that can be used to refer to the module after
|
||||
* it has been loaded.
|
||||
* exports - Table of exported symbols
|
||||
* nexports - The number of symbols in exports[]
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. On any failure, -1 (ERROR) is returned the
|
||||
* errno value is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int insmod(FAR struct module_s *modp);
|
||||
int insmod(FAR const char *filename, FAR const char *modulename,
|
||||
FAR const struct symtab_s *exports, int nexports);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rmmod
|
||||
@ -164,9 +162,44 @@ int insmod(FAR struct module_s *modp);
|
||||
* Description:
|
||||
* Remove a previously installed module from memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* modulename - The module name. This is the name module name that was
|
||||
* provided to insmod when the module was loaded.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. On any failure, -1 (ERROR) is returned the
|
||||
* errno value is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rmmod(FAR struct module_s *modp);
|
||||
int rmmod(FAR const char *modulename);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_foreach
|
||||
*
|
||||
* Description:
|
||||
* Visit each module in the registry. This is an internal OS interface and
|
||||
* not available for use by applications.
|
||||
*
|
||||
* Input Parameters:
|
||||
* callback - This callback function was be called for each entry in the
|
||||
* registry.
|
||||
* arg - This opaque argument will be passed to the callback function.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function normally returns zero (OK). If, however, any callback
|
||||
* function returns a non-zero value, the traversal will be terminated and
|
||||
* that non-zero value will be returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller does NOT hold the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
int mod_registry_foreach(mod_callback_t callback, FAR void *arg);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
@ -60,10 +60,6 @@
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* This enumeration identifies all of the thread attributes that can be
|
||||
* accessed via the procfs file system.
|
||||
*/
|
||||
|
||||
/* This structure describes one open "file" */
|
||||
|
||||
struct net_driver_s; /* Forward reference */
|
||||
|
@ -42,8 +42,16 @@ CSRCS += mod_insmod.c mod_rmmod.c
|
||||
# loadable module library
|
||||
|
||||
CSRCS += mod_bind.c mod_init.c mod_iobuffer.c mod_load.c mod_read.c
|
||||
CSRCS += mod_sections.c mod_symbols.c mod_uninit.c mod_unload.c
|
||||
CSRCS += mod_verify.c
|
||||
CSRCS += mod_registry.c mod_sections.c mod_symbols.c mod_uninit.c
|
||||
CSRCS += mod_unload.c mod_verify.c
|
||||
|
||||
# procfs support
|
||||
|
||||
ifeq ($(CONFIG_FS_PROCFS),y)
|
||||
ifneq ($(CONFIG_FS_PROCFS_EXCLUDE_MODULE),y)
|
||||
CSRCS += mod_procfs.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# Hook the module subdirectory into the build
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
|
||||
#include "module/module.h"
|
||||
@ -66,7 +67,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MODULE_DUMPBUFFER
|
||||
# define mod_dumpbuffer(m,b,n) bvdbgdumpbuffer(m,b,n)
|
||||
# define mod_dumpbuffer(m,b,n) svdbgdumpbuffer(m,b,n)
|
||||
#else
|
||||
# define mod_dumpbuffer(m,b,n)
|
||||
#endif
|
||||
@ -88,50 +89,50 @@ static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
bdbg("LOAD_INFO:\n");
|
||||
bdbg(" textalloc: %08lx\n", (long)loadinfo->textalloc);
|
||||
bdbg(" datastart: %08lx\n", (long)loadinfo->datastart);
|
||||
bdbg(" textsize: %ld\n", (long)loadinfo->textsize);
|
||||
bdbg(" datasize: %ld\n", (long)loadinfo->datasize);
|
||||
bdbg(" filelen: %ld\n", (long)loadinfo->filelen);
|
||||
bdbg(" filfd: %d\n", loadinfo->filfd);
|
||||
bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
|
||||
bdbg(" strtabidx: %d\n", loadinfo->strtabidx);
|
||||
sdbg("LOAD_INFO:\n");
|
||||
sdbg(" textalloc: %08lx\n", (long)loadinfo->textalloc);
|
||||
sdbg(" datastart: %08lx\n", (long)loadinfo->datastart);
|
||||
sdbg(" textsize: %ld\n", (long)loadinfo->textsize);
|
||||
sdbg(" datasize: %ld\n", (long)loadinfo->datasize);
|
||||
sdbg(" filelen: %ld\n", (long)loadinfo->filelen);
|
||||
sdbg(" filfd: %d\n", loadinfo->filfd);
|
||||
sdbg(" symtabidx: %d\n", loadinfo->symtabidx);
|
||||
sdbg(" strtabidx: %d\n", loadinfo->strtabidx);
|
||||
|
||||
bdbg("ELF Header:\n");
|
||||
bdbg(" e_ident: %02x %02x %02x %02x\n",
|
||||
sdbg("ELF Header:\n");
|
||||
sdbg(" e_ident: %02x %02x %02x %02x\n",
|
||||
loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1],
|
||||
loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]);
|
||||
bdbg(" e_type: %04x\n", loadinfo->ehdr.e_type);
|
||||
bdbg(" e_machine: %04x\n", loadinfo->ehdr.e_machine);
|
||||
bdbg(" e_version: %08x\n", loadinfo->ehdr.e_version);
|
||||
bdbg(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry);
|
||||
bdbg(" e_phoff: %d\n", loadinfo->ehdr.e_phoff);
|
||||
bdbg(" e_shoff: %d\n", loadinfo->ehdr.e_shoff);
|
||||
bdbg(" e_flags: %08x\n" , loadinfo->ehdr.e_flags);
|
||||
bdbg(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize);
|
||||
bdbg(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize);
|
||||
bdbg(" e_phnum: %d\n", loadinfo->ehdr.e_phnum);
|
||||
bdbg(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize);
|
||||
bdbg(" e_shnum: %d\n", loadinfo->ehdr.e_shnum);
|
||||
bdbg(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx);
|
||||
sdbg(" e_type: %04x\n", loadinfo->ehdr.e_type);
|
||||
sdbg(" e_machine: %04x\n", loadinfo->ehdr.e_machine);
|
||||
sdbg(" e_version: %08x\n", loadinfo->ehdr.e_version);
|
||||
sdbg(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry);
|
||||
sdbg(" e_phoff: %d\n", loadinfo->ehdr.e_phoff);
|
||||
sdbg(" e_shoff: %d\n", loadinfo->ehdr.e_shoff);
|
||||
sdbg(" e_flags: %08x\n" , loadinfo->ehdr.e_flags);
|
||||
sdbg(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize);
|
||||
sdbg(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize);
|
||||
sdbg(" e_phnum: %d\n", loadinfo->ehdr.e_phnum);
|
||||
sdbg(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize);
|
||||
sdbg(" e_shnum: %d\n", loadinfo->ehdr.e_shnum);
|
||||
sdbg(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx);
|
||||
|
||||
if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0)
|
||||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||
bdbg("Sections %d:\n", i);
|
||||
bdbg(" sh_name: %08x\n", shdr->sh_name);
|
||||
bdbg(" sh_type: %08x\n", shdr->sh_type);
|
||||
bdbg(" sh_flags: %08x\n", shdr->sh_flags);
|
||||
bdbg(" sh_addr: %08x\n", shdr->sh_addr);
|
||||
bdbg(" sh_offset: %d\n", shdr->sh_offset);
|
||||
bdbg(" sh_size: %d\n", shdr->sh_size);
|
||||
bdbg(" sh_link: %d\n", shdr->sh_link);
|
||||
bdbg(" sh_info: %d\n", shdr->sh_info);
|
||||
bdbg(" sh_addralign: %d\n", shdr->sh_addralign);
|
||||
bdbg(" sh_entsize: %d\n", shdr->sh_entsize);
|
||||
sdbg("Sections %d:\n", i);
|
||||
sdbg(" sh_name: %08x\n", shdr->sh_name);
|
||||
sdbg(" sh_type: %08x\n", shdr->sh_type);
|
||||
sdbg(" sh_flags: %08x\n", shdr->sh_flags);
|
||||
sdbg(" sh_addr: %08x\n", shdr->sh_addr);
|
||||
sdbg(" sh_offset: %d\n", shdr->sh_offset);
|
||||
sdbg(" sh_size: %d\n", shdr->sh_size);
|
||||
sdbg(" sh_link: %d\n", shdr->sh_link);
|
||||
sdbg(" sh_info: %d\n", shdr->sh_info);
|
||||
sdbg(" sh_addralign: %d\n", shdr->sh_addralign);
|
||||
sdbg(" sh_entsize: %d\n", shdr->sh_entsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,49 +166,90 @@ static void mod_dumpinitializer(mod_initializer_t initializer,
|
||||
* Verify that the file is an ELF module binary and, if so, load the
|
||||
* module into kernel memory and initialize it for use.
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* filename - Full path to the module binary to be loaded
|
||||
* modulename - The name that can be used to refer to the module after
|
||||
* it has been loaded.
|
||||
* exports - Table of exported symbols
|
||||
* nexports - The number of symbols in exports[]
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. On any failure, -1 (ERROR) is returned the
|
||||
* errno value is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int insmod(FAR struct module_s *modp)
|
||||
int insmod(FAR const char *filename, FAR const char *modulename,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
struct mod_loadinfo_s loadinfo;
|
||||
FAR struct module_s *modp;
|
||||
mod_initializer_t initializer;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(modp != NULL && modp->filename != NULL);
|
||||
bvdbg("Loading file: %s\n", modp->filename);
|
||||
DEBUGASSERT(filename != NULL && modulename != NULL);
|
||||
svdbg("Loading file: %s\n", filename);
|
||||
|
||||
/* Get exclusive access to the module registry */
|
||||
|
||||
mod_registry_lock();
|
||||
|
||||
/* Check if this module is already installed */
|
||||
|
||||
if (mod_registry_find(modulename) != NULL)
|
||||
{
|
||||
mod_registry_unlock();
|
||||
ret = -EEXIST;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Initialize the ELF library to load the program binary. */
|
||||
|
||||
ret = mod_initialize(modp->filename, &loadinfo);
|
||||
ret = mod_initialize(filename, &loadinfo);
|
||||
mod_dumploadinfo(&loadinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
bdbg("Failed to initialize for load of ELF program: %d\n", ret);
|
||||
goto errout;
|
||||
sdbg("ERROR: Failed to initialize to load module: %d\n", ret);
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Allocate a module registry entry to hold the module data */
|
||||
|
||||
modp = (FAR struct module_s *)kmm_zalloc(sizeof(struct module_s));
|
||||
if (ret != 0)
|
||||
{
|
||||
sdbg("Failed to initialize for load of ELF program: %d\n", ret);
|
||||
goto errout_with_loadinfo;
|
||||
}
|
||||
|
||||
/* Save the module name in the registry entry */
|
||||
|
||||
strncpy(modp->modulename, modulename, MODULENAME_MAX);
|
||||
|
||||
/* Load the program binary */
|
||||
|
||||
ret = mod_load(&loadinfo);
|
||||
mod_dumploadinfo(&loadinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
bdbg("Failed to load ELF program binary: %d\n", ret);
|
||||
goto errout_with_init;
|
||||
sdbg("Failed to load ELF program binary: %d\n", ret);
|
||||
goto errout_with_registry_entry;
|
||||
}
|
||||
|
||||
/* Bind the program to the exported symbol table */
|
||||
|
||||
ret = mod_bind(&loadinfo, modp->exports, modp->nexports);
|
||||
ret = mod_bind(&loadinfo, exports, nexports);
|
||||
if (ret != 0)
|
||||
{
|
||||
bdbg("Failed to bind symbols program binary: %d\n", ret);
|
||||
sdbg("Failed to bind symbols program binary: %d\n", ret);
|
||||
goto errout_with_load;
|
||||
}
|
||||
|
||||
/* Return the load information */
|
||||
|
||||
modp->alloc = (FAR void *)loadinfo.textalloc;
|
||||
modp->size = loadinfo.textsize + loadinfo.datasize;
|
||||
|
||||
/* Get the module initializer entry point */
|
||||
|
||||
@ -219,19 +261,28 @@ int insmod(FAR struct module_s *modp)
|
||||
ret = initializer(&modp->uninitializer, &modp->arg);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to initialize the module: %d\n", ret);
|
||||
sdbg("Failed to initialize the module: %d\n", ret);
|
||||
goto errout_with_load;
|
||||
}
|
||||
|
||||
/* Add the new module entry to the registry */
|
||||
|
||||
mod_registry_add(modp);
|
||||
|
||||
mod_uninitialize(&loadinfo);
|
||||
mod_registry_unlock();
|
||||
return OK;
|
||||
|
||||
errout_with_load:
|
||||
mod_unload(&loadinfo);
|
||||
errout_with_init:
|
||||
errout_with_registry_entry:
|
||||
kmm_free(modp);
|
||||
errout_with_loadinfo:
|
||||
mod_uninitialize(&loadinfo);
|
||||
errout:
|
||||
return ret;
|
||||
errout_with_lock:
|
||||
mod_registry_unlock();
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MODULE */
|
||||
|
320
sched/module/mod_procfs.c
Normal file
320
sched/module/mod_procfs.c
Normal file
@ -0,0 +1,320 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_procfs.c
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
|
||||
#include "module.h"
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \
|
||||
!defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Determines the size of an intermediate buffer that must be large enough
|
||||
* to handle the longest line generated by this logic.
|
||||
*/
|
||||
|
||||
#define MOD_LINELEN 64
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure describes one open "file" */
|
||||
|
||||
struct modprocfs_file_s
|
||||
{
|
||||
struct procfs_file_s base; /* Base open file structure */
|
||||
|
||||
/* Read helpers */
|
||||
|
||||
FAR char *buffer; /* User buffer pointer */
|
||||
size_t buflen; /* Size of the user buffer */
|
||||
size_t remaining; /* Space remaining in user buffer */
|
||||
size_t totalsize; /* Total size returned by read() */
|
||||
off_t offset; /* Offset skip on output */
|
||||
|
||||
/* Line buffer */
|
||||
|
||||
uint8_t lineno; /* Line number */
|
||||
uint8_t linesize; /* Number of valid characters in line[] */
|
||||
char line[MOD_LINELEN]; /* Pre-allocated buffer for formatted lines */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* File system methods */
|
||||
|
||||
static int modprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode);
|
||||
static int modprocfs_close(FAR struct file *filep);
|
||||
static ssize_t modprocfs_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static int modprocfs_dup(FAR const struct file *oldp,
|
||||
FAR struct file *newp);
|
||||
static int modprocfs_stat(FAR const char *relpath, FAR struct stat *buf);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* See include/nutts/fs/procfs.h
|
||||
* We use the old-fashioned kind of initializers so that this will compile
|
||||
* with any compiler.
|
||||
*/
|
||||
|
||||
const struct procfs_operations module_operations =
|
||||
{
|
||||
modprocfs_open, /* open */
|
||||
modprocfs_close, /* close */
|
||||
modprocfs_read, /* read */
|
||||
NULL, /* write */
|
||||
modprocfs_dup, /* dup */
|
||||
|
||||
NULL, /* opendir */
|
||||
NULL, /* closedir */
|
||||
NULL, /* readdir */
|
||||
NULL, /* rewinddir */
|
||||
|
||||
modprocfs_stat /* stat */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_callback
|
||||
****************************************************************************/
|
||||
|
||||
static int modprocfs_callback(FAR struct module_s *modp, FAR void *arg)
|
||||
{
|
||||
FAR struct modprocfs_file_s *priv;
|
||||
size_t linesize;
|
||||
size_t copysize;
|
||||
|
||||
DEBUGASSERT(modp != NULL && arg != NULL);
|
||||
priv = (FAR struct modprocfs_file_s *)arg;
|
||||
|
||||
linesize = snprintf(priv->line, MOD_LINELEN, "%s,%p,%p,%p,%lu\n",
|
||||
modp->modulename, modp->uninitializer, modp->arg,
|
||||
modp->alloc, (unsigned long)modp->size);
|
||||
copysize = procfs_memcpy(priv->line, linesize, priv->buffer,
|
||||
priv->remaining, &priv->offset);
|
||||
priv->totalsize += copysize;
|
||||
priv->buffer += copysize;
|
||||
priv->remaining -= copysize;
|
||||
|
||||
return (priv->totalsize >= priv->buflen) ? 1 : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_open
|
||||
****************************************************************************/
|
||||
|
||||
static int modprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode)
|
||||
{
|
||||
FAR struct modprocfs_file_s *priv;
|
||||
|
||||
fvdbg("Open '%s'\n", relpath);
|
||||
|
||||
/* PROCFS is read-only. Any attempt to open with any kind of write
|
||||
* access is not permitted.
|
||||
*
|
||||
* REVISIT: Write-able proc files could be quite useful.
|
||||
*/
|
||||
|
||||
if (((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0))
|
||||
{
|
||||
fdbg("ERROR: Only O_RDONLY supported\n");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* Allocate the open file structure */
|
||||
|
||||
priv = (FAR struct modprocfs_file_s *)kmm_zalloc(sizeof(struct modprocfs_file_s));
|
||||
if (!priv)
|
||||
{
|
||||
fdbg("ERROR: Failed to allocate file attributes\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the open file structure as the open-specific state in
|
||||
* filep->f_priv.
|
||||
*/
|
||||
|
||||
filep->f_priv = (FAR void *)priv;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_close
|
||||
****************************************************************************/
|
||||
|
||||
static int modprocfs_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct modprocfs_file_s *priv;
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
priv = (FAR struct modprocfs_file_s *)filep->f_priv;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Release the file attributes structure */
|
||||
|
||||
kmm_free(priv);
|
||||
filep->f_priv = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t modprocfs_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR struct modprocfs_file_s *priv;
|
||||
int ret;
|
||||
|
||||
fvdbg("buffer=%p buflen=%lu\n", buffer, (unsigned long)buflen);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
priv = (FAR struct modprocfs_file_s *)filep->f_priv;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Traverse all installed modules */
|
||||
|
||||
priv->remaining = buflen;
|
||||
priv->totalsize = 0;
|
||||
priv->buffer = buffer;
|
||||
priv->buflen = buflen;
|
||||
priv->offset = filep->f_pos;
|
||||
|
||||
ret = mod_registry_foreach(modprocfs_callback, priv);
|
||||
if (ret >= 0)
|
||||
{
|
||||
filep->f_pos += priv->totalsize;
|
||||
return priv->totalsize;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_dup
|
||||
*
|
||||
* Description:
|
||||
* Duplicate open file data in the new file structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int modprocfs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
{
|
||||
FAR struct modprocfs_file_s *oldpriv;
|
||||
FAR struct modprocfs_file_s *newpriv;
|
||||
|
||||
fvdbg("Dup %p->%p\n", oldp, newp);
|
||||
|
||||
/* Recover our private data from the old struct file instance */
|
||||
|
||||
oldpriv = (FAR struct modprocfs_file_s *)oldp->f_priv;
|
||||
DEBUGASSERT(oldpriv);
|
||||
|
||||
/* Allocate a new container to hold the task and attribute selection */
|
||||
|
||||
newpriv = (FAR struct modprocfs_file_s *)kmm_zalloc(sizeof(struct modprocfs_file_s));
|
||||
if (!newpriv)
|
||||
{
|
||||
fdbg("ERROR: Failed to allocate file attributes\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* The copy the file attribtes from the old attributes to the new */
|
||||
|
||||
memcpy(newpriv, oldpriv, sizeof(struct modprocfs_file_s));
|
||||
|
||||
/* Save the new attributes in the new file structure */
|
||||
|
||||
newp->f_priv = (FAR void *)newpriv;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modprocfs_stat
|
||||
*
|
||||
* Description: Return information about a file or directory
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int modprocfs_stat(FAR const char *relpath, FAR struct stat *buf)
|
||||
{
|
||||
memset(buf, 0, sizeof(struct stat));
|
||||
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&
|
||||
* !CONFIG_FS_PROCFS_EXCLUDE_MODULE */
|
247
sched/module/mod_registry.c
Normal file
247
sched/module/mod_registry.c
Normal file
@ -0,0 +1,247 @@
|
||||
/****************************************************************************
|
||||
* sched/module/mod_registry.c
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/module.h>
|
||||
|
||||
#include "module.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static sem_t g_mod_lock = SEM_INITIALIZER(1);
|
||||
static FAR struct module_s *g_mod_registry;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_lock
|
||||
*
|
||||
* Description:
|
||||
* Get exclusive access to the module registry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_lock(void)
|
||||
{
|
||||
while (sem_post(&g_mod_lock) < 0)
|
||||
{
|
||||
DEBUGASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_unlock
|
||||
*
|
||||
* Description:
|
||||
* Relinquish the lock on the module registry
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_unlock(void)
|
||||
{
|
||||
sem_post(&g_mod_lock);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_add
|
||||
*
|
||||
* Description:
|
||||
* Add a new entry to the module registry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - The module data structure to be registered.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_add(FAR struct module_s *modp)
|
||||
{
|
||||
DEBUGASSERT(modp);
|
||||
modp->flink = g_mod_registry;
|
||||
g_mod_registry = modp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_del
|
||||
*
|
||||
* Description:
|
||||
* Remove a module entry from the registry
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - The registry entry to be removed.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned if the registry entry was deleted. Otherwise,
|
||||
* a negated errno value is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_registry_del(FAR struct module_s *modp)
|
||||
{
|
||||
FAR struct module_s *prev;
|
||||
FAR struct module_s *curr;
|
||||
|
||||
for (prev = NULL, curr = g_mod_registry;
|
||||
curr != NULL && curr != modp;
|
||||
prev = curr, curr = curr->flink);
|
||||
|
||||
if (curr == NULL)
|
||||
{
|
||||
sdbg("ERROR: Could not find module entry\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
g_mod_registry = modp->flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->flink = modp->flink;
|
||||
}
|
||||
|
||||
modp->flink = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_find
|
||||
*
|
||||
* Description:
|
||||
* Find an entry in the module registry using the name of the module.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modulename - The name of the module to be found
|
||||
*
|
||||
* Returned Value:
|
||||
* If the registry entry is found, a pointer to the module entry is
|
||||
* returned. NULL is returned if the they entry is not found.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct module_s *mod_registry_find(FAR const char *modulename)
|
||||
{
|
||||
FAR struct module_s *modp;
|
||||
|
||||
for (modp = g_mod_registry;
|
||||
modp != NULL && strncmp(modp->modulename, modulename, MODULENAME_MAX) != 0;
|
||||
modp = modp->flink);
|
||||
|
||||
return modp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_foreach
|
||||
*
|
||||
* Description:
|
||||
* Visit each module in the registry
|
||||
*
|
||||
* Input Parameters:
|
||||
* callback - This callback function was be called for each entry in the
|
||||
* registry.
|
||||
* arg - This opaque argument will be passed to the callback function.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function normally returns zero (OK). If, however, any callback
|
||||
* function returns a non-zero value, the traversal will be terminated and
|
||||
* that non-zero value will be returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller does *NOT* hold the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_registry_foreach(mod_callback_t callback, FAR void *arg)
|
||||
{
|
||||
FAR struct module_s *modp;
|
||||
int ret;
|
||||
|
||||
/* Get exclusive access to the module registry */
|
||||
|
||||
mod_registry_lock();
|
||||
|
||||
/* Visit each installed module */
|
||||
|
||||
for (modp = g_mod_registry; modp != NULL; modp = modp->flink)
|
||||
{
|
||||
/* Perform the callback */
|
||||
|
||||
ret = callback(modp, arg);
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
mod_registry_unlock();
|
||||
return OK;
|
||||
}
|
@ -42,6 +42,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/module.h>
|
||||
@ -60,13 +61,37 @@
|
||||
* Description:
|
||||
* Remove a previously installed module from memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* modulename - The module name. This is the name module name that was
|
||||
* provided to insmod when the module was loaded.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. On any failure, -1 (ERROR) is returned the
|
||||
* errno value is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rmmod(FAR struct module_s *modp)
|
||||
int rmmod(FAR const char *modulename)
|
||||
{
|
||||
FAR struct module_s *modp;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(modp != NULL);
|
||||
DEBUGASSERT(modulename != NULL);
|
||||
|
||||
/* Get exclusive access to the module registry */
|
||||
|
||||
mod_registry_lock();
|
||||
|
||||
/* Find the module entry for this modulename in the registry */
|
||||
|
||||
modp = mod_registry_find(modulename);
|
||||
if (modp == NULL)
|
||||
{
|
||||
sdbg("ERROR: Failed to find module %s: %d\n", modulename, ret);
|
||||
ret = -ENOENT;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Is there an uninitializer? */
|
||||
|
||||
@ -81,7 +106,7 @@ int rmmod(FAR struct module_s *modp)
|
||||
if (ret < 0)
|
||||
{
|
||||
sdbg("ERROR: Failed to uninitialize the module: %d\n", ret);
|
||||
return ret;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Nullify so that the uninitializer cannot be called again */
|
||||
@ -92,7 +117,7 @@ int rmmod(FAR struct module_s *modp)
|
||||
|
||||
/* Release resources held by the module */
|
||||
|
||||
if (modp->alloc != 0)
|
||||
if (modp->alloc != NULL)
|
||||
{
|
||||
/* Free the module memory */
|
||||
|
||||
@ -101,9 +126,29 @@ int rmmod(FAR struct module_s *modp)
|
||||
/* Nullify so that the memory cannot be freed again */
|
||||
|
||||
modp->alloc = NULL;
|
||||
modp->size = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Remove the module from the registry */
|
||||
|
||||
ret = mod_registry_del(modp);
|
||||
if (ret < 0)
|
||||
{
|
||||
sdbg("ERROR: Failed to remove the module from the registry: %d\n", ret);
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
mod_registry_unlock();
|
||||
|
||||
/* And free the registry entry */
|
||||
|
||||
kmm_free(modp);
|
||||
return OK;
|
||||
|
||||
errout_with_lock:
|
||||
mod_registry_unlock();
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MODULE */
|
||||
|
@ -52,6 +52,19 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This describes the file to be loaded. */
|
||||
|
||||
struct symtab_s;
|
||||
struct module_s
|
||||
{
|
||||
FAR struct module_s *flink; /* Supports a singly linked list */
|
||||
FAR char modulename[MODULENAME_MAX]; /* Module name */
|
||||
mod_uninitializer_t uninitializer; /* Module uninitializer function */
|
||||
FAR void *arg; /* Uninitializer argument */
|
||||
FAR void *alloc; /* Allocated kernel memory */
|
||||
size_t size; /* Size of the kernel memory allocation */
|
||||
};
|
||||
|
||||
/* This struct provides a description of the currently loaded instantiation
|
||||
* of the kernel module.
|
||||
*/
|
||||
@ -332,4 +345,95 @@ int mod_allocbuffer(FAR struct mod_loadinfo_s *loadinfo);
|
||||
|
||||
int mod_reallocbuffer(FAR struct mod_loadinfo_s *loadinfo, size_t increment);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_lock
|
||||
*
|
||||
* Description:
|
||||
* Get exclusive access to the module registry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_lock(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_unlock
|
||||
*
|
||||
* Description:
|
||||
* Relinquish the lock on the module registry
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_unlock(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_add
|
||||
*
|
||||
* Description:
|
||||
* Add a new entry to the module registry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - The module data structure to be registered.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mod_registry_add(FAR struct module_s *modp);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_del
|
||||
*
|
||||
* Description:
|
||||
* Remove a module entry from the registry
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - The registry entry to be removed.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned if the registry entry was deleted. Otherwise,
|
||||
* a negated errno value is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mod_registry_del(FAR struct module_s *modp);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mod_registry_find
|
||||
*
|
||||
* Description:
|
||||
* Find an entry in the module registry using the name of the module.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modulename - The name of the module to be found
|
||||
*
|
||||
* Returned Value:
|
||||
* If the registry entry is found, a pointer to the module entry is
|
||||
* returned. NULL is returned if the they entry is not found.
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the lock on the module registry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct module_s *mod_registry_find(FAR const char *modulename);
|
||||
|
||||
#endif /* __SCHED_MODULE_MODULE_H */
|
||||
|
@ -28,7 +28,7 @@
|
||||
"getenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char*","FAR const char*"
|
||||
"getpid","unistd.h","","pid_t"
|
||||
"getsockopt","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int","FAR void*","FAR socklen_t*"
|
||||
"insmod","nuttx/module.h",defined(CONFIG_MODULE),"int","FAR struct module_s *"
|
||||
"insmod","nuttx/module.h",defined(CONFIG_MODULE),"int","FAR const char *","FAR const struct symtab_s *","int"
|
||||
"ioctl","sys/ioctl.h","!defined(CONFIG_LIBC_IOCTL_VARIADIC) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","int","int","unsigned long"
|
||||
"kill","signal.h","!defined(CONFIG_DISABLE_SIGNALS)","int","pid_t","int"
|
||||
"listen","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int"
|
||||
@ -98,7 +98,7 @@
|
||||
"rename","stdio.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*","FAR const char*"
|
||||
"rewinddir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","void","FAR DIR*"
|
||||
"rmdir","unistd.h","CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char*"
|
||||
"rmmod","nuttx/module.h",defined(CONFIG_MODULE),"int","FAR struct module_s *"
|
||||
"rmmod","nuttx/module.h",defined(CONFIG_MODULE),"int","FAR const char *"
|
||||
"sched_getparam","sched.h","","int","pid_t","struct sched_param*"
|
||||
"sched_getscheduler","sched.h","","int","pid_t"
|
||||
"sched_getstreams","nuttx/sched.h","CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0","FAR struct streamlist*"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -111,7 +111,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MODULE
|
||||
SYSCALL_LOOKUP(insmod, 1, STUB_insmod)
|
||||
SYSCALL_LOOKUP(insmod, 3, STUB_insmod)
|
||||
SYSCALL_LOOKUP(rmmod, 1, STUB_rmmod)
|
||||
#endif
|
||||
|
||||
|
@ -112,7 +112,8 @@ uintptr_t STUB_waitid(int nbr, uintptr_t parm1, uintptr_t parm2,
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MODULE
|
||||
uintptr_t STUB_insmod(int nbr, uintptr_t parm1);
|
||||
uintptr_t STUB_insmod(int nbr, uintptr_t parm1, uintptr_t parm2,
|
||||
uintptr_t parm3);
|
||||
uintptr_t STUB_rmmod(int nbr, uintptr_t parm1);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user