diff --git a/.gitignore b/.gitignore index 244ebdef..d237657d 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ diff --git a/Doxyfile b/Doxyfile index 8a16db2e..352ee44e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -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 diff --git a/documentation/doxy_mainpage.h b/documentation/doxy_mainpage.h new file mode 100644 index 00000000..1420ef75 --- /dev/null +++ b/documentation/doxy_mainpage.h @@ -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. + * + */ diff --git a/documentation/img/lfbs_logo.gif b/documentation/img/lfbs_logo.gif new file mode 100644 index 00000000..2760f9bc Binary files /dev/null and b/documentation/img/lfbs_logo.gif differ diff --git a/documentation/img/metalsvm_stack.jpg b/documentation/img/metalsvm_stack.jpg new file mode 100644 index 00000000..7b47ad79 Binary files /dev/null and b/documentation/img/metalsvm_stack.jpg differ diff --git a/documentation/img/rwth_logo.gif b/documentation/img/rwth_logo.gif new file mode 100644 index 00000000..d5db607b Binary files /dev/null and b/documentation/img/rwth_logo.gif differ diff --git a/documentation/tmpl/footer.html b/documentation/tmpl/footer.html new file mode 100644 index 00000000..6725e7cd --- /dev/null +++ b/documentation/tmpl/footer.html @@ -0,0 +1,4 @@ + + + diff --git a/documentation/tmpl/header.html b/documentation/tmpl/header.html new file mode 100644 index 00000000..b1a6a471 --- /dev/null +++ b/documentation/tmpl/header.html @@ -0,0 +1,27 @@ + + + + + $title + + + + + + + +
+
+ + + + + + +
+
MetalSVM
+ + +
A Bare-Metal Hypervisor for Non-Coherent Memory-Coupled Cores
+
+
diff --git a/documentation/tmpl/stylesheet.css b/documentation/tmpl/stylesheet.css new file mode 100644 index 00000000..125800f1 --- /dev/null +++ b/documentation/tmpl/stylesheet.css @@ -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; +} + diff --git a/include/metalsvm/fs.h b/include/metalsvm/fs.h index 60a4541e..56eba752 100644 --- a/include/metalsvm/fs.h +++ b/include/metalsvm/fs.h @@ -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); diff --git a/include/metalsvm/mailbox_types.h b/include/metalsvm/mailbox_types.h index f4d09c64..2e400562 100644 --- a/include/metalsvm/mailbox_types.h +++ b/include/metalsvm/mailbox_types.h @@ -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; diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index 43bc7892..904f737a 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -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 diff --git a/include/metalsvm/time.h b/include/metalsvm/time.h index b793169d..4c2cdf51 100644 --- a/include/metalsvm/time.h +++ b/include/metalsvm/time.h @@ -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); } diff --git a/include/metalsvm/vma.h b/include/metalsvm/vma.h index 7f3b3953..449e81da 100644 --- a/include/metalsvm/vma.h +++ b/include/metalsvm/vma.h @@ -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 diff --git a/kernel/tasks.c b/kernel/tasks.c index 144026fc..3582a9f9 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -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 #include #include @@ -32,12 +41,18 @@ #include 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;