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:
parent
aac3849aa4
commit
6751fc38ee
|
@ -22,8 +22,42 @@
|
|||
#include "rt_test_root.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
#include "nullstreams.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.*/
|
||||
static const sb_config_t sb_config1 = {
|
||||
.code_region = 0U,
|
||||
|
@ -52,9 +86,6 @@ static const sb_config_t sb_config1 = {
|
|||
MPU_RASR_ENABLE
|
||||
}
|
||||
},
|
||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
||||
.stderr_stream = (SandboxStream *)&LPSD1
|
||||
};
|
||||
|
||||
/* Sandbox 2 configuration.*/
|
||||
|
@ -85,16 +116,17 @@ static const sb_config_t sb_config2 = {
|
|||
MPU_RASR_ENABLE
|
||||
}
|
||||
},
|
||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
||||
.stderr_stream = (SandboxStream *)&LPSD1
|
||||
};
|
||||
|
||||
/* Sandbox objects.*/
|
||||
sb_class_t sbx1, sbx2;
|
||||
|
||||
static THD_WORKING_AREA(waUnprivileged1, 256);
|
||||
static THD_WORKING_AREA(waUnprivileged2, 256);
|
||||
static THD_WORKING_AREA(waUnprivileged1, 512);
|
||||
static THD_WORKING_AREA(waUnprivileged2, 512);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Main and generic code. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Green LED blinker thread, times are in milliseconds.
|
||||
|
@ -118,6 +150,8 @@ int main(void) {
|
|||
unsigned i = 1U;
|
||||
thread_t *utp1, *utp2;
|
||||
event_listener_t el1;
|
||||
vfs_file_node_c *fnp;
|
||||
msg_t ret;
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
|
@ -125,29 +159,61 @@ int main(void) {
|
|||
* and performs the board-specific initializations.
|
||||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
* - Virtual File System initialization.
|
||||
* - SandBox manager initialization.
|
||||
*/
|
||||
halInit();
|
||||
chSysInit();
|
||||
vfsInit();
|
||||
sbHostInit();
|
||||
|
||||
/*
|
||||
* Listening to sandbox events.
|
||||
*/
|
||||
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
||||
|
||||
/*
|
||||
* Activates the Serial driver using the default configuration.
|
||||
* Starting a serial port for I/O, initializing other streams too.
|
||||
*/
|
||||
sdStart(&LPSD1, NULL);
|
||||
nullObjectInit(&nullstream);
|
||||
|
||||
/*
|
||||
* Creates the blinker thread.
|
||||
* Creating a blinker thread.
|
||||
*/
|
||||
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.*/
|
||||
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
|
||||
utp1 = sbStartThread(&sbx1, "sbx1",
|
||||
waUnprivileged1, sizeof (waUnprivileged1),
|
||||
NORMALPRIO - 1);
|
||||
if (utp1 == NULL) {
|
||||
|
@ -155,7 +221,7 @@ int main(void) {
|
|||
}
|
||||
|
||||
/* Starting sandboxed thread 2.*/
|
||||
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
|
||||
utp2 = sbStartThread(&sbx2, "sbx2",
|
||||
waUnprivileged2, sizeof (waUnprivileged2),
|
||||
NORMALPRIO - 1);
|
||||
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.
|
||||
*/
|
||||
while (true) {
|
||||
|
@ -199,4 +270,3 @@ int main(void) {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,42 @@
|
|||
#include "rt_test_root.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
#include "nullstreams.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.*/
|
||||
static const sb_config_t sb_config1 = {
|
||||
.code_region = 0U,
|
||||
|
@ -38,9 +72,7 @@ static const sb_config_t sb_config1 = {
|
|||
.writeable = true
|
||||
}
|
||||
},
|
||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
||||
.stderr_stream = (SandboxStream *)&LPSD1
|
||||
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
|
||||
};
|
||||
|
||||
/* Sandbox 2 configuration.*/
|
||||
|
@ -57,16 +89,18 @@ static const sb_config_t sb_config2 = {
|
|||
.writeable = true
|
||||
}
|
||||
},
|
||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
||||
.stderr_stream = (SandboxStream *)&LPSD1
|
||||
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
|
||||
};
|
||||
|
||||
/* Sandbox objects.*/
|
||||
sb_class_t sbx1, sbx2;
|
||||
|
||||
static THD_WORKING_AREA(waUnprivileged1, 256);
|
||||
static THD_WORKING_AREA(waUnprivileged2, 256);
|
||||
static THD_WORKING_AREA(waUnprivileged1, 512);
|
||||
static THD_WORKING_AREA(waUnprivileged2, 512);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Main and generic code. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Green LED blinker thread, times are in milliseconds.
|
||||
|
@ -90,6 +124,8 @@ int main(void) {
|
|||
unsigned i = 1U;
|
||||
thread_t *utp1, *utp2;
|
||||
event_listener_t el1;
|
||||
vfs_file_node_c *fnp;
|
||||
msg_t ret;
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
|
@ -97,27 +133,59 @@ int main(void) {
|
|||
* and performs the board-specific initializations.
|
||||
* - Kernel initialization, the main() function becomes a thread and the
|
||||
* RTOS is active.
|
||||
* - Virtual File System initialization.
|
||||
* - SandBox manager initialization.
|
||||
*/
|
||||
halInit();
|
||||
chSysInit();
|
||||
vfsInit();
|
||||
sbHostInit();
|
||||
|
||||
/*
|
||||
* Listening to sandbox events.
|
||||
*/
|
||||
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
||||
|
||||
/*
|
||||
* Activates the Serial driver using the default configuration.
|
||||
* Starting a serial port for I/O, initializing other streams too.
|
||||
*/
|
||||
sdStart(&LPSD1, NULL);
|
||||
nullObjectInit(&nullstream);
|
||||
|
||||
/*
|
||||
* Creates the blinker thread.
|
||||
* Creating a blinker thread.
|
||||
*/
|
||||
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.
|
||||
* Note: The two regions cover both sandbox 1 and 2, there is no
|
||||
|
@ -137,7 +205,7 @@ int main(void) {
|
|||
MPU_RASR_ENABLE);
|
||||
|
||||
/* Starting sandboxed thread 1.*/
|
||||
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
|
||||
utp1 = sbStartThread(&sbx1, "sbx1",
|
||||
waUnprivileged1, sizeof (waUnprivileged1),
|
||||
NORMALPRIO - 1);
|
||||
if (utp1 == NULL) {
|
||||
|
@ -145,7 +213,7 @@ int main(void) {
|
|||
}
|
||||
|
||||
/* Starting sandboxed thread 2.*/
|
||||
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
|
||||
utp2 = sbStartThread(&sbx2, "sbx2",
|
||||
waUnprivileged2, sizeof (waUnprivileged2),
|
||||
NORMALPRIO - 1);
|
||||
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.
|
||||
*/
|
||||
while (true) {
|
||||
|
@ -189,4 +262,3 @@ int main(void) {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,24 +153,26 @@ static inline void __referenced_object_release_impl(void *ip) {
|
|||
/**
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param[in] rop A reference to the object.
|
||||
* @param[in] ip A reference to the object.
|
||||
*/
|
||||
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 */
|
||||
|
|
139
os/sb/host/sb.h
139
os/sb/host/sb.h
|
@ -28,6 +28,10 @@
|
|||
#ifndef SB_H
|
||||
#define SB_H
|
||||
|
||||
#include "hal.h"
|
||||
#include "vfs.h"
|
||||
#include "errcodes.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
@ -146,6 +150,138 @@
|
|||
/* 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. */
|
||||
/*===========================================================================*/
|
||||
|
@ -166,9 +302,6 @@ extern "C" {
|
|||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "errcodes.h"
|
||||
|
||||
#include "sbsysc.h"
|
||||
#include "sbposix.h"
|
||||
#include "sbapi.h"
|
||||
|
|
|
@ -100,12 +100,13 @@ bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
|
|||
* @brief Sandbox object initialization.
|
||||
*
|
||||
* @param[out] sbcp pointer to the sandbox object
|
||||
* @param[in] config pointer to the sandbox configuration
|
||||
*
|
||||
* @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;
|
||||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
sbcp->msg_tp = NULL;
|
||||
|
@ -118,16 +119,20 @@ void sbObjectInit(sb_class_t *sbcp) {
|
|||
/**
|
||||
* @brief Starts a sandboxed thread.
|
||||
*
|
||||
* @param[out] sbcp pointer to the sandbox object
|
||||
* @param[in] config pointer to the sandbox configuration
|
||||
* @param[in] sbcp pointer to a @p sb_class_t structure
|
||||
* @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.
|
||||
* @retval NULL if the sandbox thread creation failed.
|
||||
*/
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
||||
const char *name, void *wsp, size_t size,
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||
void *wsp, size_t size,
|
||||
tprio_t prio) {
|
||||
thread_t *utp;
|
||||
const sb_header_t *sbhp;
|
||||
const sb_config_t *config = sbcp->config;
|
||||
|
||||
/* Header location.*/
|
||||
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;
|
||||
}
|
||||
|
||||
/* Linking configuration information.*/
|
||||
sbcp->config = config;
|
||||
|
||||
unprivileged_thread_descriptor_t utd = {
|
||||
.name = name,
|
||||
.wbase = (stkalign_t *)wsp,
|
||||
|
@ -166,12 +168,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
|||
|
||||
/* For messages exchange.*/
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -52,115 +52,6 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
@ -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_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);
|
||||
void sbObjectInit(sb_class_t *sbcp);
|
||||
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
||||
const char *name, void *wsp, size_t size,
|
||||
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
|
||||
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||
void *wsp, size_t size,
|
||||
tprio_t prio);
|
||||
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
||||
msg_t msg,
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||
static msg_t create_descriptor(sb_ioblock_t *iop,
|
||||
vfs_node_c *np,
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
|
@ -85,7 +87,8 @@ int sb_posix_open(const char *path, int flags) {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -168,6 +171,18 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
|
|||
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.*/
|
||||
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
||||
|
||||
|
|
|
@ -48,26 +48,6 @@
|
|||
/* 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. */
|
||||
/*===========================================================================*/
|
||||
|
@ -84,6 +64,11 @@ extern "C" {
|
|||
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);
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,9 +23,23 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "errcodes.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))
|
||||
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);
|
||||
if (CH_RET_IS_ERROR(err)) {
|
||||
__errno_r(r) = MAKERR(err);
|
||||
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||
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);
|
||||
if (CH_RET_IS_ERROR(err)) {
|
||||
__errno_r(r) = MAKERR(err);
|
||||
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||
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);
|
||||
if (CH_RET_IS_ERROR(err)) {
|
||||
__errno_r(r) = MAKERR(err);
|
||||
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||
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);
|
||||
if (CH_RET_IS_ERROR(err)) {
|
||||
__errno_r(r) = MAKERR(err);
|
||||
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue