This commit is contained in:
Dmitry Zavalishin 2019-11-27 12:48:02 +03:00
parent 0341bb9121
commit 6dbea2fdfb
9 changed files with 584 additions and 0 deletions

View File

@ -1,6 +1,12 @@
# openpod
OpenPOD portable driver specification sources an examples
Goal of this project is to define driver API for experimental and special
purpose operating systems.
Current documents are in Russian, so, please, look into the sources and
headers. English docs are in progress to.
NB!
Current state of these sources: raw drafts, just compiled, no real working code.

3
dox/source/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"restructuredtext.confPath": "${workspaceFolder}"
}

171
dox/source/conf.py Normal file
View File

@ -0,0 +1,171 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.doctest']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'OpenPOD drivers API'
copyright = '2019, Dmitry Zavalishin'
author = 'Dmitry Zavalishin'
# -----------------------------------------------------------------------
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0.1-0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
'navigation.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'OpenPODdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'OpenPOD.tex', 'OpenPOD drivers API',
'Dmitry Zavalishin', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'openpod', 'OpenPOD drivers API',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'OpenPOD', 'OpenPOD drivers API',
author, 'OpenPOD', 'Portable drivers API specification.',
'Miscellaneous'),
]

View File

@ -0,0 +1,43 @@
==============
Directory tree
==============
GitHub project directory tree:
**src**
Source code
**openpod**
Headers.
**libs**
Libraries of default functions and support subsystems for OpenPOD drivers.
**os**
Example bindings for some operating systems.
**test**
Regress test suite. Work in progress.
**examples**
Code examples.
**modules**
Loadable kernel modules. Mostly experimental.
**barebones**
Driver skeletons: starting points to implement or port a driver.
**dox**
Sources for this document,

View File

@ -0,0 +1,6 @@
========================
Simplest driver skeleton
========================
Please see ``barebones/simple`` directory for this example's source code.

0
dox/source/img/.keep Normal file
View File

74
dox/source/index.rst Normal file
View File

@ -0,0 +1,74 @@
.. toctree::
:maxdepth: 3
.. rem :caption: Contents:
"""""""""""""""""""""""""""""""""""""""
OpenPOD: Portable drivers specification
"""""""""""""""""""""""""""""""""""""""
............
Introduction
............
OpenPOD is a specification of a driver API, structure and lifecycle.
Aim of this specification is to provide small and alternative operating systems
with common basis to share drivers around.
Source codes for the project (and for this book) can be found in `OpenPOD GitHub`_ repository.
.. _OpenPOD GitHub: https://github.com/dzavalishin/openpod/
.. only:: html
.. rem Package version |version|.
You can also get this document in `PDF format`_.
.. _PDF format: https://buildmedia.readthedocs.org/media/pdf/phantomdox/latest/phantomdox.pdf
.. include:: introduction.rst.inc
.................
Project structure
.................
.. include:: directories.rst.inc
................
Driver structure
................
.. include:: structure.rst.inc
.........
Reference
.........
.. REM .. include:: api.rst.inc
This section is not ready yet.
.. REM ......................
.. REM Implementation details
.. REM ......................
.. REM .. include:: implement.rst.inc
.....................
Examples
.....................
.. include:: examples.rst.inc

View File

@ -0,0 +1,39 @@
There are tens of operating system projects in the world.
From tiny experimental works to medium size projects to big and old ones with
a bing community.
All of them need drivers. All of OS authors work on quite the same drivers from early start
and for ever and ever.
It seems just natural for OS authors community to define a standard for a driver API to
share work around and help each other.
This document is an attempt to start such effort.
Goal is to define API and driver structure that is:
* **Simple enough.** There were previous efforts to define portable driver API which required
driver (even simplest one) to be unnecessarily complex. This specification lets driver
author to start from a simple skeleton and make trivial driver in a day or so.
* **Extencible.** It must let complex and specific driver to have reach API into the kernel which
does not limit driver designer too much and does not enforce him to come around and add non-standard
entry points.
* **Support different device classes naturally.** Video and network drivers are really different and
provide APIs that have quite nothing in common. But drivers in each class generally provide identical
entry points.
* **Support runtime device addition and removal.** Driver must be able to inform kernel about status change
and add or remove devices in run time.
* **Support drivers providing different types of devices.** PS2 driver exports both keyboard and mouse. Video
card driver can provide sound device for an HDMI port, and so on.
* **Let driver to be both statically and dynamically linked.** Though, current specification is not really checked
in a project with a dynamic driver loading, there is corresponding support in API and data structures.
Current state of specification: It is partially complete and waits for your comments.
The best way to comment is to create an issue in project's GitHub repository: <https://github.com/dzavalishin/openpod/issues>.

View File

@ -0,0 +1,242 @@
OpenPOD driver includes:
* **Driver descriptor.** A structure that defines global (not device specific) properties an
entry points.
Driver descriptor is a required part of a driver.
* **Device descriptor.** A structure which describes each device exported by driver. Can be single and
static, or can be dynamically allocated in run time. For example, USB disk driver can create device
descriptors dynamically as devices come and go.
Device descriptor is not a required part - there can be driver which does not export devices at all
or just starts with empty set of devices. But most drivers will provide at least one device at start.
* **Driver and/or device properties.** Set of key=value parameters to control driver or device and
request meta information. For example, sound driver can set sampling rate with corresponding
property.
Properties are optional part of specification.
=======================
Driver and device class
=======================
Device class specifies API this device exports to the kernel.
.. code:: c
#define POD_DEV_CLASS_VOID 0 // No API.
#define POD_DEV_CLASS_SPECIAL 1 // Has user defined nonstandard interface
#define POD_DEV_CLASS_VIDEO 2 // Framebuf, bitblt io
#define POD_DEV_CLASS_BLOCK 3 // Disk, cdrom: block io
#define POD_DEV_CLASS_CHARACTER 4 // Tty, serial, byte io
#define POD_DEV_CLASS_NET 5 // Packet IO, has MAC address
#define POD_DEV_CLASS_KEYBD 6 // Key (make/break) events
#define POD_DEV_CLASS_MOUSE 7 // Mouse coordinate events
#define POD_DEV_CLASS_MULTIPLE 0xFF // Driver only, has multiple dev types
.. note:: Sound driver class is missing.
Sound device is, basically a character (byte stream) device, but separate class
can help kernel to classify and connect driver in a special way.
=================
Driver descriptor
=================
--------------
Driver methods
--------------
**pod_construct**
Driver initialization. Driver must allocate structures and do any setup required
but do not scan hardware or attempt to export devices. This stage can be empty.
.. code:: c
errno_t pod_construct( pod_driver *drv ); // ENOMEM
**pod_destruct**
Complete driver destruction. Driver must free all resources, stop threads,
release OS objects (such as mutexes and conds). Driver can be unloaded after
this call.
It is assumed that ``deactivate`` was called before this call. Nevertheless
if no ``deactivate`` was called driver must attempt to do its best to deactivate
self before desctruction. If it is not possible, this call can fail.
.. code:: c
errno_t pod_destruct( pod_driver *drv );
**pod_activate**
Start driver. Prepare and activate hardware. Inform kernel
about all devices this driver exports. See ``pod_dev_link``.
This call is done before any IO is attempted by kernel.
Until this call driver must refuse to do any IO.
Hardware scan must be done before this call.
.. code:: c
errno_t pod_activate( pod_driver *drv );
**pod_deactivate**
Stop driver. Reset and stop hardware. Revoke all
exported devices. See ``pod_dev_unlink``.
.. code:: c
errno_t pod_deactivate( pod_driver *drv );
**pod_sense**
Look for hardware to exist and be operational. Scan for
devices that can be operated by this driver.
Devices must be found but not exported to kernel or started.
It is ok to call kernel entry points to scan hardware, such as
PCI enumeration functions.
.. code:: c
errno_t pod_sense( pod_driver *drv );
**pod_probe**
This is a call from kernel with an offer of a device to handle.
Driver must check if this device can be handled and accept or refuse
to handle it. As with ``pod_sense`` accepted device should not be
started or exported to kernel during processing of this call.
This entry point is not finally defined. Request for comments.
.. code:: c
errno_t pod_probe( pod_driver *drv, bus?, dev? ); // ENOMEM, EFAULT
-----------------
Driver life cycle
-----------------
Defines driver initialization, start, search for hardware, stop and resource release stages.
Basic life cycle:
* Kernel calls ``pod_construct``, driver allocates data strutures and resources (mutexes, threads, etc).
* Kernel calls ``pod_sense`` and/or ``pod_probe``, driver looks for hardware and decides on list of
devices that exist and can be served.
* Kernel calls ``pod_activate``, driver exports to kernel known devices with calls to ``pod_dev_link``.
* Driver serves IO requests. If devices come or go driver calls ``pod_dev_link`` / ``pod_dev_unlink`` to
inform kernel.
* Kernel calls ``pod_deactivate``, driver deregisters all devices.
* Kernel calls ``pod_destruct``, driver releases all resources.
* Kernel can unload driver at this point.
=================
Device descriptor
=================
.. code:: c
struct pod_device {
uint32_t magic;
uint8_t class;
uint8_t pad0;
uint8_t pad1;
uint8_t flags;
pod_driver *drv;
pod_dev_f *calls;
pod_properties *prop;
void *class_interface;
void *private_data;
// Fields below are used by default framework code
// Request queue, used by pod_dev_q_ functions
pod_q *default_r_q; // default request q
pod_request *curr_rq; // request we do now
pod_thread *rq_run_thread; // thread used to run requests
pod_cond *rq_run_cond; // triggered to run next request
};
--------------
Device methods
--------------
**pod_dev_stop**
Stop device. Called after all IO is done and all possible users disconnected.
In Unix like OS this entry point is called after device was closed by least
process. No IO can be done after stop.
**pod_dev_start**
Start device. Called before first IO attempt on device.
In Unix like OS corresponds to open system call for this device.
.. code:: c
errno_t pod_dev_stop( pod_device *dev );
errno_t pod_dev_start( pod_device *dev );
**pod_rq_enqueue**
Start asyncronous IO on device.
**pod_rq_dequeue**
Revoke IO request previously enqueued by ``pod_rq_enqueue``, if
possible. Can fail if IO is already in progress.
This entry point is optional.
**pod_rq_fence**
Make sure that all IO started before this call is finished.
Can return instantly or wait for all previous IO is complete.
In any case must guarantee that on call to request callback
for this request all previously enqueued requests are complete
and callbacks for them are finished too.
**pod_rq_raise**
Change (usually - rise:) request priority.
Optional, but for disk IO it is really good thing to have.
.. code:: c
errno_t pod_rq_enqueue( pod_device *dev, pod_request *rq );
errno_t pod_rq_dequeue( pod_device *dev, pod_request *rq );
errno_t pod_rq_fence( pod_device *dev, pod_request *rq );
errno_t pod_rq_raise( pod_device *dev, pod_request *rq, uint32_t io_prio );
-----------------
Device life cycle
-----------------