Committed the rest. There is only few stuff missing.

Embedded nice pictures.
This commit is contained in:
Jacek Galowicz 2011-04-05 14:44:42 +02:00
parent f411498368
commit 6c6d77cfa6
15 changed files with 1162 additions and 22 deletions

4
.gitignore vendored
View file

@ -6,6 +6,8 @@
*.pcap
*.img
tags
include/metalsvm/config.h
Makefile
tools/make_initrd
newlib/examples/hello
newlib/examples/echo
@ -13,4 +15,4 @@ newlib/examples/tests
newlib/tmp/*
newlib/x86/*
metalsvm.elf
documentation/html
documentation/html/

View file

@ -605,7 +605,8 @@ INPUT = ./fs \
./arch \
./libkern \
./mm \
./tools
./tools \
./documentation/doxy_mainpage.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -683,7 +684,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
IMAGE_PATH = ./documentation/img/
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -825,13 +826,13 @@ HTML_FILE_EXTENSION = .html
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
HTML_HEADER = ./documentation/tmpl/header.html
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
HTML_FOOTER = ./documentation/tmpl/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
@ -840,7 +841,7 @@ HTML_FOOTER =
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET =
HTML_STYLESHEET = ./documentation/tmpl/stylesheet.css
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images

View file

@ -0,0 +1,47 @@
/**
* @file doxy_mainpage.h
* @mainpage
*
* @section Introduction
*
* On a traditional multicore system, a single operating system
* manages all cores and schedules threads and processes among
* them, inherently supported by hardware-implemented cache
* coherence protocols. However, a further growth of the number
* of cores per system implies an increasing chip complexity,
* especially with respect to the cache coherence protocols.
* Therefore, a very attractive alternative for future many-core
* systems is to waive the hardware-based cache coherency and to
* introduce a software-oriented message-passing based architecture
* instead: a so-called Cluster-on-Chip architecture.
* Intel's Single-chip Cloud Computer (SCC), a many-core research
* processor with 48 non-coherent memory-coupled cores, is a very
* recent example for such a Cluster-on-Chip architecture. The SCC
* can be configured to run one operating system per core by
* partitioning the shared main memory in a strict manner. However,
* it is also possible to access the shared main memory in an unsplit
* and concurrent manner, provided that the cache coherency is then
* ensured by software.
*
* @section Research Objective
*
* In this project, we develop a new approach for a SCC-related shared
* virtual memory management system, called MetalSVM, that will be
* implemented in terms of a bare-metal hypervisor, located within a
* virtualization layer between the SCC's hardware and the actual
* operating system. This new hypervisor will undertake the crucial
* task of coherency management by utilizing special SCC-related features
* as, for example, its on-die Message-Passing Buffers (MPB). That way,
* common Linux kernels will be able to run almost transparently across
* the entire SCC system. However, in order to offer a maximum of flexibility
* with respect to resource allocation as well as to an efficiency-adjusted
* degree of parallelism, also a dynamic partitioning of the SCC's computing
* resources into several coherency domains will be made possible.
*
* @image html metalsvm_stack.jpg
*
* @section Acknowledgment
*
* This research project is funded by Intel Corporation.
*
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,4 @@
<hr class="footer"/><address class="footer"><small>
Generated on $datetime for $projectname by&#160;<a href="http://www.doxygen.org/index.html"><img class="footer" src="$relpath$doxygen.png" alt="doxygen"/></a> $doxygenversion</small></address>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>$title</title>
<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
<link href="$relpath$search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath$search/search.js"></script>
<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css"/>
<link href="$relpath$stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body onload='searchBox.OnSelectItem(0);'>
<div id="top"><!-- do not remove this div! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">MetalSVM</div>
<div id="lfbslogo"><img src="../img/lfbs_logo.gif" alt="Lehrstuhl f&uuml;r Betriebssysteme" /></div>
<div id="rwthlogo"><img src="../img/rwth_logo.gif" alt="RWTH Aachen University" /></div>
<div id="projectbrief">A Bare-Metal Hypervisor for Non-Coherent Memory-Coupled Cores</div>
</td>
</tr>
</tbody>
</table>
</div>

View file

@ -0,0 +1,814 @@
/* The standard CSS for doxygen */
body, table, div, p, dl {
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
font-size: 12px;
}
/* @group Heading Levels */
h1 {
font-size: 150%;
}
h2 {
font-size: 120%;
}
h3 {
font-size: 100%;
}
dt {
font-weight: bold;
}
div.multicol {
-moz-column-gap: 1em;
-webkit-column-gap: 1em;
-moz-column-count: 3;
-webkit-column-count: 3;
}
p.startli, p.startdd, p.starttd {
margin-top: 2px;
}
p.endli {
margin-bottom: 0px;
}
p.enddd {
margin-bottom: 4px;
}
p.endtd {
margin-bottom: 2px;
}
/* @end */
caption {
font-weight: bold;
}
span.legend {
font-size: 70%;
text-align: center;
}
h3.version {
font-size: 90%;
text-align: center;
}
div.qindex, div.navtab{
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
padding: 2px;
}
div.qindex, div.navpath {
width: 100%;
line-height: 140%;
}
div.navtab {
margin-right: 15px;
}
/* @group Link Styling */
a {
color: #3D578C;
font-weight: normal;
text-decoration: none;
}
.contents a:visited {
color: #4665A2;
}
a:hover {
text-decoration: underline;
}
a.qindex {
font-weight: bold;
}
a.qindexHL {
font-weight: bold;
background-color: #9CAFD4;
color: #ffffff;
border: 1px double #869DCA;
}
.contents a.qindexHL:visited {
color: #ffffff;
}
a.el {
font-weight: bold;
}
a.elRef {
}
a.code {
color: #4665A2;
}
a.codeRef {
color: #4665A2;
}
/* @end */
dl.el {
margin-left: -1cm;
}
.fragment {
font-family: monospace, fixed;
font-size: 105%;
}
pre.fragment {
border: 1px solid #C4CFE5;
background-color: #FBFCFD;
padding: 4px 6px;
margin: 4px 8px 4px 2px;
overflow: auto;
word-wrap: break-word;
font-size: 9pt;
line-height: 125%;
}
div.ah {
background-color: black;
font-weight: bold;
color: #ffffff;
margin-bottom: 3px;
margin-top: 3px;
padding: 0.2em;
border: solid thin #333;
border-radius: 0.5em;
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
box-shadow: 2px 2px 3px #999;
-webkit-box-shadow: 2px 2px 3px #999;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
}
div.groupHeader {
margin-left: 16px;
margin-top: 12px;
font-weight: bold;
}
div.groupText {
margin-left: 16px;
font-style: italic;
}
body {
background: white;
color: black;
margin: 0;
}
div.contents {
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
}
td.indexkey {
background-color: #EBEFF6;
font-weight: bold;
border: 1px solid #C4CFE5;
margin: 2px 0px 2px 0;
padding: 2px 10px;
}
td.indexvalue {
background-color: #EBEFF6;
border: 1px solid #C4CFE5;
padding: 2px 10px;
margin: 2px 0px;
}
tr.memlist {
background-color: #EEF1F7;
}
p.formulaDsp {
text-align: center;
}
img.formulaDsp {
}
img.formulaInl {
vertical-align: middle;
}
div.center {
text-align: center;
margin-top: 0px;
margin-bottom: 0px;
padding: 0px;
}
div.center img {
border: 0px;
}
address.footer {
text-align: right;
padding-right: 12px;
}
img.footer {
border: 0px;
vertical-align: middle;
}
/* @group Code Colorization */
span.keyword {
color: #008000
}
span.keywordtype {
color: #604020
}
span.keywordflow {
color: #e08000
}
span.comment {
color: #800000
}
span.preprocessor {
color: #806020
}
span.stringliteral {
color: #002080
}
span.charliteral {
color: #008080
}
span.vhdldigit {
color: #ff00ff
}
span.vhdlchar {
color: #000000
}
span.vhdlkeyword {
color: #700070
}
span.vhdllogic {
color: #ff0000
}
/* @end */
/*
.search {
color: #003399;
font-weight: bold;
}
form.search {
margin-bottom: 0px;
margin-top: 0px;
}
input.search {
font-size: 75%;
color: #000080;
font-weight: normal;
background-color: #e8eef2;
}
*/
td.tiny {
font-size: 75%;
}
.dirtab {
padding: 4px;
border-collapse: collapse;
border: 1px solid #A3B4D7;
}
th.dirtab {
background: #EBEFF6;
font-weight: bold;
}
hr {
height: 0px;
border: none;
border-top: 1px solid #4A6AAA;
}
hr.footer {
height: 1px;
}
/* @group Member Descriptions */
table.memberdecls {
border-spacing: 0px;
padding: 0px;
}
.mdescLeft, .mdescRight,
.memItemLeft, .memItemRight,
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
background-color: #F9FAFC;
border: none;
margin: 4px;
padding: 1px 0 0 8px;
}
.mdescLeft, .mdescRight {
padding: 0px 8px 4px 8px;
color: #555;
}
.memItemLeft, .memItemRight, .memTemplParams {
border-top: 1px solid #C4CFE5;
}
.memItemLeft, .memTemplItemLeft {
white-space: nowrap;
}
.memTemplParams {
color: #4665A2;
white-space: nowrap;
}
/* @end */
/* @group Member Details */
/* Styles for detailed member documentation */
.memtemplate {
font-size: 80%;
color: #4665A2;
font-weight: normal;
margin-left: 9px;
}
.memnav {
background-color: #EBEFF6;
border: 1px solid #A3B4D7;
text-align: center;
margin: 2px;
margin-right: 15px;
padding: 2px;
}
.memitem {
padding: 0;
margin-bottom: 10px;
}
.memname {
white-space: nowrap;
font-weight: bold;
margin-left: 6px;
}
.memproto {
border-top: 1px solid #A8B8D9;
border-left: 1px solid #A8B8D9;
border-right: 1px solid #A8B8D9;
padding: 6px 0px 6px 0px;
color: #253555;
font-weight: bold;
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
/* opera specific markup */
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
border-top-right-radius: 8px;
border-top-left-radius: 8px;
/* firefox specific markup */
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
-moz-border-radius-topright: 8px;
-moz-border-radius-topleft: 8px;
/* webkit specific markup */
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-webkit-border-top-right-radius: 8px;
-webkit-border-top-left-radius: 8px;
background-image:url('nav_f.png');
background-repeat:repeat-x;
background-color: #E2E8F2;
}
.memdoc {
border-bottom: 1px solid #A8B8D9;
border-left: 1px solid #A8B8D9;
border-right: 1px solid #A8B8D9;
padding: 2px 5px;
background-color: #FBFCFD;
border-top-width: 0;
/* opera specific markup */
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
/* firefox specific markup */
-moz-border-radius-bottomleft: 8px;
-moz-border-radius-bottomright: 8px;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
/* webkit specific markup */
-webkit-border-bottom-left-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
}
.paramkey {
text-align: right;
}
.paramtype {
white-space: nowrap;
}
.paramname {
color: #602020;
white-space: nowrap;
}
.paramname em {
font-style: normal;
}
.params, .retval, .exception, .tparams {
border-spacing: 6px 2px;
}
.params .paramname, .retval .paramname {
font-weight: bold;
vertical-align: top;
}
.params .paramtype {
font-style: italic;
vertical-align: top;
}
.params .paramdir {
font-family: "courier new",courier,monospace;
vertical-align: top;
}
/* @end */
/* @group Directory (tree) */
/* for the tree view */
.ftvtree {
font-family: sans-serif;
margin: 0px;
}
/* these are for tree view when used as main index */
.directory {
font-size: 9pt;
font-weight: bold;
margin: 5px;
}
.directory h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
/*
The following two styles can be used to replace the root node title
with an image of your choice. Simply uncomment the next two styles,
specify the name of your image and be sure to set 'height' to the
proper pixel height of your image.
*/
/*
.directory h3.swap {
height: 61px;
background-repeat: no-repeat;
background-image: url("yourimage.gif");
}
.directory h3.swap span {
display: none;
}
*/
.directory > h3 {
margin-top: 0;
}
.directory p {
margin: 0px;
white-space: nowrap;
}
.directory div {
display: none;
margin: 0px;
}
.directory img {
vertical-align: -30%;
}
/* these are for tree view when not used as main index */
.directory-alt {
font-size: 100%;
font-weight: bold;
}
.directory-alt h3 {
margin: 0px;
margin-top: 1em;
font-size: 11pt;
}
.directory-alt > h3 {
margin-top: 0;
}
.directory-alt p {
margin: 0px;
white-space: nowrap;
}
.directory-alt div {
display: none;
margin: 0px;
}
.directory-alt img {
vertical-align: -30%;
}
/* @end */
div.dynheader {
margin-top: 8px;
}
address {
font-style: normal;
color: #2A3D61;
}
table.doxtable {
border-collapse:collapse;
}
table.doxtable td, table.doxtable th {
border: 1px solid #2D4068;
padding: 3px 7px 2px;
}
table.doxtable th {
background-color: #374F7F;
color: #FFFFFF;
font-size: 110%;
padding-bottom: 4px;
padding-top: 5px;
text-align:left;
}
.tabsearch {
top: 0px;
left: 10px;
height: 36px;
background-image: url('tab_b.png');
z-index: 101;
overflow: hidden;
font-size: 13px;
}
.navpath ul
{
font-size: 11px;
background-image:url('tab_b.png');
background-repeat:repeat-x;
height:30px;
line-height:30px;
color:#8AA0CC;
border:solid 1px #C2CDE4;
overflow:hidden;
margin:0px;
padding:0px;
}
.navpath li
{
list-style-type:none;
float:left;
padding-left:10px;
padding-right:15px;
background-image:url('bc_s.png');
background-repeat:no-repeat;
background-position:right;
color:#364D7C;
}
.navpath li.navelem a
{
height:32px;
display:block;
text-decoration: none;
outline: none;
}
.navpath li.navelem a:hover
{
color:#6884BD;
}
.navpath li.footer
{
list-style-type:none;
float:right;
padding-left:10px;
padding-right:15px;
background-image:none;
background-repeat:no-repeat;
background-position:right;
color:#364D7C;
font-size: 8pt;
}
div.summary
{
float: right;
font-size: 8pt;
padding-right: 5px;
width: 50%;
text-align: right;
}
div.summary a
{
white-space: nowrap;
}
div.ingroups
{
font-size: 8pt;
padding-left: 5px;
width: 50%;
text-align: left;
}
div.ingroups a
{
white-space: nowrap;
}
div.header
{
background-image:url('nav_h.png');
background-repeat:repeat-x;
background-color: #F9FAFC;
margin: 0px;
border-bottom: 1px solid #C4CFE5;
}
div.headertitle
{
padding: 5px 5px 5px 10px;
}
dl
{
padding: 0 0 0 10px;
}
dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
{
border-left:4px solid;
padding: 0 0 0 6px;
}
dl.note
{
border-color: #D0D000;
}
dl.warning, dl.attention
{
border-color: #FF0000;
}
dl.pre, dl.post, dl.invariant
{
border-color: #00D000;
}
dl.deprecated
{
border-color: #505050;
}
dl.todo
{
border-color: #00C0E0;
}
dl.test
{
border-color: #3030E0;
}
dl.bug
{
border-color: #C08050;
}
#projectlogo
{
text-align: center;
vertical-align: bottom;
border-collapse: separate;
}
#projectlogo img
{
border: 0px none;
}
#projectname
{
font: 300% arial,sans-serif;
margin: 0px;
padding: 0px;
}
#projectbrief
{
font: 120% arial,sans-serif;
margin: 0px;
padding: 0px;
}
#lfbslogo
{
position: absolute;
top: 5px;
right: 200px;
}
#rwthlogo
{
position: absolute;
top: 5px;
right: 5px;
}
#projectnumber
{
font: 50% arial,sans-serif;
margin: 0px;
padding: 0px;
}
#titlearea
{
padding: 0px;
margin: 0px;
width: 100%;
border-bottom: 1px solid #5373B4;
}

View file

@ -17,6 +17,12 @@
* This file is part of MetalSVM.
*/
/**
* @author Stefan Lankes
* @file include/metalsvm/fs.h
* @brief Filesystem related functions and structures
*/
#ifndef __FS_H__
#define __FS_H__
@ -33,65 +39,162 @@
struct vfs_node;
/* These typedefs define the type of callbacks - called when read/write/open/close are called. */
/** @defgroup fsprototypes FS access function prototypes
*
* These typedefs define the type of callbacks - called when read/write/open/close are called.\n
* They aren't as well documented as the read_fs and so on functions. Just look there for further information.
*
* @{
*/
/** @brief Read function pointer */
typedef ssize_t (*read_type_t) (struct vfs_node *, uint8_t*, size_t, off_t);
/** @brief Write function pointer */
typedef ssize_t (*write_type_t) (struct vfs_node *, uint8_t*, size_t, off_t);
/** @brief Open function pointer */
typedef int (*open_type_t) (struct vfs_node *);
/** @brief Close function pointer */
typedef int (*close_type_t) (struct vfs_node *);
/** @brief Read directory function pointer */
typedef struct dirent *(*readdir_type_t) (struct vfs_node *, uint32_t);
/** @brief Find directory function pointer */
typedef struct vfs_node *(*finddir_type_t) (struct vfs_node *, const char *name);
/** @brief Make directory function pointer */
typedef struct vfs_node *(*mkdir_type_t) (struct vfs_node *, const char *name);
/** @} */
#define MAX_DATABLOCKS 12
#define MAX_DIRENTRIES 32
/** @brief Block list structure. VFS nodes keep those in a list */
typedef struct block_list {
/// Array with pointers to data blocks
void* data[MAX_DATABLOCKS];
/// Pointer to the next block_list in the list
struct block_list* next;
} block_list_t;
typedef struct vfs_node {
uint32_t mask; // The permissions mask.
uint32_t uid; // The owning user.
uint32_t gid; // The owning group.
uint32_t type; // Includes the node type. See #defines above.
/// The permissions mask.
uint32_t mask;
/// The owning user.
uint32_t uid;
/// The owning group.
uint32_t gid;
/// Includes the node type. See #defines above.
uint32_t type;
/// Open handler function pointer
open_type_t open;
/// Close handler function pointer
close_type_t close;
/// Read handler function pointer
read_type_t read;
/// Write handler function pointer
write_type_t write;
/// Read dir handler function pointer
readdir_type_t readdir;
/// Find dir handler function pointer
finddir_type_t finddir;
/// Make dir handler function pointer
mkdir_type_t mkdir;
/// Lock variable to thread-protect this structure
spinlock_t lock;
/// Block size
size_t block_size;
/// List of blocks
block_list_t block_list;
} vfs_node_t;
/** @brief Directory entry structure */
typedef struct dirent{
/// Directory name
char name[MAX_FNAME];
/// Corresponding VFS node pointer
vfs_node_t* vfs_node;
} dirent_t;
/** @brief Dir block structure which will keep directory entries */
typedef struct {
/// Array of directory entries
dirent_t entries[MAX_DIRENTRIES];
} dir_block_t;
extern vfs_node_t* fs_root; // The root of the filesystem.
/*
/** @defgroup fsfunc FS related functions
*
* Standard read/write/open/close/mkdir functions. Note that these are all suffixed with
* _fs to distinguish them from the read/write/open/close which deal with file descriptors,
* not file nodes.
*
* @{
*/
/** @brief Read from file system into the buffer
* @param node Pointer to the node to read from
* @param buffer Pointer to buffer to write into
* @param size Number of bytes to read
* @param offset Offset position of the source range
* @return
* - number of bytes copied (size)
* - 0 on error
*/
ssize_t read_fs(vfs_node_t * node, uint8_t* buffer, size_t size, off_t offset);
/** @brief Write into the file system from the buffer
* @param node Pointer to the node to write to
* @param buffer Pointer to buffer to read from
* @param size Number of bytes to read
* @param offset Offset position of the destination range
* @return
* - number of bytes copied (size)
* - 0 on error
*/
ssize_t write_fs(vfs_node_t * node, uint8_t* buffer, size_t size, off_t offset);
/** @brief Yet to be documented */
int open_fs(vfs_node_t * node, uint8_t read, uint8_t write);
/** @brief Yet to be documented */
int close_fs(vfs_node_t * node);
/** @brief Get dir entry at index
* @param node VFS node to get dir entry from
* @param index Index position of desired dir entry
* @return
* - The desired dir entry
* - NULL on failure
*/
struct dirent *readdir_fs(vfs_node_t * node, uint32_t index);
/** @brief Find a directory by looking for the dir name
* @param node The node where to start the search from
* @param name The dir name string
* @return
* - a VFS node pointer
* - NULL on failure
*/
vfs_node_t* finddir_fs(vfs_node_t * node, const char *name);
/** @brief Make a new directory in a VFS node
* @param node Pointer to the node where the dir is to create in
* @param name Name of the new directory
* @return
* - new VFS node pointer
* - NULL on failure
*/
vfs_node_t* mkdir_fs(vfs_node_t* node, const char* name);
/** @brief Find a node within root file system
* @param name The node name
* @return
* - VFS node pointer
* - NULL on failure
*/
vfs_node_t* findnode_fs(const char* name);
/* @} */
int null_init(vfs_node_t* node, const char* name);
int initrd_init(void);

View file

@ -17,6 +17,12 @@
* This file is part of MetalSVM.
*/
/**
* @author Stefan Lankes
* @file include/metalsvm/mailbox_types.h
* @brief Message type structure definitions for various task return types
*/
#ifndef __MAILBOX_TYPES_H__
#define __MAILBOX_TYPES_H__
@ -26,8 +32,13 @@
extern "C" {
#endif
/** @brief Wait message structure
*
* This message struct keeps a recipient task id and the message itself */
typedef struct {
/// The task id of the task which is waiting for this message
tid_t id;
/// The message payload
int32_t result;
} wait_msg_t;

View file

@ -54,7 +54,7 @@ int multitasking_init(void);
/** @brief create a kernel task.
*
* @param id The value behind this pointer will be set to the new task's id
* @param ep Entry point for the new task
* @param ep Pointer to the entry function for the new task
* @param arg Arguments the task shall start with
*
* @return
@ -66,14 +66,14 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg);
/** @brief Create a user level task.
*
* @param id The value behind this pointer will be set to the new task's id
* @param filename Filename of the executable to start the task with
* @param fname Filename of the executable to start the task with
* @param argv Pointer to arguments array
*
* @return
* - 0 on success
* - -EINVAL (-22) or -ENOMEM (-12)on failure
*/
int create_user_task(tid_t* id, const char* filename, char** argv);
int create_user_task(tid_t* id, const char* fame, char** argv);
/** @brief Block current task until the child task is terminated
* @param result The terminated child's return value

View file

@ -17,6 +17,12 @@
* This file is part of MetalSVM.
*/
/**
* @author Stefan Lankes
* @file include/metalsvm/time.h
* @brief Time related functions
*/
#ifndef __TIME_H__
#define __TIME_H__
@ -24,8 +30,23 @@
extern "C" {
#endif
/** @brief Initialize Timer interrupts
*
* This procedure installs IRQ handlers for timer interrupts
*/
int timer_init(void);
void timer_wait(unsigned int);
/** @brief Blocking wait function
*
* This function does no busy-wait.
*
* @param ticks Amount of ticks to wait
*/
void timer_wait(unsigned int ticks);
/** @brief Returns the current number of ticks.
* @return Current number of ticks
*/
uint64_t get_clock_tick(void);
static inline void sleep(unsigned int i) { timer_wait(i*TIMER_FREQ); }

View file

@ -17,6 +17,12 @@
* This file is part of MetalSVM.
*/
/**
* @author Stefan Lankes
* @file include/metalsvm/vma.h
* @brief VMA related sructure and functions
*/
#ifndef __VMA_H__
#define __VMA_H__
@ -33,14 +39,42 @@ extern "C" {
struct vma;
/** @brief VMA structure definition */
typedef struct vma {
size_t start, end;
/// Start address of the memory area
size_t start;
/// End address of the memory area
size_t end;
/// Type flags field
uint32_t type;
/// Pointer of next VMA element in the list
struct vma* next;
/// Pointer to previous VMA element in the list
struct vma* prev;
} vma_t;
/** @brief Add a new virtual memory region to the list of VMAs
*
* @param task Pointer to the task_t structure of the task
* @param start Start address of the new region
* @param end End address of the new region
* @param type Type flags the new region shall have
*
* @return
* - 0 on success
* - -EINVAL (-22) or -EINVAL (-12) on failure
*/
int vma_add(struct task* task, size_t start, size_t end, uint32_t type);
/** @brief Dump information about this task's VMAs into the terminal.
*
* This will print out Start, end and flags for each VMA in the task's list
*
* @param task The task's task_t structure
* @return
* - 0 on success
* - -EINVAL (-22) on failure
*/
int vma_dump(struct task* task);
#ifdef __cplusplus

View file

@ -17,6 +17,15 @@
* This file is part of MetalSVM.
*/
/**
* @author Stefan Lankes
* @file kernel/tasks.c
* @brief Implementations of task loading, killing, scheduling.
*
* This files contains all the implementations of different functions
* to start tasks with, wake them up, schedule them, etc.
*/
#include <metalsvm/stdio.h>
#include <metalsvm/stdlib.h>
#include <metalsvm/string.h>
@ -32,12 +41,18 @@
#include <asm/elf.h>
DEFINE_PER_CORE(task_t*, current_task, NULL);
static task_t task_table[MAX_TASKS] = {[0 ... MAX_TASKS-1] = {0, TASK_INVALID, ATOMIC_INIT(0), \
SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL}};
/** @brief Array of task structures
*
* A task's id will be its position in this array.
*/
static task_t task_table[MAX_TASKS] = {[0 ... MAX_TASKS-1] = \
{0, TASK_INVALID, ATOMIC_INIT(0), \
SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL}};
static spinlock_t table_lock = SPINLOCK_INIT;
/*
* helper function for the assembly code to determine the current task
/** @brief helper function for the assembly code to determine the current task
* @return Pointer to the task_t structure of current task
*/
task_t* get_current_task(void) {
return per_core(current_task);
@ -58,6 +73,10 @@ int multitasking_init(void) {
return -ENOMEM;
}
/** @brief Wakeup tasks which are waiting for a message from the current one
*
* @param result Current task's resulting return value
*/
static void wakeup_blocked_tasks(int result)
{
wait_msg_t tmp = { per_core(current_task)->id, result };
@ -76,6 +95,8 @@ static void wakeup_blocked_tasks(int result)
spinlock_unlock_irqsave(&table_lock);
}
/** @brief A procedure to be called by
* procedures which are called by exiting tasks. */
static void NORETURN do_exit(int arg) {
vma_t* tmp;
@ -98,7 +119,8 @@ static void NORETURN do_exit(int arg) {
drop_pgd(); // delete page directory and its page tables
if (atomic_int32_read(&per_core(current_task)->user_usage))
kprintf("Memory leak! Task %d did not release %d pages\n", per_core(current_task)->id, atomic_int32_read(&per_core(current_task)->user_usage));
kprintf("Memory leak! Task %d did not release %d pages\n",
per_core(current_task)->id, atomic_int32_read(&per_core(current_task)->user_usage));
per_core(current_task)->status = TASK_FINISHED;
reschedule();
@ -108,6 +130,7 @@ static void NORETURN do_exit(int arg) {
}
}
/** @brief A procedure to be called by kernel tasks */
void NORETURN leave_kernel_task(void) {
int result;
@ -115,14 +138,25 @@ void NORETURN leave_kernel_task(void) {
do_exit(result);
}
/** @brief To be called by the systemcall to exit tasks */
void NORETURN sys_exit(int arg) {
do_exit(arg);
}
/** @brief Aborting a task is like exiting it with result -1 */
void NORETURN abort(void) {
do_exit(-1);
}
/** @brief Create a task with a specific entry point
*
* @param id Pointer to a tid_t struct were the id shall be set
* @param ep Pointer to the function the task shall start with
* @param arg Arguments list
* @return
* - 0 on success
* - -ENOMEM (-12) or -EINVAL (-22) on failure
*/
static int create_task(tid_t* id, entry_point_t ep, void* arg)
{
int ret = -ENOMEM;
@ -166,6 +200,7 @@ create_task_out:
return ret;
}
int sys_fork(void)
{
int ret = -ENOMEM;
@ -243,13 +278,24 @@ int create_kernel_task(tid_t* id, entry_point_t ep, void* arg)
#define MAX_ARGS (PAGE_SIZE - 2*sizeof(int) - sizeof(vfs_node_t*))
/** @brief Structure which keeps all
* relevant data for a new task to start */
typedef struct {
/// Points to the node with the executable in the file system
vfs_node_t* node;
/// Argument count
int argc;
/// Environment var count
int envc;
/// Buffer for env and argv values
char buffer[MAX_ARGS];
} load_args_t;
/** @brief Internally used function to load tasks with a load_args_t structure
* keeping all the information needed to launch.
*
* This is where the serious loading action is done.
*/
static int load_task(load_args_t* largs)
{
uint32_t i, offset, idx;
@ -431,11 +477,22 @@ invalid:
return -EINVAL;
}
/** @brief This call is used to adapt create_task calls
* which want to have a start function and argument list */
static int STDCALL user_entry(void* arg)
{
return load_task((load_args_t*) arg);
}
/** @brief Luxus-edition of create_user_task functions. Just call with an exe name
*
* @param id Pointer to the tid_t structure which shall be filles
* @param fname Executable's path and filename
* @param argv Arguments list
* @return
* - 0 on success
* - -ENOMEM (-12) or -EINVAL (-22) on failure
*/
int create_user_task(tid_t* id, const char* fname, char** argv)
{
vfs_node_t* node;
@ -476,6 +533,7 @@ int create_user_task(tid_t* id, const char* fname, char** argv)
return create_task(id, user_entry, load_args);
}
/** @brief Used by the execve-Systemcall */
int sys_execve(const char* fname, char** argv, char** env)
{
vfs_node_t* node;
@ -552,6 +610,8 @@ int sys_execve(const char* fname, char** argv, char** env)
return ret;
}
/** @brief Called by tasks which are waiting for another task's
* return value. */
tid_t wait(int32_t* result)
{
wait_msg_t tmp = { -1, -1};
@ -571,6 +631,12 @@ tid_t wait(int32_t* result)
return tmp.id;
}
/** @brief Wakeup a blocked task
* @param id The task's tid_t structure
* @return
* - 0 on success
* - -EINVAL (-22) on failure
*/
int wakeup_task(tid_t id)
{
int ret = -EINVAL;
@ -590,6 +656,12 @@ int wakeup_task(tid_t id)
return ret;
}
/** @brief Block a running or ready task.
* @param id The task's tid_t structure
* @return
* - 0 on success
* - -EINVAL (-22) on failure
*/
int block_task(tid_t id)
{
int ret = -EINVAL;
@ -606,6 +678,10 @@ int block_task(tid_t id)
return ret;
}
/** @brief _The_ scheduler procedure
*
* Manages scheduling - right now this is just a round robin scheduler.
*/
void scheduler(void)
{
unsigned int i;