118 lines
4.8 KiB
TeX
118 lines
4.8 KiB
TeX
%% SCRAP: hardware/PLATFORM_BUILD_GUIDE
|
|
%% SOURCE: docs/working/hardware/PLATFORM_BUILD_GUIDE.adoc
|
|
%% STATUS: CURRENT
|
|
%% FITS: dev-guide/ch-build
|
|
%% EDITORIAL: lifted — prose rewritten to press voice
|
|
|
|
\section{Platform Build Guide}
|
|
|
|
StarForth builds for both POSIX hosts and the L4Re microkernel from a single
|
|
codebase, selected by one Makefile switch. The POSIX path is the default; the
|
|
L4Re path is enabled with \texttt{L4RE=1}.
|
|
|
|
\begin{lstlisting}[language=bash]
|
|
# POSIX build (Linux/macOS/BSD) -- default
|
|
make
|
|
make fastest
|
|
make pgo
|
|
|
|
# L4Re/StarshipOS build
|
|
make L4RE=1
|
|
|
|
# Clean switch between platforms
|
|
make clean && make L4RE=1
|
|
\end{lstlisting}
|
|
|
|
\subsection{Platform Abstraction Files}
|
|
|
|
The platform layer isolates timing and clock functionality behind a small set
|
|
of files. The remainder of the VM is untouched by the platform choice.
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
File & Purpose & Platform \\
|
|
\midrule
|
|
\texttt{include/platform\_time.h} & Abstraction API & All \\
|
|
\texttt{src/platform/platform\_init.c} & Platform selector & All \\
|
|
\texttt{src/platform/time\_posix.c} & POSIX implementation & POSIX \\
|
|
\texttt{src/platform/time\_l4re.c} & L4Re implementation & L4Re \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Platform abstraction source files.}
|
|
\end{table}
|
|
|
|
Only three core files consume the abstraction: \texttt{src/log.c} (timestamps
|
|
via \texttt{sf\_realtime\_ns()} and \texttt{sf\_format\_timestamp()}),
|
|
\texttt{src/profiler.c} (monotonic timing via \texttt{sf\_monotonic\_ns()}),
|
|
and \texttt{src/main.c} (calls \texttt{sf\_time\_init()} at startup). All other
|
|
VM core files, word implementations, and the block I/O system are unchanged.
|
|
|
|
\subsection{L4Re Time Backend}
|
|
|
|
The L4Re RTC server provides hardware RTC access (x86 I/O ports, ARM PL031,
|
|
I2C chips), nanosecond precision via the CPU timestamp counter, an IPC
|
|
interface for getting and setting time, and suspend/resume handling that
|
|
refreshes the offset on wakeup. The C API lives in \texttt{librtc.a}:
|
|
|
|
\begin{lstlisting}[language=C]
|
|
l4_uint64_t l4rtc_get_timer(void);
|
|
int l4rtc_get_offset_to_realtime(l4_cap_idx_t server, l4_uint64_t *ns);
|
|
int l4rtc_set_offset_to_realtime(l4_cap_idx_t server, l4_uint64_t ns);
|
|
\end{lstlisting}
|
|
|
|
StarForth's L4Re backend behaves as follows. Initialization attempts to obtain
|
|
the \texttt{"rtc"} capability from the L4Re environment, queries the RTC offset
|
|
by IPC when found, and falls back to a zero offset (epoch time) otherwise.
|
|
Monotonic time always works without an RTC, reading
|
|
\texttt{l4\_kip\_clock\_ns(l4re\_kip())} directly from the Kernel Info Page.
|
|
Real time returns the RTC offset plus the KIP clock, or zero when no RTC is
|
|
available. Setting time computes a new offset from the desired time minus
|
|
uptime and writes it via IPC, which requires write permission on the
|
|
\texttt{"rtc"} capability.
|
|
|
|
L4Re's libc already provides working \texttt{clock\_gettime},
|
|
\texttt{time}, \texttt{localtime}, and \texttt{strftime}. The platform
|
|
abstraction is retained anyway for direct control over the RTC capability,
|
|
explicit handling of a missing RTC, a portable API across all platforms, and
|
|
to avoid a libc dependency in minimal builds.
|
|
|
|
\subsection{Testing}
|
|
|
|
For the POSIX build, confirm timestamped log output and a non-zero RTC check:
|
|
|
|
\begin{lstlisting}[language=bash]
|
|
make clean && make
|
|
./build/starforth --log-info
|
|
\end{lstlisting}
|
|
|
|
For the L4Re build inside the StarshipOS tree, \texttt{make l4} selects the
|
|
L4Re backend automatically; running under \texttt{scripts/runos.sh} should
|
|
show working profiler timing (always available via the KIP clock) and working
|
|
timestamps, which may report 1970 if no RTC server is present. A
|
|
syntax-checking script can validate both backends without a full L4Re tree by
|
|
compiling \texttt{time\_l4re.c} with \texttt{-fsyntax-only} (a fatal error on
|
|
missing L4Re headers is expected) and compiling the POSIX backend and selector
|
|
cleanly.
|
|
|
|
\subsection{Troubleshooting}
|
|
|
|
\begin{itemize}
|
|
\item \emph{undefined reference to sf\_monotonic\_ns} --- ensure
|
|
\texttt{time\_posix.c} and \texttt{platform\_init.c} are compiled.
|
|
\item \emph{implicit declaration of sf\_time\_init} --- add
|
|
\texttt{\#include "platform\_time.h"}.
|
|
\item \emph{fatal error: l4/re/env.h: No such file or directory} ---
|
|
expected outside the L4Re tree; build through the StarshipOS build system.
|
|
\item \emph{RTC server not found} --- start the RTC server in the loader
|
|
script and provide the \texttt{rtc} capability.
|
|
\item \emph{Timestamps show 1970-01-01} --- the RTC server is not supplying
|
|
an offset; check the vbus configuration and hardware RTC.
|
|
\end{itemize}
|
|
|
|
The result is a complete platform abstraction layer that builds on POSIX and
|
|
L4Re alike, with zero runtime overhead from inline functions and a clean
|
|
vtable-style separation. Switching platforms requires only \texttt{make
|
|
L4RE=1}; the core VM is unchanged.
|