KOS is designed from the ground up to address common use cases for building hardware devices. Unlike mobile and cloud development, with many existing frameworks and patterns, device development is an area where developers must solve complex problems independently. KOS addresses this by providing not just architectural infrastructure but also corresponding frameworks all the way up through the UI layer to simplify many common problems and provide the foundational infrastructure that developers can build upon. The sections below highlight many of the core architectural choices made in KOS and offer some insight into overall platform capabilities.
Multi-node
While many devices consist of a single node running Linux, It’s becoming increasingly common that complex devices require multiple Linux nodes. In some cases, multiple nodes are contained in a single enclosure, with different nodes controlling different parts of the device. In other cases, the device may consist of distributed components, where each component may appear as a separate physical device, but in fact, they are all running as a single synchronized distributed device that works together.
While multi-node devices offer a lot of flexibility in many aspects of device design, they tend to be overwhelmingly complex to program. Even the simple goal of ensuring all nodes in the device are running compatible software can be enormously difficult to achieve. KOS is an inherently multi-node operating system that drastically simplifies building distributed devices but does so in a way that single-node devices don’t incur any additional complexity. This allows for a consistent and scalable api and development environment across various device architectures.
Every KOS device has one primary node and any number of secondary nodes. All nodes are managed by the primary, which ensures that every node runs the correct software version at all times. Combined with KOS firmware services, this provides device-wide atomic updates of software and firmware and atomic rollback support.
All core services within KOS are also multi-node enabled. This provides a consistent api on every node, and KOS will manage the complexities of synchronization and orchestration. This is all built upon layers of infrastructure within KOS, which provide network-transparent communications and network-transparent hardware integration, allowing hardware and services on different nodes to integrate seamlessly across a device. This infrastructure extends all the way up to the browser, even allowing applications running in browsers on different nodes to communicate directly with each other.
Linux
The base of the KOS stack is a custom Linux distribution that is tuned for small embedded environments. Unlike a typical Linux distribution constructed from packages or even a monolithic image, which is common in immutable Linux platforms, KOS Linux is split into a collection of immutable, digitally signed layers that can be combined at runtime to present a complete running user space environment. These layers are defined using a signed manifest, allowing the entire state of the os image to be highly granular while remaining fully immutable and verifiable on each boot. This is coupled with bootloader-level manifest management, which allows the entire os to support atomic updates and rollbacks where different versions of the os may share many of the same layers. This not only eliminates the classic A/B partition strategy, which saves considerable disk space but can also drastically reduce the size of updates as only layers that have been changed are required to boot a new version.
KOS Linux manifests are part of a larger device manifest that defines the entire software state of a device. As nodes boot into user space, a special node manager application coordinates across all nodes in the device. The node manager manages all system infrastructure, such as time synchronization, software updates, networking, and VPN setup, to ensure that all nodes in a device are in a deterministic and consistent state as defined by the device manifest. The node manager also acts as a KOS Studio agent, allowing developers to push code directly to any KOS device from their desktop environment, bypassing the typical board-specific flashing process. KOS Studio even provides a feature where the entire os of a device can be replaced for a single reboot cycle, after which it automatically reverts to the previous running os image—a useful feature when trying to leverage hardware resources in a shared lab setting.
Unlike the complexity of maintaining a custom Linux buildroot or yocto image, KOS releases provide simple checkbox options for which high-level features to include, such as browser, Java, graphics, and so on. There is no need to rebuild; simply check the options and hit the run button.
Java
KOS provides an extensive Java framework for device development, ranging from application-based development to hot-swap hardware detection and integration. In addition to high-level, complex functionality, the KOS java framework provides extensive support for common hardware development tasks such as advanced timer management, backoff algorithms, unit systems, localization, time/date change detection, etc. Many of these are designed to integrate with UI libraries tightly, drastically simplifying end-to-end development.
The KOS java framework is application-based. Unlike mobile development, which actively sandboxes applications, KOS applications are collaborative. Applications can share classes or collaborate using micro-services, either locally on the same node or across nodes in a device. Applications can load other applications, and third parties can share applications in the KOS Studio market. Applications have private data areas, local database support, virtual filesystem access, and the ability to mount immutable packages into the native filesystem, including bundles with native binaries and many other features and capabilities. The application framework allows what was historically monolithic code to be packaged separately and reused across devices. User interfaces, device agents, and so on can all be selected from inventory for inclusion in a device manifest and be automatically loaded when the device starts.
KOS also provides deep system-level integration into the Java framework. Java can access features such as udev events, network configuration, USB detection, process control, serial probing, etc. Not only on the local node but also across multiple nodes in the device. This means Java can manage processes, detect USB devices, and even probe serial devices on other nodes. This forms the basis for the hardware integration layer within KOS, which is entirely transparent to the network. Developers write adapters in native code using the KOS blink network protocol, and Java can manage any device on any node on any other node.
As the preferred ui display mechanism is a web browser, the Java framework provides sophisticated browser integration. A single node can support multiple browsers running on different nodes or even multiple browsers running on a single node. KOS introduces a browser intent system that allows applications to interact at the navigation level without directly processing URLs. Java applications can expose endpoints by simply annotating methods.
KOS also introduces a websocket router, which is a routed websocket mesh network. This allows network transparent communication between all Java instances and all browser applications. This enables advanced capabilities like mixing HTTP and broker traffic over the same connection. Consider an endpoint that performs long-running operations, such as priming a pump. The standard HTTP model doesn’t provide any easy way to push progress information back to the client. KOS provides a standard Java and ui abstraction for asynchronous work that leverages the websocket router to both call and endpoint and track the progress to completion.
UI
The KOS UI Framework is a counterpart to KOS Java-based services, enhancing the overall development process. Here’s a deeper look at its features:
At its core, the framework has an abstraction layer that normalizes the use of HTTP and WebSockets, promoting resilient web development practices. This layer includes tooling that replaces traditional browser fetch functionalities tailored specifically for KOS applications. It offers optimized performance and resilience, adapting to the idiosyncrasies of the KOS environment.
State management is central to the KOS UI Framework, facilitated by a robust model framework. This framework supports incremental updates through a topic-based messaging system integrated into the Java backend. It provides a structured approach to managing lifecycle events, respecting the dependencies and containment relationships among models. This allows for sophisticated data modeling with minimal overhead for cleanup, ensuring efficient memory and resource management. Optimized for development in TypeScript, the framework supports declarative, decorator-based development that is more natural to traditional Java developers.
Models within the framework are observable by design. This feature supports fine-grained updates in the UI, allowing the system to refresh only the parts of the UI that are affected by underlying data changes. This leads to more efficient rendering and reduced system load during updates.
The framework is built to handle long-running asynchronous tasks effectively. It offers built-in mechanisms for progress updates and the ability to cancel operations. This ensures that applications can manage tasks that take extended periods without freezing the UI, providing a better user experience.
The KOS UI tooling provides advanced localization support, which includes comprehensive tools for application-level translations. This allows developers to implement multi-tiered locale systems that seamlessly adapt to complex regional and linguistic requirements. The framework’s deep integration with backend localization services ensures that applications can cater to a global audience while maintaining the nuances of local languages and formats.
The KOS UI Framework features a sophisticated configuration property management system that facilitates comprehensive settings management, allowing developers to define, manipulate, and persist properties across various application levels. A standout feature within this management system is its support for automated unit conversion, which is useful for operating across different regions while supporting consistent persistence policies. It automatically adjusts measurement units like temperature, volumes, and flow rates to match the regional settings of the user’s environment, ensuring seamless adaptability and user experience.
To enhance the development experience, the framework supports various tools, including CLI and IDE plugins. These tools streamline adding new models and components, which are pre-configured to integrate smoothly with the existing system framework. This integration facilitates a smoother workflow for developers, reducing the setup time and complexity typically associated with configuring new elements in a development project.
Overall, the KOS UI Framework provides rich tools and capabilities to streamline the development of integrated device applications, enhancing developer efficiency and performance.
Native
Native device development is typically complicated by configuring and installing cross-compiler toolchains. This is complex and requires frequent updates to keep libraries in sync with targeted os versions. KOS provides a full native toolchain for every supported target, which can be included in a release with the check of a box. Installing the exact toolchain for a release is as easy as hitting the run button in KOS Studio. This allows the native device to be used for local development. In addition, if the native architecture of a developer laptop aligns with the architecture of the target hardware, the native toolchain can also be run in a desktop simulator. This provides quick and easy access to native tools aligned with the targeted release.
The most common need for native development is hardware integration into KOS, and the standard model for integrating hardware is to write an adapter. KOS adapters use a network socket to connect to Java using the KOS binary-link (Blink) library. This provides a command-response channel from Java to native and an event channel from native to Java. Blink messages are extremely efficient binary-packed structures, and Blink supports endian transparency, so native code works with native structures in native format. Since Blink is network-based, this also allows adapters to be run on real hardware but points to Java running in a desktop simulator, which combines the speed and convenience of working on a laptop with the accuracy of working with real hardware.
While native applications can be packaged in os layers to make them appear in the native filesystem, they can also be bundled with Java applications, either with the application itself or as data. KOS provides sophisticated FUSE integration, which allows Java to mount any component into the native Linux filesystem, so applications can bundle native code, mount them via FUSE, and run them natively.
