KOS is designed from the ground up to address common use cases for building hardware devices. Unlike mobile and cloud development, where there are many existing frameworks and patterns, device development tends to be an area where developers need to solve complex problems on their own. KOS addresses this by providing not just architectural infrastructure, but also corresponding frameworks all the way up through the ui layer, to both simplify many common problems as well as provide 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.
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 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 a range of 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 is running the correct version of software at all times. Combined with KOS firmware services, this provides device-wide atomic updates of software and firmware as well as 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 as well as network transparent hardware integration, allowing hardware and services on different nodes to be seamlessly integrated 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.
The base of the KOS stack is a custom Linux distribution which is tuned for small embedded environments. Unlike a typical linux distribution that is 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 which 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. Node manager manages all system infrastructure such as time synchronization, software update, 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. Node manager also acts as a KOS Studio agent, allowing developers to push code directly to any KOS device directly 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 back to the previous running os image. A useful feature when trying 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. No need to rebuild, simply check the options and hit the run button.
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 also provides extensive support for common hardware development tasks such as advanced timer management, backoff algorithms, unit systems, localization, time / date change detection and so on. Many of these are designed to tightly integrate with ui libraries, 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 can 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, the ability to mount immutable packages into the native filesystem, including bundles with native binaries, along with 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, call 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 has access to features such as udev events, network configuration, usb detection, process control, serial probing and so on. Not only on the local node, but even 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 network transparent. Developers write adapters in native code using the KOS blink network protocol and any device on any node can be managed by java on any other node.
As the preferred ui display mechanism is a web browser, the java framework also 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 which allows applications to interact at the browser navigation level without the need to process urls directly. 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 as well as all browser applications. This enables advanced capabilities such as the ability to mix http and broker traffic over the same connection. Consider an endpoint that performs a 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.
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 to 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 modelling 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 management of settings, 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 the process of 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 a rich set of tools and capabilities designed to streamline the development of integrated device applications, enhancing both developer efficiency and application performance.
Native development for devices is typically complicated by the need to configure and install cross compiler toolchains. Not only is this complex, but it 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 that are always aligned with the targeted release.
The most common need for native development is for 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 point 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 then natively.