SB-VFS integration working in the demo.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15280 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-12-29 16:00:10 +00:00
parent aac3849aa4
commit 6751fc38ee
9 changed files with 380 additions and 203 deletions

View File

@ -22,8 +22,42 @@
#include "rt_test_root.h" #include "rt_test_root.h"
#include "oslib_test_root.h" #include "oslib_test_root.h"
#include "nullstreams.h"
#include "startup_defs.h" #include "startup_defs.h"
/*===========================================================================*/
/* VFS-related. */
/*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
/* VFS FatFS driver object representing the root directory.*/
static vfs_fatfs_driver_c root_driver;
#endif
/* VFS overlay driver object representing the root directory.*/
static vfs_overlay_driver_c root_overlay_driver;
/* VFS streams driver object representing the /dev directory.*/
static vfs_streams_driver_c dev_driver;
/* VFS API will use this object as implicit root, defining this
symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
static NullStream nullstream;
/* Stream to be exposed under /dev as files.*/
static const drv_streams_element_t streams[] = {
{"VSD1", (BaseSequentialStream *)&LPSD1},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
/*===========================================================================*/
/* SB-related. */
/*===========================================================================*/
/* Sandbox 1 configuration.*/ /* Sandbox 1 configuration.*/
static const sb_config_t sb_config1 = { static const sb_config_t sb_config1 = {
.code_region = 0U, .code_region = 0U,
@ -52,9 +86,6 @@ static const sb_config_t sb_config1 = {
MPU_RASR_ENABLE MPU_RASR_ENABLE
} }
}, },
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
}; };
/* Sandbox 2 configuration.*/ /* Sandbox 2 configuration.*/
@ -85,16 +116,17 @@ static const sb_config_t sb_config2 = {
MPU_RASR_ENABLE MPU_RASR_ENABLE
} }
}, },
.stdin_stream = (SandboxStream *)&LPSD1,
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
}; };
/* Sandbox objects.*/ /* Sandbox objects.*/
sb_class_t sbx1, sbx2; sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 256); static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 256); static THD_WORKING_AREA(waUnprivileged2, 512);
/*===========================================================================*/
/* Main and generic code. */
/*===========================================================================*/
/* /*
* Green LED blinker thread, times are in milliseconds. * Green LED blinker thread, times are in milliseconds.
@ -118,6 +150,8 @@ int main(void) {
unsigned i = 1U; unsigned i = 1U;
thread_t *utp1, *utp2; thread_t *utp1, *utp2;
event_listener_t el1; event_listener_t el1;
vfs_file_node_c *fnp;
msg_t ret;
/* /*
* System initializations. * System initializations.
@ -125,29 +159,61 @@ int main(void) {
* and performs the board-specific initializations. * and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the * - Kernel initialization, the main() function becomes a thread and the
* RTOS is active. * RTOS is active.
* - Virtual File System initialization.
* - SandBox manager initialization. * - SandBox manager initialization.
*/ */
halInit(); halInit();
chSysInit(); chSysInit();
vfsInit();
sbHostInit(); sbHostInit();
/* /*
* Listening to sandbox events. * Starting a serial port for I/O, initializing other streams too.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Activates the Serial driver using the default configuration.
*/ */
sdStart(&LPSD1, NULL); sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream);
/* /*
* Creates the blinker thread. * Creating a blinker thread.
*/ */
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/*
* Initializing an overlay VFS object as a root, no overlaid driver,
* registering a streams VFS driver on the VFS overlay root as "/dev".
*/
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
ret = drvOverlayRegisterDriver(&root_overlay_driver,
drvStreamsObjectInit(&dev_driver, &streams[0]),
"dev");
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
/*
* Sandbox objects initialization.
*/
sbObjectInit(&sbx1, &sb_config1);
sbObjectInit(&sbx2, &sb_config2);
/*
* Associating standard input, output and error to sandboxes. Both sandboxes
* use the same serial port in this setup.
*/
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
vfsCloseFile(fnp);
/* Starting sandboxed thread 1.*/ /* Starting sandboxed thread 1.*/
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1", utp1 = sbStartThread(&sbx1, "sbx1",
waUnprivileged1, sizeof (waUnprivileged1), waUnprivileged1, sizeof (waUnprivileged1),
NORMALPRIO - 1); NORMALPRIO - 1);
if (utp1 == NULL) { if (utp1 == NULL) {
@ -155,7 +221,7 @@ int main(void) {
} }
/* Starting sandboxed thread 2.*/ /* Starting sandboxed thread 2.*/
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2", utp2 = sbStartThread(&sbx2, "sbx2",
waUnprivileged2, sizeof (waUnprivileged2), waUnprivileged2, sizeof (waUnprivileged2),
NORMALPRIO - 1); NORMALPRIO - 1);
if (utp1 == NULL) { if (utp1 == NULL) {
@ -163,7 +229,12 @@ int main(void) {
} }
/* /*
* Normal main() thread activity, in this demo it monitos the user button * Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state. * and checks for sandboxes state.
*/ */
while (true) { while (true) {
@ -199,4 +270,3 @@ int main(void) {
i++; i++;
} }
} }

View File

@ -22,8 +22,42 @@
#include "rt_test_root.h" #include "rt_test_root.h"
#include "oslib_test_root.h" #include "oslib_test_root.h"
#include "nullstreams.h"
#include "startup_defs.h" #include "startup_defs.h"
/*===========================================================================*/
/* VFS-related. */
/*===========================================================================*/
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
/* VFS FatFS driver object representing the root directory.*/
static vfs_fatfs_driver_c root_driver;
#endif
/* VFS overlay driver object representing the root directory.*/
static vfs_overlay_driver_c root_overlay_driver;
/* VFS streams driver object representing the /dev directory.*/
static vfs_streams_driver_c dev_driver;
/* VFS API will use this object as implicit root, defining this
symbol is expected.*/
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
static NullStream nullstream;
/* Stream to be exposed under /dev as files.*/
static const drv_streams_element_t streams[] = {
{"VSD1", (BaseSequentialStream *)&LPSD1},
{"null", (BaseSequentialStream *)&nullstream},
{NULL, NULL}
};
/*===========================================================================*/
/* SB-related. */
/*===========================================================================*/
/* Sandbox 1 configuration.*/ /* Sandbox 1 configuration.*/
static const sb_config_t sb_config1 = { static const sb_config_t sb_config1 = {
.code_region = 0U, .code_region = 0U,
@ -38,9 +72,7 @@ static const sb_config_t sb_config1 = {
.writeable = true .writeable = true
} }
}, },
.stdin_stream = (SandboxStream *)&LPSD1, .vfs_driver = (vfs_driver_c *)&root_overlay_driver
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
}; };
/* Sandbox 2 configuration.*/ /* Sandbox 2 configuration.*/
@ -57,16 +89,18 @@ static const sb_config_t sb_config2 = {
.writeable = true .writeable = true
} }
}, },
.stdin_stream = (SandboxStream *)&LPSD1, .vfs_driver = (vfs_driver_c *)&root_overlay_driver
.stdout_stream = (SandboxStream *)&LPSD1,
.stderr_stream = (SandboxStream *)&LPSD1
}; };
/* Sandbox objects.*/ /* Sandbox objects.*/
sb_class_t sbx1, sbx2; sb_class_t sbx1, sbx2;
static THD_WORKING_AREA(waUnprivileged1, 256); static THD_WORKING_AREA(waUnprivileged1, 512);
static THD_WORKING_AREA(waUnprivileged2, 256); static THD_WORKING_AREA(waUnprivileged2, 512);
/*===========================================================================*/
/* Main and generic code. */
/*===========================================================================*/
/* /*
* Green LED blinker thread, times are in milliseconds. * Green LED blinker thread, times are in milliseconds.
@ -90,6 +124,8 @@ int main(void) {
unsigned i = 1U; unsigned i = 1U;
thread_t *utp1, *utp2; thread_t *utp1, *utp2;
event_listener_t el1; event_listener_t el1;
vfs_file_node_c *fnp;
msg_t ret;
/* /*
* System initializations. * System initializations.
@ -97,27 +133,59 @@ int main(void) {
* and performs the board-specific initializations. * and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the * - Kernel initialization, the main() function becomes a thread and the
* RTOS is active. * RTOS is active.
* - Virtual File System initialization.
* - SandBox manager initialization. * - SandBox manager initialization.
*/ */
halInit(); halInit();
chSysInit(); chSysInit();
vfsInit();
sbHostInit(); sbHostInit();
/* /*
* Listening to sandbox events. * Starting a serial port for I/O, initializing other streams too.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Activates the Serial driver using the default configuration.
*/ */
sdStart(&LPSD1, NULL); sdStart(&LPSD1, NULL);
nullObjectInit(&nullstream);
/* /*
* Creates the blinker thread. * Creating a blinker thread.
*/ */
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
/*
* Initializing an overlay VFS object as a root, no overlaid driver,
* registering a streams VFS driver on the VFS overlay root as "/dev".
*/
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
ret = drvOverlayRegisterDriver(&root_overlay_driver,
drvStreamsObjectInit(&dev_driver, &streams[0]),
"dev");
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
/*
* Sandbox objects initialization.
*/
sbObjectInit(&sbx1, &sb_config1);
sbObjectInit(&sbx2, &sb_config2);
/*
* Associating standard input, output and error to sandboxes. Both sandboxes
* use the same serial port in this setup.
*/
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
if (CH_RET_IS_ERROR(ret)) {
chSysHalt("VFS");
}
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
vfsCloseFile(fnp);
/* /*
* Creating **static** boxes using MPU. * Creating **static** boxes using MPU.
* Note: The two regions cover both sandbox 1 and 2, there is no * Note: The two regions cover both sandbox 1 and 2, there is no
@ -137,7 +205,7 @@ int main(void) {
MPU_RASR_ENABLE); MPU_RASR_ENABLE);
/* Starting sandboxed thread 1.*/ /* Starting sandboxed thread 1.*/
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1", utp1 = sbStartThread(&sbx1, "sbx1",
waUnprivileged1, sizeof (waUnprivileged1), waUnprivileged1, sizeof (waUnprivileged1),
NORMALPRIO - 1); NORMALPRIO - 1);
if (utp1 == NULL) { if (utp1 == NULL) {
@ -145,7 +213,7 @@ int main(void) {
} }
/* Starting sandboxed thread 2.*/ /* Starting sandboxed thread 2.*/
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2", utp2 = sbStartThread(&sbx2, "sbx2",
waUnprivileged2, sizeof (waUnprivileged2), waUnprivileged2, sizeof (waUnprivileged2),
NORMALPRIO - 1); NORMALPRIO - 1);
if (utp1 == NULL) { if (utp1 == NULL) {
@ -153,7 +221,12 @@ int main(void) {
} }
/* /*
* Normal main() thread activity, in this demo it monitos the user button * Listening to sandbox events.
*/
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
/*
* Normal main() thread activity, in this demo it monitors the user button
* and checks for sandboxes state. * and checks for sandboxes state.
*/ */
while (true) { while (true) {
@ -189,4 +262,3 @@ int main(void) {
i++; i++;
} }
} }

View File

@ -153,24 +153,26 @@ static inline void __referenced_object_release_impl(void *ip) {
/** /**
* @brief New reference creation. * @brief New reference creation.
* *
* @param[in] rop A reference to the object. * @param[in] ip A reference to the object.
* @return A new reference to the object. * @return A new reference to the object.
*/ */
CC_FORCE_INLINE CC_FORCE_INLINE
static inline referenced_object_c *roAddRef(referenced_object_c *rop) { static inline referenced_object_c *roAddRef(void *ip) {
referenced_object_c *objp = (referenced_object_c *)ip;
return (referenced_object_c *)rop->vmt->addref((void *)rop); return objp->vmt->addref(ip);
} }
/** /**
* @brief Reference release. * @brief Reference release.
* *
* @param[in] rop A reference to the object. * @param[in] ip A reference to the object.
*/ */
CC_FORCE_INLINE CC_FORCE_INLINE
static inline void roRelease(referenced_object_c *rop) { static inline void roRelease(void *ip) {
referenced_object_c *objp = (referenced_object_c *)ip;
return rop->vmt->release((void *)rop); return objp->vmt->release(ip);
} }
#endif /* OOP_REFERENCED_OBJECT_H */ #endif /* OOP_REFERENCED_OBJECT_H */

View File

@ -28,6 +28,10 @@
#ifndef SB_H #ifndef SB_H
#define SB_H #define SB_H
#include "hal.h"
#include "vfs.h"
#include "errcodes.h"
/*===========================================================================*/ /*===========================================================================*/
/* Module constants. */ /* Module constants. */
/*===========================================================================*/ /*===========================================================================*/
@ -146,6 +150,138 @@
/* Module data structures and types. */ /* Module data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Type of a sandbox manager global structure.
*/
typedef struct {
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Event source for sandbox termination.
*/
event_source_t termination_es;
#endif
} sb_t;
/**
* @brief Type of a sandbox memory region.
*/
typedef struct {
/**
* @brief Associated memory area.
*/
memory_area_t area;
/**
* @brief Writable memory range.
*/
bool writeable;
} sb_memory_region_t;
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Type of a sandbox I/O structure.
*/
typedef struct {
/**
* @brief VFS nodes associated to file descriptors.
*/
vfs_node_c *vfs_nodes[SB_CFG_FD_NUM];
/**
* @brief Extra attributes added to the VFS nodes.
*/
uint8_t attributes[SB_CFG_FD_NUM];
} sb_ioblock_t;
#endif
/**
* @brief Type of a sandbox configuration structure.
*/
typedef struct {
/**
* @brief Memory region for code.
* @note It is used to locate the startup header.
*/
uint32_t code_region;
/**
* @brief Memory region for data and stack.
* @note It is used for initial PSP placement.
*/
uint32_t data_region;
/**
* @brief SandBox regions.
* @note The following memory regions are used only for pointers
* validation, not for MPU setup.
*/
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
/**
* @brief MPU regions initialization values.
* @note Regions initialization values must be chosen to be
* consistent with the values in the "regions" field.
*/
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS driver associated to the sandbox as root.
*/
vfs_driver_c *vfs_driver;
#else
/**
* @brief Sandbox STDIN stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdin_stream;
/**
* @brief Sandbox STDOUT stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdout_stream;
/**
* @brief Sandbox STDERR stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stderr_stream;
#endif
} sb_config_t;
/**
* @brief Type of a sandbox object.
*/
typedef struct {
/**
* @brief Pointer to the sandbox configuration data.
*/
const sb_config_t *config;
/**
* @brief Thread running in the sandbox.
*/
thread_t *tp;
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Thread sending a message to the sandbox.
*/
thread_t *msg_tp;
#endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Sandbox events source.
*/
event_source_t es;
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS bindings for Posix API.
*/
sb_ioblock_t io;
#endif
} sb_class_t;
/*===========================================================================*/ /*===========================================================================*/
/* Module macros. */ /* Module macros. */
/*===========================================================================*/ /*===========================================================================*/
@ -166,9 +302,6 @@ extern "C" {
/* Module inline functions. */ /* Module inline functions. */
/*===========================================================================*/ /*===========================================================================*/
#include "hal.h"
#include "errcodes.h"
#include "sbsysc.h" #include "sbsysc.h"
#include "sbposix.h" #include "sbposix.h"
#include "sbapi.h" #include "sbapi.h"

View File

@ -100,12 +100,13 @@ bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
* @brief Sandbox object initialization. * @brief Sandbox object initialization.
* *
* @param[out] sbcp pointer to the sandbox object * @param[out] sbcp pointer to the sandbox object
* @param[in] config pointer to the sandbox configuration
* *
* @init * @init
*/ */
void sbObjectInit(sb_class_t *sbcp) { void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) {
sbcp->config = NULL; sbcp->config = config;
sbcp->tp = NULL; sbcp->tp = NULL;
#if CH_CFG_USE_MESSAGES == TRUE #if CH_CFG_USE_MESSAGES == TRUE
sbcp->msg_tp = NULL; sbcp->msg_tp = NULL;
@ -118,16 +119,20 @@ void sbObjectInit(sb_class_t *sbcp) {
/** /**
* @brief Starts a sandboxed thread. * @brief Starts a sandboxed thread.
* *
* @param[out] sbcp pointer to the sandbox object * @param[in] sbcp pointer to a @p sb_class_t structure
* @param[in] config pointer to the sandbox configuration * @param[in] name name to be assigned to the thread
* @param[out] wsp pointer to a working area dedicated to the thread stack
* @param[in] size size of the working area
* @param[in] prio the priority level for the new thread
* @return The thread pointer. * @return The thread pointer.
* @retval NULL if the sandbox thread creation failed. * @retval NULL if the sandbox thread creation failed.
*/ */
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config, thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
const char *name, void *wsp, size_t size, void *wsp, size_t size,
tprio_t prio) { tprio_t prio) {
thread_t *utp; thread_t *utp;
const sb_header_t *sbhp; const sb_header_t *sbhp;
const sb_config_t *config = sbcp->config;
/* Header location.*/ /* Header location.*/
sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base; sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
@ -142,9 +147,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
return NULL; return NULL;
} }
/* Linking configuration information.*/
sbcp->config = config;
unprivileged_thread_descriptor_t utd = { unprivileged_thread_descriptor_t utd = {
.name = name, .name = name,
.wbase = (stkalign_t *)wsp, .wbase = (stkalign_t *)wsp,
@ -166,12 +168,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
/* For messages exchange.*/ /* For messages exchange.*/
sbcp->tp = utp; sbcp->tp = utp;
#if CH_CFG_USE_MESSAGES == TRUE
sbcp->msg_tp = NULL;
#endif
#if CH_CFG_USE_EVENTS == TRUE
chEvtObjectInit(&sbcp->es);
#endif
return utp; return utp;
} }

View File

@ -52,115 +52,6 @@
/* Module data structures and types. */ /* Module data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Type of a sandbox manager global structure.
*/
typedef struct {
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Event source for sandbox termination.
*/
event_source_t termination_es;
#endif
} sb_t;
/**
* @brief Type of a sandbox memory region.
*/
typedef struct {
/**
* @brief Associated memory area.
*/
memory_area_t area;
/**
* @brief Writable memory range.
*/
bool writeable;
} sb_memory_region_t;
/**
* @brief Type of a sandbox configuration structure.
*/
typedef struct {
/**
* @brief Memory region for code.
* @note It is used to locate the startup header.
*/
uint32_t code_region;
/**
* @brief Memory region for data and stack.
* @note It is used for initial PSP placement.
*/
uint32_t data_region;
/**
* @brief SandBox regions.
* @note The following memory regions are used only for pointers
* validation, not for MPU setup.
*/
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
/**
* @brief MPU regions initialization values.
* @note Regions initialization values must be chosen to be
* consistent with the values in the "regions" field.
*/
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
#endif
/**
* @brief Sandbox STDIN stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdin_stream;
/**
* @brief Sandbox STDOUT stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stdout_stream;
/**
* @brief Sandbox STDERR stream.
* @note Set this to @p NULL if standard I/O is not needed.
* @note By design you can use HAL streams here, you need to use
* a cast however.
*/
SandboxStream *stderr_stream;
} sb_config_t;
/**
* @brief Type of a sandbox object.
*/
typedef struct {
/**
* @brief Pointer to the sandbox configuration data.
*/
const sb_config_t *config;
/**
* @brief Thread running in the sandbox.
*/
thread_t *tp;
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Thread sending a message to the sandbox.
*/
thread_t *msg_tp;
#endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Sandbox events source.
*/
event_source_t es;
#endif
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief VFS bindings for Posix API.
*/
sb_ioblock_t io;
#endif
} sb_class_t;
/** /**
* @brief Type of a sandbox binary image header. * @brief Type of a sandbox binary image header.
*/ */
@ -200,10 +91,9 @@ extern "C" {
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size); bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size); bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n); bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n);
void sbObjectInit(sb_class_t *sbcp); void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
void sbStart(sb_class_t *sbcp, const sb_config_t *config); thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config, void *wsp, size_t size,
const char *name, void *wsp, size_t size,
tprio_t prio); tprio_t prio);
msg_t sbSendMessageTimeout(sb_class_t *sbcp, msg_t sbSendMessageTimeout(sb_class_t *sbcp,
msg_t msg, msg_t msg,

View File

@ -48,6 +48,7 @@
/* Module local functions. */ /* Module local functions. */
/*===========================================================================*/ /*===========================================================================*/
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
static msg_t create_descriptor(sb_ioblock_t *iop, static msg_t create_descriptor(sb_ioblock_t *iop,
vfs_node_c *np, vfs_node_c *np,
uint8_t attributes) { uint8_t attributes) {
@ -69,6 +70,7 @@ static bool is_valid_descriptor(sb_ioblock_t *iop, int fd) {
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL); return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
} }
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Module exported functions. */ /* Module exported functions. */
@ -85,7 +87,8 @@ int sb_posix_open(const char *path, int flags) {
} }
do { do {
ret = vfsDrvOpenFile(sbp->io.vfs_driver, path, (unsigned)flags, &fnp); ret = vfsDrvOpenFile(sbp->config->vfs_driver, path,
(unsigned)flags, &fnp);
CH_BREAK_ON_ERROR(ret); CH_BREAK_ON_ERROR(ret);
ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0); ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0);
@ -122,7 +125,7 @@ int sb_posix_close(int fd) {
ssize_t sb_posix_read(int fd, void *buf, size_t count) { ssize_t sb_posix_read(int fd, void *buf, size_t count) {
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
if (!sb_is_valid_read_range(sbp, (void *)buf, count)) { if (!sb_is_valid_write_range(sbp, (void *)buf, count)) {
return CH_RET_EFAULT; return CH_RET_EFAULT;
} }
@ -140,7 +143,7 @@ ssize_t sb_posix_read(int fd, void *buf, size_t count) {
ssize_t sb_posix_write(int fd, const void *buf, size_t count) { ssize_t sb_posix_write(int fd, const void *buf, size_t count) {
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
if (!sb_is_valid_write_range(sbp, (void *)buf, count)) { if (!sb_is_valid_read_range(sbp, (void *)buf, count)) {
return CH_RET_EFAULT; return CH_RET_EFAULT;
} }
@ -168,6 +171,18 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
return CH_RET_EBADF; return CH_RET_EBADF;
} }
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
int fd,
vfs_file_node_c *fnp) {
chDbgAssert(is_valid_descriptor(&sbp->io, fd) &&
sbp->io.vfs_nodes[fd] == NULL,
"invalid file descriptor");
sbp->io.vfs_nodes[fd] = (vfs_node_c *)fnp;
sbp->io.attributes[fd] = 0;
}
#else /* Fallbacks for when there is no VFS.*/ #else /* Fallbacks for when there is no VFS.*/
uint32_t sb_posix_open(const char *pathname, uint32_t flags) { uint32_t sb_posix_open(const char *pathname, uint32_t flags) {

View File

@ -48,26 +48,6 @@
/* Module data structures and types. */ /* Module data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Type of a sandbox I/O structure.
*/
typedef struct {
/**
* @brief VFS driver associated to the sandbox as root.
*/
vfs_driver_c *vfs_driver;
/**
* @brief VFS nodes associated to file descriptors.
*/
vfs_node_c *vfs_nodes[SB_CFG_FD_NUM];
/**
* @brief Extra attributes added to the VFS nodes.
*/
uint8_t attributes[SB_CFG_FD_NUM];
} sb_ioblock_t;
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Module macros. */ /* Module macros. */
/*===========================================================================*/ /*===========================================================================*/
@ -84,6 +64,11 @@ extern "C" {
ssize_t sb_posix_read(int fd, void *buf, size_t count); ssize_t sb_posix_read(int fd, void *buf, size_t count);
ssize_t sb_posix_write(int fd, const void *buf, size_t count); ssize_t sb_posix_write(int fd, const void *buf, size_t count);
off_t sb_posix_lseek(int fd, off_t offset, int whence); off_t sb_posix_lseek(int fd, off_t offset, int whence);
#if SB_CFG_ENABLE_VFS == TRUE
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
int fd,
vfs_file_node_c *fnp);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,9 +23,23 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include "errcodes.h"
#include "sbuser.h" #include "sbuser.h"
#define MAKERR(e) (-(int)(e)) __attribute__((used))
int _open_r(struct _reent *r, const char *p, int oflag, int mode) {
uint32_t err;
(void)mode;
err = sbFileOpen(p, oflag);
if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = CH_DECODE_ERROR(err);
return -1;
}
return err;
}
__attribute__((used)) __attribute__((used))
int _close_r(struct _reent *r, int file) { int _close_r(struct _reent *r, int file) {
@ -33,7 +47,7 @@ int _close_r(struct _reent *r, int file) {
err = sbFileClose((uint32_t)file); err = sbFileClose((uint32_t)file);
if (CH_RET_IS_ERROR(err)) { if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err); __errno_r(r) = CH_DECODE_ERROR(err);
return -1; return -1;
} }
@ -46,7 +60,7 @@ int _write_r(struct _reent *r, int file, char * ptr, int len) {
err = sbFileWrite((uint32_t)file, (const uint8_t *)ptr, (size_t)len); err = sbFileWrite((uint32_t)file, (const uint8_t *)ptr, (size_t)len);
if (CH_RET_IS_ERROR(err)) { if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err); __errno_r(r) = CH_DECODE_ERROR(err);
return -1; return -1;
} }
@ -59,7 +73,7 @@ int _read_r(struct _reent *r, int file, char * ptr, int len) {
err = sbFileRead((uint32_t)file, (uint8_t *)ptr, (size_t)len); err = sbFileRead((uint32_t)file, (uint8_t *)ptr, (size_t)len);
if (CH_RET_IS_ERROR(err)) { if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err); __errno_r(r) = CH_DECODE_ERROR(err);
return -1; return -1;
} }
@ -72,7 +86,7 @@ int _lseek_r(struct _reent *r, int file, int ptr, int dir) {
err = sbFileSeek((uint32_t)file, (uint32_t)ptr, (uint32_t)dir); err = sbFileSeek((uint32_t)file, (uint32_t)ptr, (uint32_t)dir);
if (CH_RET_IS_ERROR(err)) { if (CH_RET_IS_ERROR(err)) {
__errno_r(r) = MAKERR(err); __errno_r(r) = CH_DECODE_ERROR(err);
return -1; return -1;
} }