Project maintainers


Name: taar
Created: Dec 16, 2017
Updated: Aug 15, 2022
SVN: No files checked in
Bugs: 1 reported / 0 solved
Star6you like it: star it!

Other project properties

Category:System on Chip
Development status:Planning
Additional info:
WishBone compliant: No
WishBone version: n/a
License: GPL

Project Kosmos - Introduction ( project formerly known as Taar )

This open source project currently comprises a SoC ( System-on-Chip ) type microprocessor and a microkernel-based operating system which are being designed to complement each other. A necessary factor here is to keep the processor and OS architectures as simple as possible, general purpose, reliability-capable and elegant and this has resulted in the processor architecture going away from traditions in multiple things.

This document is a design specification based on which further processor and OS architecture will be defined. In this document the processor's details are given first and then the OS'.

The name of the project comes from two sources :

  1. The Russian word Kosmos meaning Space, what is beyond the limits of Earth or any world, to indicate that this project is also intended to be used in spacecraft, spacesuits and vehicles and habitats meant to work on other worlds - all in due time, but also to indicate the large universality of the application of the project.
  2. The Greek word Kosmos whose one meaning I find appropriate : "1. Kosmos is found in Greek writings from Homer down with the basic meaning of "an apt and harmonious arrangement or constitution". A condition of orderliness, orderly arrangement, order. It denotes what is well assembled or constructed from its individual parts. " The derived meaning indicating in the project that the processor hardware is meant to work in harmony with the operating system software written specifically for the processor - the OS software complementing the processor hardware.

The project name, Kosmos, currently describes a SoC that is entirely electronic but in future versions the name will describe a SoC where will be bio-electronics-based additional computation unit, additional memory unit and eyes. So Kosmos will be a series of SoCs.

The humanist, simplifying, thoughtful and Nature-abiding ideology of the Kosmos project will be enhanced by having as its anthem the song Shob lokey koy, a beautiful mixing in Coke Studio Bangla of the thoughts of two South Asian philosophers of older times - Lalon Fakir and Kabir Das. As one of the comments on the video page puts it, this song should really be adopted as the anthem of the United Nations Organization.

Project contributors

Vishal Zuluk.

Kosmos processor version 1 overview

The Kosmos version 1 SoC processor has two broad parts : (a). Digital data-processing part, (b). I/O.

In the digital data-processing part the processor is arranged as a vector processor with an Instruction Dispatch Unit and multiple Instruction Execution Units. The Instruction Dispatch Unit doesn't operate on a clock and all Instruction Execution Units have a common design and execute in lock step upon the same instruction but using different data. The number of Instruction Execution Units can vary in chip production depending on the application of the SoC. The instruction execution happens on a 32-bit addressing and 32-bit data processing basis and depending on the instruction the data can be integer or real. Integers will be used only for bitwise logic operations like 'and' and 'xor'. For mathematical operations like 'add' only real numbers will be used and real numbers here will be computed through the recent Posit Number System which I am still getting to know and will use the system as is or a simplified variation. Integer-based mathematical operations aren't present because I think the system will be simpler if there is consistent circuitry and just one programming data type for mathematical operations by using just Posit. Further, multimedia operations will be done through special generic instructions which I don't think need fixed integer-based mathematical instructions ( add, sub, mul ) and these generic multimedia instructions will be vectorized to enable not only fast software-based decoding of multimedia formats but also enable machine learning. There will be addition of instructions also with the furthering of the kernel design. There is no subroutine stack in the processor i.e. Kosmos is a stackless processor.

The I/O part of the SoC is the Molecule subsystem which is adapted from the PCI Express standard and the RapidIO architecture and :

As an SoC subsystem it enables the addresses and data generated within the SoC to be exchanged with the devices outside the SoC, and routes data between the devices outside the SoC. So the Molecule circuitry is a central routing system.

Outside the SoC at physical layer it will electrically consist of four pairs of differential-signaling-based single-lane bi-directional serial interfaces.

At data link layer each of the serial interfaces can transceive data prefixed with an four-byte common protocol header which is as below :

-------> Source Data Type ( 3 bits )
-------> Source Device Type ( 5 bits )
-------> Unused ( 3 bits )
-------> Destination Device Type ( 5 bits )
-------> Count Of Data Blocks Being Transferred ( 8 bits )
-------> Number Of Data Block Being Currently Transferred ( 8 bits )

After the header will come 17-byte-long formatted or unformatted data blocks specific to the device.

In the header :

-------> "Data Type" can be either of : Get Device Information = 000b, Reset All Devices = 001b, Configure Device = 010b, Put Device To Idle = 011b, Device Plugged Status Change = 100b, Normal Data Transfer To Device = 101b, Normal Data Transfer From Device = 110b, Device Is In Error = 111b.
-------> About "Device Type" : Currently there are 15 device types that the Molecule system connects to : Main Kosmos SoC; Assistant Kosmos SoC; Data / Program RAM interconnect; System power control and status; Button; General purpose timer; Watchcat timer; Flash storage; System environment interface; Camera; LiDAR; Imagery output unit; WiFi transceiver; Optical communication transceiver; Microphone and speaker.
-------> Examples of "Device Type" settings are : Button = 00001b, WiFi = 00100b.
-------> About "Count Of Data Blocks Being Transferred" : Each data block is 17 bytes long meaning the max data transferrable from / to a device in one transfer session is 4352 bytes because the byte represented by this field can carry 256 values ( 0 to 255 ) so 17 x 256 = 4352. The 17-byte transfer has been chosen because a Kosmos processor instruction is 136 bits long i.e. 17 bytes.

Molecule interrupts will be generated within the SoC as per the device.

The device type "System environment interface" refers to sensors for temperature and electrical radiation.

The SoC is overall a simpler processor in the larger scheme of things and is meant to be used in a wearable computer, in embedded systems and server systems all with intelligent visual data processing even with external analog phenomena ( like analog meters, multiple microphones outputting through LED pulses of varying brightness, optic-fiber-based vehicle parking sensor data ).

After a comfortable round of design the SoC can be ready for an FPGA implementation and the source code(s) presented through the channels.

An application of Kosmos SoC - The wearable computer

The wearable computer's form will be undisclosed as of now but its visual-based input subsystem will sense touches and movement that will allow three ways of usage : (a). Button selection, menu selection and regular typing, (b). Free hand colored drawing with a finger or stylus, (c). Colored drawing with geometric instruments like a scale. The input will be made either in the space just in front of the camera or on a flat surface for drawing. Having a visual camera for input also enables short-range augmented reality.

The wearable's wireless communication will be through the WiFi standard ( the exact standard from the WiFi IEEE 802.11 series is yet to be decided ). WiFi has been selected because of its general purposeness and lending itself more to political appropriateness. The reasoning is below :

  1. Political appropriateness : Telecommunication, whether voice or video or internet, must not be made available in exchange of money but be free for use by every person because communication, whether in-person or over a telecom device, is a fundamental human right that should not be arranged by a third party in exchange of money as that would be extortion which is not rational and morally legal.

  2. Unlike 4G mobile telephony there is no need in WiFi networks to remember some complicated phone number of the one you need to communicate with. It is often the case that people using mobile telephones aren't able to remember more than one or two phone numbers and this can be dangerous in some situations and is otherwise simply irritating and inconvenient. WiFi networks are presented to the device as a list of text-based names which are easier to work with and among those networks should be a public network which can be used by a device-installed app that does voice and video communication and file sharing by connecting to another such app using a social-system-verified identifier that is a combination of text-based name and a photo thus easy to remember and convenient.

  3. WiFi lends itself to Ad Hoc communication where the regular, fixed base station infrastructure is no longer available like in earthquake. WiFi then provides for direct communication between portable / wearable devices without any base station intermediary. This presents the quite a socially progressive idea of peer-to-peer networks where each person carrying or keeping the device has to participate in being socially responsible by letting his or her device to forward others' network packets. Actually this Ad Hoc peer-to-peer communication should be the only way for WiFi networking instead of a big-infrastructure-based network which is susceptible to being exploited for commercial profit.

  4. WiFi provides for short-range communication to smart TVs. The screen of a WiFi-enabled device can be telecast to a WiFi-enabled smart TV.

  5. It may be possible to enable a situation where communication satellites in planetary orbit have transponders that can work with WiFi portable / wearable devices on the ground or the seas.

So, WiFi i.e. the IEEE 802.11 series can become a universal standard for wireless communication.

Kosmos processor and operating system memory management

Memory management is paging-based and the total addressable space is 4 GB. A page directory in Kosmos processor is sized 4 KB, has 1024 four-byte-long entries as is traditional but is flexible in the sense that it can be connected to a 4 KB page table or to a 4 KB data page or to a less than 4 KB data "page". The paging system's view of memory is primarily of a set of 4 KB pages throughout. The traditional data cache and code cache have been discarded altogether and in their place the Kosmos processor will be stacked with the DRAM memory module via a stacking technique like HBM. This simplifies the memory system and eliminates the traditional cache management circuitry. The addressing is 32-bit and thus addressable space is limited to 4 GB as the idea is to have small modules of stacked processor + memory which will allow small, triple-redundancy-participating and parallel-processing network of Kosmos vector processors.

Structure of a page directory entry :
-------> Status ( 8 bits )
-------> Page number ( 24 bits )

The Status bits in the page directory will consist of :
-------> Bit 0 - Kernel page table
-------> Bit 1 - Native process' process descriptor "page"
-------> Bit 2 - Native process' scratchpad page
-------> Bit 3 - Client process' process descriptor "page"
-------> Bit 4 - Client process' scratchpad page
-------> Bit 5 - Client process' I/O buffer's page table
-------> Bit 6 - Native process' code page table
-------> Bit 7 - Native process' data page table

Structure of a page table entry :
-------> Status ( 8 bits )
-------> Page number ( 24 bits )

The Status bits in the page table will consist of :
-------> Bit 0 - Entry present
-------> Bits 1 to 7 - Unused

Memory map of a process ( the arrangement of entries in the page directory ) :
-------> Kernel page tables ( 0th entry to 7th entry - 32 MB space - accessible only by kernel )
-------> Native process' process descriptor "page" ( 8th entry - accessible only by kernel )
-------> Native process' scratchpad page ( 9th entry - accessible by native process, kernel )
-------> Client process' process descriptor "page" ( 10th entry - accessible only by kernel )
-------> Client process' scratchpad page ( 11th entry - accessible by native process, kernel, service process )
-------> Client process' I/O buffer's page table ( 12th entry - accessible by native process, kernel, service process )
-------> Process code page tables ( 13th entry - 500 MB space - accessible by kernel, native process )
-------> Process private data page tables ( entry position to be written - 500 MB space - accessible by kernel, native subprocess )
-------> Process common data page tables ( entry position to be written - 2.5 GB space - accessible by kernel, native process )

As one measure of processor-level support for secure user-mode code execution i.e. when the If In Kernel Mode bit in the Process Settings register ( described in below section ) does not contain a one the instruction has to be from within a process code page ( where the page's page directory entry's status bits is set for code i.e. bit 6 ). If a program's instruction is not from a code page the processor will generate an appropriate error which will call the relevant process in the desktop process group to handle this error essentially meaning terminating that user error process and generating a dump record of the process to be seen by the system administrator.

[ To be done ]

Kosmos processor register set ( under draft )

In Kosmos processor there are no registers exposed to the programs ( the kernel or a user-mode process ). The programs provide the instructions with data addresses and / or immediate values and / or branch instruction addresses and the instructions do the work silently or show the result by automatically branching out to the provided code branch's address, as appropriate. Vector instructions or singular-data-processing instructions aka Scalar instructions will read from memory into the source IEU scratchpad register(s), use the destination IEU scratchpad register to keep the result of the operation and write the destination IEU scratchpad into memory. This keeps the processor design simple and can work nicely with faster current memories such as HBM and is future-proof for the soon-coming time when RAM will combine the speed of SRAM, the density of DRAM and the non-volatility of Flash plus and one step now is in form of Nantero company's NRAM which is based on CNTs ( carbon nanotubes ). The Instruction Dispatch Unit which sends out the instructions to be executed, is clock-less but I think the speed bottleneck currently will be through the speed limitation of the clocked DRAM memory module. There is no legacy architectural complexity in Kosmos processor so vector processing is built-in from the start so this is unlike processors like ARM and RISC-V where there is a base scalar instruction set and vector instructions had to be brought in separately as extensions to the base.

The IDU ( Instruction Dispatch Unit ) contains x number of registers as listed below along with their bit length :

Max Usable Computation Units ( IEUs ) ------------ 5 bits ( Set during chip fabrication. The maximum number of IEUs in any Kosmos implementation will be 32 because this somehow seems natural but it can vary in two implementations : 8 IEUs [for wearable and embedded devices ] and 32 IEUs [ for server systems ] )

Current Page Directory Page Number -------------- 32 bits

Process Settings ------------------------------------------ 32 bits ( From LSB : 1 bit for In Kernel Mode, 1 bit for In Interrupt, 1 bit for Breakpoint Enabled For Every Instruction, 1 bit for Breakpoint Enabled for Specific Instruction, 1 bit for Breakpoint Enabled For Datum Access, 5 bits for Number Of Computation Units To Use, 2 bits for Vector Address Increment Method, 1 bit for If Blocked In Channel I/O, 5 bits Unused, 14 bits for Loop Counter )

Main Process' Descriptor Address ------------------- 32 bits

Current Instruction Content --------------------------- 136 bits ( For instruction decoding, sufficient space to contain the largest instruction in the ISA which is setinstcfg )

Next-Instruction Address ------------------------------ 32 bits ( To hold the next instruction's address of the process )

IDU Scratchpad 1 ---------------------------------------- 32 bits

IDU Scratchpad 2 ---------------------------------------- 32 bits

IDU Scratchpad 3---------------------------------------- 32 bits

Source 1 Start Virtual Address ---------------------- 32 bits

Source 2 Start Virtual Address ---------------------- 32 bits

Destination Virtual Address -------------------------- 32 bits

Debugger Channel Address -------------------------- 32 bits

Each of the IEUs ( Instruction Execution Units - computation units ) consist of x number of registers as below :

IEU Scratchpad 1 -- 32 bits

IEU Scratchpad 2 -- 32 bits

IEU Scratchpad 3 -- 32 bits

Kosmos processor instructions

At present there are 22 instructions as given below :

setinstcfg, copyimm, copyword, goto, jmptblexec, add, sub, mul, and, or, xor, lsh, rsh, countofonebits, setfromfirstzerobit, unsetbitsat, bytecmp, takelock, saveprocess, loadprocess, kcall, kexit.

Each instruction described in detail further below. Except for Operation Code ( henceforth called opcode ) the Kosmos processor instructions are of variable length but to allow the processor logic to read instructions at a determinate rate and keep things simple as much as possible every instruction memory read will read 136 bits which is the length of the setinstcfg instruction - the longest instruction in the ISA. Once the the opcode is known and it is not of setinstcfg the remainder bits are disregarded.

Instruction format :
Opcode ------ ( 8 bits )
Operands --- ( variable number of bits according to opcode )

setinstcfg instruction

setinstcfg : Sets the configuration for the instruction stream in a process to be used by subsequent vector and scalar instructions ( like looping, arithmetic, logic and data copy ).

Usage ( lsb on top ) :
-------> opcode ( setinstcfg )
-------> number of computation units to use -- 5 bits
-------> address increment method -- 2 bits
-------> loop count -- 14 bits
-------> unused -- 11 bits
-------> source address 1 -- 32 bits
-------> source address 2 -- 32 bits
-------> destination address -- 32 bits

"address increment method" : 00b for no increment, 01b for increment sources only, 10b for increment destination only, 11b for increment both sources and destination.

Example :
-------> setinstcfg 4, 11b, 10, 00000000000b, 20, 40, 100

copyimm instruction

copyimm : Copy an immediate value to the address in the destination as set in the configuration.

Usage ( lsb on top ) :
-------> opcode ( copyimm )
-------> immediate value -- 32 bits

Example :
-------> copyimm 198000

copyword instruction

copyword : Copy a memory word from the address in the first source to the destination address as per the configuration.

Usage ( lsb on top ) :
-------> opcode ( copyword )

Example :
-------> copyword

goto instruction

goto : If the first operand is zero then the instruction performs an unconditional jump to the provided address. If however the first operand is a one then this instruction allows for counted loops where it subtracts one from the Loop Counter bits in the Process Settings register which if non-zero makes the instruction to go to the instruction pointed by the second operand else if Loop Counter is zero goes to the next instruction after this instruction.

Usage ( lsb on top ) :
-------> opcode ( goto )
-------> if counted jump -- 8 bits
-------> address to jump to

Example :
-------> goto 0 _aai_zanjeer_ki_jhankaar

jmptblexec instruction

jmptblexec : This instruction provides a fast and convenient way of executing functions based on a numerical function identifier. For example in most OSes user-level processes call kernel calls by providing the call identifier number in a register and this register can be checked by individual 'if' statements in the kernel to arrive upon the correct kernel call associated with the call identifier and the call executed accordingly but kernel calls are many, so, many a number of the 'if' statements takes a lot of processor time and repetitive code space, so to avoid these two situations a call jump table can be used where in case of Kosmos processor and Kosmos OS the user process fills the kernel call number in the 0th word ( byte 0 ) in the scratchpad page and executes the kcall instruction whereupon the relevant kernel code is jumped-to which :

  1. Fills the 1st word in the scratchpad page with the the number that defines the number limit of the kernel calls.
  2. Fills the 2nd word in the scratchpad page with the address of the table of pointers to the kernel calls where the table has to exist in kernel space.

And then the kernel calls the jmptblexec instruction which reads the scratchpad page's 0th word into IEU Scratchpad 1 and checks if it has a number greater than the kernel call number limit ( which is stored in the scratchpad page's 1st word ) and if so then the very next instruction is executed which has to take appropriate action, essentially returning to the user process with an error code in the error code word in the scratchpad page ( halfway down the page ). If however the 0th word in the scratchpad page has a number within the zero to limit-number range then the instruction goes to the jump table ( addressed from the scratchpad page's 2nd word ) which has pointers to the kernel calls. The content of the IEU Scratchpad 1 is multiplied by four ( the word size of instruction addresses ) to arrive upon the correct index into the jump table and the content i.e. the kernel call address retrieved in another IEU scratchpad and prepared for execution.

This procedure is similarly followed for jump tables used in user processes where the table exists in the process' code space. About the instruction addresses stored in the table for user-mode processes see note in the Memory Management section above.

Usage ( lsb on top ) :
-------> opcode ( jmptblexec )

Example :
-------> jmptblexec

The mathematic, logic and bitwise instructions

As appropriate to the instruction and the configuration set by the setinstcfg instruction the input for these instructions is taken from the source IEU scratchpad registers which are fed in by the the source memory words and the result of operation which will be in the destination IEU scratchpad will be written to the destination memory word.

add : Addition possibly in a matrix.

sub : Subtraction possibly in a matrix.

mul : Simple multiplication possibly in a matrix.

and : Logical and'ing possibly in a matrix.

or : Logical or'ing possibly in a matrix.

xor : Logical exclusive or'ing possibly in a matrix.

lsh : Left shifting of a number given in source 1 address by so many places given in source 2 address.

rsh : Right shifting of a number given in source 1 address by so many places given in source 2 address.

Usage ( lsb on top ) :
-------> opcode ( the mathematic or logic or bitwise instruction )
-------> equal compare value -- 32 bits
-------> address for jump on less-than
-------> address for jump on greater-than

Example :
-------> add 2909, _ye_mera_deewanapan_hai, _bulbuli

Other instructions for counting, setting and unsetting bits

countofonebits : Count the number of 1 bits in the word given in source 1 address. The bits are counted from LSB. Return the count in destination address.

Usage ( lsb on top ) :
-------> opcode ( countofonebits )

Example :
-------> countofonebits

setfromfirstzerobit : In the given 32-bit number in source address 1 find the first valid zero bit position and set it. The number is provided via source 1 address and the successful result is indicated by executing the very next instruction and failure is indicated by jumping to a relevant code using the "set-fail code address" operand. This instruction differs from other instructions in that the source 1 address is written back with the changed state of the input number word and the destination address will be stored with the position of the first bit set.

Usage ( lsb on top ) :
-------> opcode ( setfromfirstzerobit )
-------> bit position to ignore -- 8 bits
-------> number of contiguous bits to set -- 8 bits
-------> byte offset into the data structure to store the count at -- 8 bits
-------> set-fail code address

"bit position to ignore" : The search for zero is started from the LSB and if this position is found to have a zero it will be ignored and the search carried on. If still by the end of the word there is no zero bit then the "set-fail code address" is used. If a zero has been found then the "number of contiguous bits to set" field is checked. If the bits to be set are more than the positions remaining in the word then a "Malformed instruction" interrupt is raised.

Example :
-------> setfromfirstzerobit 30, 3, 8, 100

unsetbitsat : Generally to be used after using setfromfirstzerobit. The word to operate on is taken from source 1 address and the beginning bit position to unset from is taken from data structure in source 2 address plus the offset.

Usage ( lsb on top ) :
-------> opcode ( unsetbitsat )
-------> byte offset into the data structure to retrieve the count from -- 8 bits
-------> number of contiguous bits to unset -- 8 bits

Example :
-------> unsetbitsat 8, 3

Instruction for byte comparison

bytecmp : This instruction compares two bytes in memory and if there is positive match the instruction jumps to the very instruction after this one else jumps to another instruction whose address is provided as the operand. The instruction is useful in string comparisons. The source for the byte to be checked is taken from source 1 address as set by setinstcfg instruction and the address of the byte that provides the fixed comparison letter is taken from source 2.

Usage ( lsb on top ) :
-------> opcode ( bytecmp )
-------> address of code for no positive match

Example :
-------> bytecmp _banjaara

Instruction for critical sections

takelock : "Take" a 32-bit lock memory word if possible. There are two rules of the instruction : (a) Before any kernel code calls this instruction it should fill into the process descriptor's 0th address the address of the word to be locked, (b). If the lock word's value is 0x00000000 it is an unlocked lock and if the value is 0xFFFFFFFF it is a taken lock, .

The instruction operates as follow :

  1. Reads into IEU Scratchpad 1 the value from the memory word at the 8th entry in the page directory where is found the address of the current process' process descriptor. That address ( offset 0 into the process descriptor ) has the field 'Address Of Lock Word' so IEU Scratchpad 1 now has that address.
  2. Copies IEU Scratchpad1 to IEU Scratchpad 2 which now also has the lock word's address.
  3. Reads into IEU Scratchpad 3 the value from the address found in IEU Scratchpad 2. IEU Scratchpad 3 now has the "old value" of the lock.
  4. If "old value" in IEU Scratchpad 3 is 0x00000000 then IEU Scratchpad 2 is set to 0xFFFFFFFF and copied to the lock's address found in IEU Scratchpad 1. The lock is now considered taken. The instruction jumps to the very next instruction address which starts the code for the lock-taken situation.
  5. However, if IEU Scratchpad 3 ( "old value" ) is 0xFFFFFFFF ( lock already taken by some other code ) then operand 1 is picked up as the address of the instruction to execute which will start the code for the lock-not-taken situation.

Usage ( lsb on top ) :
-------> opcode ( takelock )
-------> address of code for if lock not taken

Example :

_che_vuole_questa_musica_stasera : // try to take lock
takelock _jab_bhi_ye_dil_udaas_hota_hai
_likhe jo khat tujhe // lock taken
_jab_bhi_ye_dil_udaas_hota_hai : // lock not taken
goto 0 _che_vuole_questa_musica_stasera // try to take lock again  

Usage and structure of the Scratchpad Page

This page is mainly used to transfer call arguments and return values between user processes, kernel calls and the user-mode service calls. At byte 0 will be the kernel call and then the parameters. At halfway point in the page will be error code number, then return values. So unlike in other OSes like Linux which use processor registers to transfer call values, in Kosmos OS such an external call can transfer more number of values through this page. The page can also be used to store temporary values.

Instructions for process context operations

saveprocess : When called by the kernel this instruction will save the changing context of the current process i.e. via the "native" process descriptor address available at a fixed address in the current page directory. The changing context being the registers Process Settings and Next-Instruction Address.

Usage ( lsb on top ) :
-------> opcode ( saveprocess )

Example :
-------> saveprocess

loadprocess : When called by the kernel this will load a new process by taking the new process' descriptor's address from a fixed memory address in kernel space and updating the Current Page Directory Page Number register and then the process' changing-context. That fixed address is not yet defined but it is the kernel which will store in it the new process descriptor's address.

Usage ( lsb on top ) :
-------> opcode ( loadprocess )

Example :
-------> loadprocess

kcall : When called by a user level process this will save the Process Settings register and the Next-Instruction Address into the native process descriptor and write a one to the If In Kernel Mode bit in the Process Settings register and change the process' execution path from user mode to kernel mode by jumping to the kernel call handler function so that the kernel can perform various actions according to the provided arguments which should be in the scratchpad page starting from byte 0.

Usage ( lsb on top ) :
-------> opcode ( kcall )

Example :
-------> kcall

kexit : Called by the kernel to get a process back from kernel call to user mode. When called in the kernel the instruction will read the current native process' descriptor to reload the Process Settings making the If In Kernel Mode bit set to zero and will then read the Next-Instruction Address word to use the content address as the instruction in user space to get the process back into user mode.

Usage ( lsb on top ) :
-------> opcode ( kexit )

Example :
-------> kexit

[ To be done ]

Interrupt handling

[ To be done ]

List of instructions that can operate on a vector


List of instructions that can be executed only in kernel mode


[ To be done ]

Kosmos operating system version 1 overview

The OS as said earlier is based on microkernel architecture which means the kernel has just a few facilities which are :

  1. Process creation, control and deletion.
  2. Synchronous IPC ( Event Waiting / Posting and Buffered I/O ).
  3. Interrupt redirection.
  4. Timers.
  5. System control.

The rest of the services are facilitated by user-mode server processes. This simple division of work makes the software system more reliable.

Below are the kernel calls, system error codes and other OS elements whose shape may be modified as per development in processor ISA and OS design :

Process management

Below are the 16 process priorities possible :

  1. Highest priority processes == priority 0
  2. Normal priority processes == priorities 1 to 15

Minimum amount of memory alloted to a main process : 6 pages ( 24 KB ) + x bytes : process descriptor ( x bytes ), page directory, code page table, data page table, code page, regular data page, scratchpad page.

Minimum amount of memory alloted to every sub process : x bytes + 4 KB : process descriptor ( x bytes ), scratchpad page.

The "x bytes" for a process descriptor are "x" because as of now the process descriptor is not yet complete.

Process identifier method : .

[ To be done ]

Process descriptor fields ( under draft )

Address Of Lock Word ----------------------------------------------------------------------------- 32 bits
Lock Word --------------------------------------------------------------------------------------------- 32 bits
Page Directory Page Number ------------------------------------------------------------------- 32 bits
Process Settings ------------------------------------------------------------------------------------ 32 bits
Next-Instruction Address ------------------------------------------------------------------------ 32 bits
Original Priority ------------------------------------------------------------------------------------- 32 bits
Partition Address ----------------------------------------------------------------------------------- 32 bits
Main Process' Descriptor Address ------------------------------------------------------------- 32 bits
Instruction Breakpoint Address ---------------------------------------------------------------- 32 bits
Datum Access Breakpoint Address ----------------------------------------------------------- 32 bits
Debug Target Register State and Process Descriptor State Dump Address ------ 32 bits
Guarded Code 1 Instruction Address --------------------------------------------------------- 32 bits
Guarded Code 2 Instruction Address --------------------------------------------------------- 32 bits
Guarded Code 3 Instruction Address --------------------------------------------------------- 32 bits
Guarded Code 4 Instruction Address --------------------------------------------------------- 32 bits
Guarded Code Slot Address --------------------------------------------------------------------- 32 bits
Capabilities Bitmap -------------------------------------------------------------------------------- 32 bits

[ To be done ]

Process partitioning

Partitioning is used to ensure that untrustworthy process groups ( main process and sub processes ) or unresponsive processes or misbehaving interrrupt handler processes do not take up all the processor's time and leave the other processes starved of execution. In Kosmos OS a partition quantum is 2 seconds from which the administrator can assign different percentages of execution time limits to different processes and within every 2 seconds these processes execute for only those times. So a misbehaving process will run only part of the time and the user can invoke the process manager to terminate that process. Or a virtual machine that is running ( a reduced and modified ) Linux can be assigned only 50 percent of execution time out of the 2 seconds.

[ To be done ]

OS error codes

EBUSY ( kernel resources are busy )

[ To be done ]

Process "Capabilities" ( under draft )

CAP_PROCESS_DEBUGGER ( be able to set instruction+data breakpoint info on a target process, get process descriptor and register state of the process being debugged, receive notifications for processes failing some Capability settings )
CAP_PROCESS_PRIORITY_CONTROL ( increase or decrease process priority )
CAP_PROCESS_HW_INTERRUPT_CONNECT ( connect a process to a hardware device interrupt )
CAP_PROCESS_PARTITION_CONTROL ( create a partition, edit it, remove it )
CAP_PROCESS_RANDOM_GENERATE ( be able to generate random number )
CAP_PROCESS_USE_GOTO ( able to use the processor's goto instruction )
CAP_SERVICE_IOBUFFER_READ_PROTECT ( enable a client I/O buffer such that a service cannot read from pages in the page table other than between the exact page boundaries of the buffer )
CAP_SERVICE_OBJECT_CREATE ( request a service to create a file, network connection, maybe a graphical element etc )
CAP_SERVICE_OBJECT_SHRED ( primarily to shred a file but maybe there are other things to shred )

[ To be done ]

User-mode services and the IPC calls

The Kosmos microkernel provides only a few fundamental services so all other common services in the OS like graphical UI, storage and networking are to be provided by user-mode services which are nothing but process groups that know how to work on a particular resource and use the kernel's simple IPC mechanisms to provide the controlled use of that resource to other process groups. The kernel contains a text-based list of all the main services in a particular Kosmos SoC and each record in that list is called a Channel... Channel that can be connected to by other process groups for use. Each service can have multiple channels for different purposes ( the max number of channels in each service process is not yet decided ). Processes can get the list of the channels using the below kernel call :
-------> channelGetList(List Buffer)

For a service to add a channel into the kernel-based channel list the below kernel call is used :
-------> channelAdd(Channel Name, Channel Type, Service-local Channel Info Table Index)
-------> "Channel Type" is either :
------->>> Event
------->>> Debug I/O
------->>> Regular I/O
-------> "Service-local Channel Info Table Index" is a convenient index into a table that the service process maintains within its user-mode data space, containing any service-specific info about the channels it creates. This index is recorded into the channel's kernel structure and is part of the information returned to the service process by the unblocked channelWaitIO call described below. The table should not use the zeroth element in the table because zero index in this case will be returned by the kernel as an error indication.
-------> Channels have no priority.

And for a process to connect to a particular channel the below kernel call is used :
-------> Connection ID = channelConnect(Channel Name)

There are two ways that a service provides use of the channel and a client process utilizes the channels :

  1. Event Wait and Event Broadcast based IPC : Usually used to broadcast the change of state in a data block within a service to multiple processes interested to know that change. The service associates a data structure within it with a channel and this can be specific to a service. Client processes interested in knowing any change to that structure will call a "wait" kernel call on that channel and block. Thus multiple processes will block on that channel. Once the service process makes change to that data structure it will make a "post" kernel call on that channel, unblocking all the processes waiting on that channel, in effect broadcasting the state change / event to all the waiting processes. The waiting client processes can be outside the service's process group or within. This is a simple system where only two 32-bit words ( the type of the event and the datum pertaining to the event ) are broadcast from the service to all the waiting processes to notify them of state change or an event. Below are the two kernel calls for this :

    -------> Event Type, Event Datum = channelWaitEvent(Connection ID)
    -------> channelPostEvent(Channel ID, Event Type, Event Datum)

  2. I/O-Buffer based IPC : Here a service process running at the priority given to the service's process group does a general channelWaitIO kernel call within a loop, without specifying any of the I/O type channels it has created and begins waiting for client I/O requests. The service process is removed from the running processes list. A client process requiring substantial I/O work from one of that service's channels, calls the channelDoIO kernel call on that channel. The kernel puts the client process into I/O-blocked mode and brings back the waiting service process into execution mode to process the client's I/O request with the following attributes :

    The service process is notified as to which of its channels has been sent the client I/O request.

    There is no copying of data from the client to the service because though the service works mostly within the memory context of the service process ( the service's page directory ) the client's scratchpad page and the client I/O buffer's entire page table are simply and directly attached to the service's page directory at two fixed addresses which means that the service process will be directly able to access the relevant client memory. This negates the need to do kernel buffering of the message itself nor is there the need for the kernel to copy the message between the client process and the server process.

    The service call will work within the process context of the service except the client's priority becoming the priority of the service call for the duration of the call. If however the currently-job-servicing service process is pre-empted by a higher priority process that wants to get service from that same channel this new process is not only attached to the channel's processes waiters list as before but the service process' priority is raised to become the higher priority of the new process. This is the Priority Inheritance implementation and is to negate the Priority Inversion issue which is nicely explained on the Geeks for Geeks website on this page.

    After the service has peformed work for the current client and has called channelWaitIO for the next client, the next queued client process will be chosen according to its priority and FIFO place in that priority's list.

    The service call will run in this part-server part-client memory and process context until either the service call returns to the client voluntarily through the channelReplyIO kernel call or the client call times out.

    The three kernel calls used for this I/O buffer based message passing mechanism are below, the first one and third one to be used by the service / channel handler process and the second by the client :
    -------> Service-local Channel Info Table Index, Client State, Transaction Number = channelWaitIO()
    -------> channelDoIO(Connection ID, Service Type, I/O Buffer)
    -------> channelReplyIO(Transaction Number)
    Any client process that has not been replied to, if its channelDoIO call times out or that process has been deleted, ChannelWaitIO returns with the relevant information to the service process on those situations. In the other situation where a transaction has been completed successfully the service process should not keep the transaction as a permanent record because the kernel can reuse the same transaction number for another transaction.
    The service process that has unblocked from a successful channelWaitIO may in turn do at most one channelDoIO to call the channel of another service to maybe fulfill the original client's channelDoIO.

// Begin section to be edited

Kernel calls for Guarded Code

These will be gcodeBegin() and gcodeEnd() and will be described soon.

Debugging of user-mode programs

In the Kosmos OS implementation there will be no separate debugger program because that facility will be inbuilt into the desktop process which can do it because it has the capability bit CAP_PROCESS_DEBUGGER set in its main process. Programs can be debugged in two ways :

  1. The desktop process will present a password-protected user interface function to select a program to start with to-be-debugged mode set. In case of an embedded Kosmos implementation the in-all-implementations-running desktop process will get the debug request from the network. The desktop function will start the target program using the processCreate kernel call which sets the target's process descriptor with appropriate data in its Instruction Breakpoint Base Address field, Data Breakpoint Base Address field and the Break Point bit in the Process Settings field set. The target program will halt at the appropriate breakpoints and the relevant desktop window visually shows the register state of the program and also its process descriptor state or the info is sent to the network.
  2. An already running program / process can also be set for debugging from either the Process Manager desktop function or through the network. In this case either of the two means will use the processControl kernel call which similar to above sets in the target process' process descriptor the instruction and data breakpoint fields and the Process Setting register's Break Point bit. This too will be password-protected.

The Instruction Breakpoint Base Address and Data Breakpoint Base Address are called "Base Address" because these addresses are the beginning of ranges where in case of instruction breakpointing any instruction about to be executed and falling within this range will trigger execution of the breakpoint handling process within the desktop process group, and in case of data breakpointing any read or write address falling within the range will trigger execution of the same breakpoint process. The breakpointing address range for both instruction and data will be within 1024 bytes from the base address. Breakpointing is checked during the various logics done during the preparation to execute an instruction in user mode. As to whether instruction breakpointing will be checked first or data breakpointing it will be instruction breakpointing.

// End section to be edited

List of all kernel calls ( under draft )

timerConfigure(Timer Duration, If Sleep Now)

Program executable file format

The format will be a simplified derivation from the simple A.out format that is described here.

[ To be done ]