Astra operating system¶
Astra is straightforward and thoroughly robust OS
Introduction¶
AstraOS is a new operating system designed for running on RISC-V hardware.
Its goals are:
to be the software half of a solution to the thirty million line problem
to simplify the development process both for kernel and userspace software.
to remove conflicts between userspace interfaces through strict typing of the outputs
to simplify the software distribution on the platform
to make security easy to achieve without sacrificing flexibility like Android does
to give users control on software configuration, so every program uses a config picked by the user
It is achieved by designing everything from the ground up, avoiding legacy ideas.
Details¶
POSIX compatibility is not the goal; there may be a compatibility layer in the future, but quality and simplicity are the priority.
Executable files will be able to contain any arbitrary data in marked sections to simplify the software distribution.
Link security options to individual files to make things more precise.
Users will have control over the exact configuration software uses and what program is allowed to do.
On documentation¶
The documentation is currently made using Sphinx documentation generator.
To build it yourself it in Linux for an HTML format, change the directory to doc of the Astra source code and type in your shell:
make html
API documentation¶
OS source¶
The AstraOS code itself is located in “src” directory.
kernel.c¶
-
void _putchar(char c)¶
Implements a putchar function. Sends a single char value to the UART port.
- Parameters
c – the char value
- Since
v0.1
-
void uart_write_string(char *str)¶
Writes a string of an arbitrary length to the UART port.
- Parameters
str – the char pointer
- Since
v0.1
-
void kinit_hart(u64 hartid)¶
Performs a kernel init for a given hardware thread by its id. The other hardware threads start their execution here.
- Parameters
hartid – uint64; obtained in an assembly code
- Since
v0.1
-
void trap_hang_kernel(u64 epc, u64 tval, u64 cause, u64 hart, u64 status, TrapFrame *frame)¶
This function is used to perform system calls and switch tasks.
It is called by the assembly code in trap.s, when a hart experiences a trap event and after the processor state is stored in memory.
- Parameters
epc – the program counter before the trap event (tells which instruction we were on)
tval – the value that caused the trap if there was a value involved (a segmentation fault for instance)
cause – what type of trap it was
hart – hardware thread that is trapping
status – TODO
frame – a
TrapFrame
pointer; the state of all the cpu registers
- Since
v0.1
process.h¶
-
struct TrapFrame¶
The TrapFrame is a struct that holds the state of all the cpu registers before the trap.
- Since
v0.1
-
u64 regs[32]¶
integer registers
-
u64 fregs[32]¶
floating point registers
-
u64 satp¶
Supervisor Address Translation and Protection register, a pointer to the virtual memory table to be used. Some of the bits tell the type of address translation being used. (TODO detail these bits.)
-
int process_shrink_allocation()¶
Returns the kallocation that is no longer being tracked by the process. If “new_page_count” is 0 then this is the whole kallocation at vaddr.
If the shrink fails or encounters an error state the returned “kallocation” points to NULL.
TODO explain the context in detail.
- Parameters
process – a Process instance
vaddr – TODO
new_page_count – TODO
- Returns
a Kallocation instance or a NULL pointer
- Since
v0.1
uart.h¶
-
void uart_init()¶
Initializes the UART port.
- Since
v0.1
-
void uart_write(u8 *data, u64 len)¶
Writes a number of bytes to UART port.
- Parameters
data – a pointer to bytes array to write
len – a number of the bytes to write
- Since
v0.1
-
u64 uart_read(u8 *data, u64 len)¶
Reads a number of bytes to the data array.
- Parameters
data – a pointer to bytes array to record read result to
len – a number of the bytes to read
- Since
v0.1
-
void uart_read_blocking(u8 *data, u64 len)¶
Performs a blocking reading for a number of bytes to the data array.
- Parameters
data – a pointer to bytes array to record read result to
len – a number of the bytes to read
- Since
v0.1
libfuncs.h¶
-
int memcmp(const void *vl, const void *vr, u64 n)¶
Compares the first n bytes (each interpreted as unsigned char) of the memory areas s1 and s2.
- Parameters
vl – left array
vr – right array
n – number of bytes to compare
- Returns
TODO, an integer
- Since
v0.1
-
void *memcpy(void *dst0, const void *src0, u64 length)¶
Copies a number of bytes set by length from scr0 to dst0. TODO is “0” needed for “src0” and “dst0” at all?
- Parameters
dst0 – destination void pointer to copy bytes to
src0 – source void pointer to copy bytes from
length – a length of bytes to copy, unsigned 64-bit integer
- Returns
a void pointer, dst0
- Since
v0.1
-
void *memmove(void *s1, const void *s2, u64 n)¶
Copies a memory area of a given length from “s2” to “s1”, given a length.
- Parameters
s2 – a destination byte array
s1 – a source byte array
n – a number of bytes to copy
- Since
v0.1
-
void *memset(void *dest, int c, u64 n)¶
Fills a bytearray with a certain byte given a maximum number of bytes to fill.
- Parameters
dest – a destination bytearray pointer
c – a byte to copy (TODO check)
n – a number of bytes to copy (TODO check)
- Since
v0.1
-
u64 strlen(char *str)¶
Calculates the length of the string pointed to by “str” parameter, excluding the terminating null byte (‘0’).
- Parameters
str – a char array input pointer
- Returns
an actual length of a string or 0
- Since
v0.1
-
u64 strnlen_s(char *str, u64 max_len)¶
Calculates the length of the string, excluding the first null character terminating it. Stops counting when “max_len” is reached, returns “max_len” in that case.
TODO: check if this implementation should be used. https://stackoverflow.com/questions/66346502/
- Returns
string length (for a null-terminated byte string)
- Since
v0.1
-
char *strcpy(char *dest, char *src)¶
Copies the string pointed by src to the buffer pointed to by dest. Includes the terminating null byte (‘0’).
The destination string dest must be large enough to store the copy.
- Parameters
dest – the pointer to the bytearray to write to
src – the pointer to the source bytearray
- Returns
the dest pointer
- Since
v0.1
-
char *strncpy(char *dest, char *src, u64 max_len)¶
Copies a string.
- Parameters
dest – a destination bytearray pointer to copy bytes to
src – a source bytearray pointer to copy bytes from
max_len – a maximum length of a string to copy, an unsigned 64-bit integer
- Returns
a destination bytearray pointer
- Since
v0.1
-
int strcmp(const char *s1, const char *s2)¶
Compares two strings.
- Parameters
s1 – string A
s2 – string B
- Returns
an integer less than 0 if s1 is less than s2, zero if s1 matches s2, greater than zero if s1 is greater than s2
- Since
v0.1
-
int strncmp(const char *s1, const char *s2, u64 n)¶
Compares two strings.
- Parameters
s1 – string A
s2 – string B
n – a number of characters to compare, a 64-bit unsigned integer
- Returns
an integer less than 0 if s1 is less than s2, zero if s1 matches s2, greater than zero if s1 is greater than s2
- Since
v0.1
-
void strcat(char *dest, char *src)¶
Concatenates two strings, appends “src” string to “dest” one. Overwrites a null-terminating byte and terminates it later. TODO check if termination happens. “dest” character array must have enough space for this operation.
- Parameters
dest – destination character array pointer
src – source character array pointer
- Since
v0.1
random.h¶
-
struct xoshiro256ss_state¶
A struct keeping the internal state for xoshiro256ss algorithm.
-
u64 rol64(u64 x, int k)¶
Rotl function implementation for u64 value.
- Parameters
x – the number
k – a bit count
- Returns
the result of rotating the bits of the number to the left by that count.
-
u64 xoshiro256ss(struct xoshiro256ss_state *state)¶
xoshiro256** is the family’s general-purpose random 64-bit number generator (xor/shift/rotate).
Details:
- Parameters
state – a pointer to xoshiro256ss_state struct
- Returns
u64
Notes¶
The “Scrambled Linear Pseudorandom Number Generators” article by David Blackman and Sebastiano Vigna shows that “static inline” may be needed for “rol64” function, but compiler is already inlining it on -O3.
printf.c and printf.h¶
-
type out_fct_type¶
Output function type
-
struct out_fct_wrap_type¶
Wrapper (used as buffer) for output function type
-
void _out_buffer(char character, void *buffer, int idx, int maxlen)¶
Internal buffer output.
- Parameters
character – TODO
buffer – TODO
idx – TODO
maxlen – TODO
- Since
v0.1
-
void _out_null(char character, void *buffer, int idx, int maxlen)¶
Internal null output.
- Parameters
character – TODO
buffer – TODO
idx – TODO
maxlen – TODO
- Since
v0.1
-
void _out_char(char character, void *buffer, int idx, int maxlen)¶
Internal _putchar wrapper
- Parameters
character – TODO
buffer – TODO
idx – TODO
maxlen – TODO
- Since
v0.1
-
void _out_fct(char character, void *buffer, int idx, int maxlen)¶
Internal output function wrapper
- Parameters
character – TODO
buffer – TODO
idx – TODO
maxlen – TODO
- Since
v0.1
-
unsigned int _strnlen_s(const char *str, int maxsize)¶
Internal secure strlen.
- Parameters
str – an input string
maxsize – a maximum string size
- Returns
The length of the string (excluding the terminating 0) limited by ‘maxsize’
-
int _is_digit()¶
Internal test if char is a digit (0-9)
- Parameters
ch – an input character
- Returns
true if char is a digit
-
unsigned int _atoi(const char **str)¶
Internal ASCII string to unsigned int conversion.
- Parameters
str – TODO
- Returns
unsigned int
-
int _out_rev()¶
Output the specified string in reverse, taking care of any zero-padding.
TODO describe the parameters.
elf.h¶
-
struct ELF_Header¶
An executable Linux file header. Visit Wikipedia for more details.
-
u32 magic¶
First 4 bytes of a file, identifying a file as ELF object file: 0x7F, ELF (45 4c 46)
-
u8 bitsize¶
“bitsize” or “e_ident” identifies if a file is using 32 or 64-bit format. 1: 32-bit, 2: 64-bit.
-
u8 endian¶
1 for a little endian file, 2 for a big endian one. Affects the interpretation of multi-byte fields starting with offset 0x10.
-
u8 ident_abi_version¶
ELF format version, 1 for the current one.
-
u8 target_platform¶
A target operating system ABI ID (TODO: add AstraOS ID)
-
u8 abi_version¶
ABI version specifier.
-
u8 padding[7]¶
Currently unused, fill with zeros.
-
u16 obj_type¶
An object file type: 0x00=ET_NONE, 0x01=ET_REL, 0x02=ET_EXEC, 0x03=ET_DYN, 0x04=ET_CORE, 0xFE00=ET_LOOS, 0xFEFF=ET_HIOS, 0xFF00=ET_LOPROC, 0xFFFF=ET_HIPROC.
-
u16 machine¶
Target instruction set architecture (ISA), like RISC-V, MIPS, x86, etc.
-
u32 version¶
“e_version”, leave as 1.
-
u64 entry_addr¶
A memory address for the entry point from where the process starts executing. 32 or 64-bits long depending on bitsize.
-
u64 phoff¶
A start of the program header table. TODO: add details.
-
u64 shoff¶
A start of the section header table.
-
u32 flags¶
Architecture-dependent, TODO
-
u16 ehsize¶
Size of the header. 64 Bytes for 64-bit, 52 Bytes for 32-bit format.
-
u16 phentsize¶
The size of a program header table entry.
-
u16 phnum¶
The number of entries in the program header table.
-
u16 shentsize¶
The size of a section header table entry.
-
u16 shnum¶
The number of entries in the section header table.
-
u16 shtrndx¶
Index of the section header table entry that contains the section names.
-
u32 magic¶
-
struct ELF_ProgramHeader¶
A structure definition for an ELF program header. Visit a Wikipedia article for more details.
-
u32 seg_type¶
Segment type, header table entry unused, loadable, dynamic linking, etc.
-
u32 flags¶
Segment-dependent flags
-
u64 off¶
Offset of the segment in the file image
-
u64 vaddr¶
Virtual address of the segment in memory.
-
u64 paddr¶
Reserved for segment’s physical address on systems where physical address is relevant
-
u64 filesz¶
Size in bytes of the segment in the file image, may be 0.
-
u64 memsz¶
Size in bytes of the segment in memory. May be 0.
-
u64 align¶
0 and 1 specify no alignment. Should be a positive, integral power of 2, with p_vaddr equating p_offset modulus p_align.
-
u32 seg_type¶
-
u64 create_process_from_file(u64 file_id, u64 *pid_ret)¶
Creates a process from an elf file by its file_id.
- Parameters
file_id – a system-wide unique id of a file to load it from the filesystem, used instead of a filename
pid_ret – a pointer to an unsigned 64-bit integer that will be updated after the process is created with a process id
- Returns
0 on error, 1 on success
Common¶
Commonly used headers
Maths¶
Note: functions starting with “_” are internal-use only. This is done, because many trigonometry functions have symmetries. It allows to have several internal-use functions that are valid at a certain range and wrappers users will actually need.
-
f32 floorF32(f32 x)¶
A floor function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the floor function result
- Since
v0.1
-
f64 _Sine(f64 x)¶
An internal-use sine function implementation for 64-bit floats.
Calculates \(sin(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a sine function result
- Since
v0.1
-
f32 _SineF32(f32 x)¶
An internal-use sine function implementation for 32-bit floats.
Calculates \(sin(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a sine function result
- Since
v0.1
-
f64 _arc_sine(f64 x)¶
An internal-use arcsine function implementation for 64-bit floats.
Calculates \(arcsin(x)\) for x in \([0; 0.5]\).
- Parameters
x – an input value
- Returns
an arcsine function result
- Since
v0.1
-
f32 _arc_sineF32(f32 x)¶
An internal-use arcsine function implementation for 32-bit floats.
Calculates \(arcsin(x)\) for x in \([0; 0.5]\).
- Parameters
x – an input value
- Returns
an arcsine function result
- Since
v0.1
-
f64 _arc_tangent(f64 x)¶
An internal-use arctangent function implementation for 64-bit floats.
Calculates \(arctan(x)\) for x in \([0; 0.5]\).
- Parameters
x – an input value
- Returns
an arctan function result
- Since
v0.1
-
f32 _arc_tangentF32(f32 x)¶
An internal-use arctangent function implementation for 32-bit floats.
Calculates \(arctan(x)\) for x in \([0; 0.5]\).
- Parameters
x – an input value
- Returns
an arctan function result
- Since
v0.1
-
f64 _Cosine(f64 x)¶
An internal-use cosine function implementation for 64-bit floats.
Calculates \(cos(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a cosine function result
- Since
v0.1
-
f32 _CosineF32(f32 x)¶
An internal-use cosine function implementation for 32-bit floats.
Calculates \(cos(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a cosine function result
- Since
v0.1
-
f64 _Tangent(f64 x)¶
An internal-use tangent function implementation for 64-bit floats.
Calculates \(tan(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a tangent function result
- Since
v0.1
-
f32 _TangentF32(f32 x)¶
An internal-use tangent function implementation for 32-bit floats.
Calculates \(tan(x)\) for x in \([0; \frac{\pi}{4}]\).
- Parameters
x – an input value
- Returns
a tangent function result
- Since
v0.1
-
f64 sine(f64 x)¶
A sine function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the sine function result
- Since
v0.1
-
f32 sineF32(f32 x)¶
A sine function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the sine function result
- Since
v0.1
-
f64 cosine(f64 x)¶
A cosine function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the cosine function result
- Since
v0.1
-
f32 cosineF32(f32 x)¶
A cosine function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the cosine function result
- Since
v0.1
-
f64 tangent(f64 x)¶
A tangent function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the tangent function result
- Since
v0.1
-
f32 tangentF32(f32 x)¶
A tangent function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the tangent function result
- Since
v0.1
-
f64 arc_sine(f64 x)¶
A arcsine function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the arcsine function result
- Since
v0.1
-
f32 arc_sineF32(f32 x)¶
A arcsine function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the arcsine function result
- Since
v0.1
-
f64 arc_cosine(f64 x)¶
A arccosine function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the arccosine function result
- Since
v0.1
-
f32 arc_cosineF32(f32 x)¶
A arccosine function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the arccosine function result
- Since
v0.1
-
f64 arc_tangent(f64 x)¶
A arctangent function for 64-bit floats.
- Parameters
x – an input variable
- Returns
the arctangent function result
- Since
v0.1
-
f32 arc_tangentF32(f32 x)¶
A arctangent function for 32-bit floats.
- Parameters
x – an input variable
- Returns
the arctangent function result
- Since
v0.1
-
f64 arc_tangent2(f64 y, f64 x)¶
TODO
- Since
v0.1
-
f32 arc_tangent2F32(f32 y, f32 x)¶
TODO
- Since
v0.1
-
f64 exponential2(f64 x)¶
TODO
- Since
v0.1
-
f32 exponential2F32(f32 x)¶
TODO
- Since
v0.1
-
f64 logarithm2(f64 x)¶
Finds the power to which the number 2 must be raised to obtain the value x.
TODO: check if this explanation is valid.
\(logarithm2(x) = \log_2 x\)
- Since
v0.1
-
f32 logarithm2F32(f32 x)¶
Finds the power to which the number 2 must be raised to obtain the value x.
TODO: check if this explanation is valid.
\(logarithm2F32(x) = \log_2 x\)
- Since
v0.1
-
f64 power(f64 x, f64 y)¶
A power function for 64-bit floats.
\(power(x, y) = x ^ y\)
- Parameters
x – an input variable, a base, a number to be raised
y – an input variable, an exponent, number used to raise the base
- Returns
the power function result
- Since
v0.1
-
f32 powerF32(f32 x, f32 y)¶
A power function for 32-bit floats.
\(powerF32(x, y) = x ^ y\)
- Parameters
x – an input variable, a base, a number to be raised
y – an input variable, an exponent, number used to raise the base
- Since
v0.1
Types¶
Fsmake¶
TODO
Fsread¶
TODO
Square src¶
TODO
Userland¶
TODO