-
Notifications
You must be signed in to change notification settings - Fork 0
/
os-considerations.tex
163 lines (141 loc) · 9.35 KB
/
os-considerations.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
\section{Operating System Considerations}
\label{os-considerations}
Tanenbaum's \emph{Modern Operating Systems} asserts, ``The main property which
distinguishes embedded systems from handhelds is the certainty that no untrusted
software will ever run on it''~\cite{tanenbaum}. This was once true, but is no
longer the case. The Pebble~\cite{pebble} watch, for example, allows users to
load multiple third-party applications dynamically.
Embedded systems have traditionally been categorized by event-driven computation,
minuscule sleep currents, and constrained battery life. Existing embedded operating systems
have provided support for these properties and constraints. Providing support for concurrent, isolated
applications, as traditional operating systems do, provides a different set
of goals and challenges.
We argue that these these requirements and constraints create a new design space
for operating systems research.
% They do not provide a mechanism for granting applications arbitrary direct
% hardware access for performance or peripheral requirements purposes.
%
% Note: We won't either; they'll have to implement a platform or device driver
% to access hardware directly. This is somewhat analogous to kernel modules,
% which Linux provides, albeit that kernel modules are unsafe.
% In the first evolutionary cycle of embedded devices, applications were written
% as an integral part of the runtime environment on the device. The second
% cycle brought operating systems like TinyOS~\cite{tinyos}, Contiki~\cite{contiki}, FreeRTOS~\cite{freertos} and conceptually
% separated application and OS code. Development
% % became easier allowing
% % complexity of applications to remain manageable as they grew.
% simplified,
% but the resulting
% code still compiled to a monolithic image uploaded to the device.
% Now the third evolutionary cycle is emerging: multiple and independently
% developed applications co-existing on the same device (Pebble~\cite{pebble} watch),
% and modular embedded devices
% % are becoming modular. The latter is evident with
% % multi-billion companies like Samsung, Telefonica and GE innovating with
% (SimBand~\cite{simband}, Wzzard~\cite{wzzard}, ThinkingThings~\cite{thinkingthings}, and Spotter UNIQ~\cite{spotteruniq}).
% %~\endnote{http://www.samsung.com/us/globalinnovation/innovation_areas/}, Wzzard
% %~\endnote{http://bb-smartsensing.com/wzzard-sensing-platform/}, ThinkingThings
% %~\endnote{http://www.thinkingthings.telefonica.com/}, Spotter UNIQ
% %~\endnote{https://www.quirky.com/shop/982-spotter-uniq-customizable-multipurpose-sensor}
% % The aim is to create a core hardware platform where adding sensory
% % peripherals is done by the consumer in a Lego-like fashion while the developer compiles the
% % application with the provided SDK.
% %this paragraph needs rephrasing
% These trends completely change the way applications for the embedded devices
% have been developed over the last five decades. Developers have very little control over the
% application execution model, its coexistence with other application, and which
% peripherals are connected to the embedded device. Instead application developers
% expect that the underlying operating system will perform fair resource allocation,
% protecting the application from malicious or malfunctioning applications and
% peripherals.
\subsection{General-Purpose Requirements}
In traditional embedded systems, application code is completely trusted with
full access to all hardware resources. When a single developer both writes the
application and designs the hardware, this design is reasonable. However, new
embedded devices run third-party applications and allow the end-user to dynamically
load applications from app stores. A modern operating system for embedded
devices must support loading applications dynamically by the end-user. It must
also protect the hardware and kernel from these applications and applications
from one another. Modern general-purpose operating systems use hardware
features such as virtual memory and hardware virtualization to isolate
applications. While these features are not available in embedded
microcontrollers, embedded operating systems must use the tools at their
disposal to achieve similar goals.
\subsection{Embedded Requirements}
\label{sec:os:execution}
While attractive from a compatibility and bootstrapping perspective, porting
general-purpose operating systems, like Linux, to microcontrollers is not the
best solution. First, embedded systems today are still bound by power and
battery constraints. Second, embedded applications are significantly different
than applications on general-purpose systems. Embedded applications are
event-driven, responding to timers, packet arrival, sensor interrupts, etc.,
with short bursts of computation. General-purpose applications typically use
threaded execution, which may include long-running computations or latency
sensitive user interactions. General-purpose system support for event-driven
models has largely focused on latency, throughput, and
scalability~\cite{epoll,libasync,ninja}, rather than power draw, which is
typically more important in embedded devices. Finally, embedded applications
often require direct access to underlying hardware resources. Some
general-purpose operating systems have attempted to make dynamically loaded
drivers more safe by using lightweight hardware protection domains~\cite{nooks}
but do not offer the flexibility that many embedded applications may need. We
argue that in embedded systems, \emph{applications} should have direct access to
hardware resources when those resources are not shared or the hardware can do
isolation by itself~\cite{ix:osdi2014}.
% %% not sure if this figure is needed
% % \begin{figure}
% % \centering
% % \includegraphics[width=1\columnwidth]{img/appcycle.png}
% % \caption{Runnable life cycle.}
% % \label{fig:appcycle}
% % \end{figure}
% It's is not sufficient for a modern operating system allowing multiple
% simultaneous applications only have an event driven or preemptive
% multi-threading. In traditional OS the applications are not interrupted for
% longer period of times and in most of the cases there is no competition for
% resources. Resources need to be fairly distributed and applications, services or
% drivers notified upon event that effects program flow. Critical events are
% initialization of the application, the device is going to or waking up from low
% power mode as well secondary event like interrupts, timer, radio etc.
% % left here for event-driven e.g. Sergio add
% to allow attache new
% peripherals and load they drivers, start new services, and load/unload
% applications. The OS is expected to be a full scale modern OS except it has to
% handle all of the constrain of OS for embedded devices. Unlike most desktop and
% server applications, embedded applications must continue to run without end-user
% intervention. There is no console to indicate to the user that an application
% has crashed. Even if a crash could be communicated to the user, there is little
% action they could take. While a Blue-Screen-Of-Death is annoying on a desktop or
% server, it is unacceptable in embedded systems. Moreover, given the variety of
% devices, the OS should allow developer to use any language supporting
% Application Binary Interface, ABI.
% With resource sharing between applications and the end of exclusively trusted
% software on embedded devices comes the need for better protection guarantees
% from the operating system. The operating system must arbitrate and moderate
% access to hardware resources and protect kernel memory from misbehaving
% applications. Further, embedded applications must continue to run without
% end-user intervention as there is often little recourse for users to detect
% and correct system error.
% % isolation incoming somewere here
% Besides separating drivers for core peripherals (SPI, USART, GPIO, etc) and
% device drivers (radio, flash, etc) into separate layers. Modern OS has to
% enforce safety policies not only on applications but also on device drivers. The
% OS has to ensure that at most one driver has access to a specific hardware
% resource---multiplexing must be done explicitly in the core peripheral driver
% or through an intermediate interface. Finally, the OS need to ensure that
% device drivers cannot corrupt kernel memory or perform denial of service
% attacks by drivers. Multiple application on the embedded device also requires
% of to protect the kernel and other applications from malicious actions.
% While requirements have resemblance to those of a traditional OS, modern
% embedded OS has to fulfill them with the computational and energy constrains.
% energy efficency
% \name prevents drivers from subverting Rust's memory safety by restricting
% device drivers to a safe subset of the Rust language.~\endnote{Rust allows code
% to circumvent the type system using the \tt{unsafe} keyword. \name uses a
% compiler flag that disallows this keyword when compiling device drivers.} \name
% also ensures, at compile time, that at most one driver has access to a specific
% hardware resource---multiplexing must be done explicitly in the core peripheral
% driver or through an intermediate interface. Finally, \name ensures device
% drivers cannot corrupt kernel memory through careful choice of interfaces. \name
% ensures that \name does not protect the kernel from denial of service attacks by
% drivers. %wait what does this last sentence mean?