summaryrefslogtreecommitdiff
path: root/documentation
diff options
context:
space:
mode:
Diffstat (limited to 'documentation')
-rw-r--r--documentation/compositor.txt26
-rw-r--r--documentation/euler/heap.txt32
-rw-r--r--documentation/panics.txt8
-rw-r--r--documentation/sockets.txt28
-rw-r--r--documentation/syscalls.txt160
5 files changed, 222 insertions, 32 deletions
diff --git a/documentation/compositor.txt b/documentation/compositor.txt
new file mode 100644
index 0000000..8946eff
--- /dev/null
+++ b/documentation/compositor.txt
@@ -0,0 +1,26 @@
+compositors listen on the socket id "hilbert.compositor".
+
+data types:
+
+ color24:
+ byte: red
+ byte: green
+ byte: blue
+
+ color24 rectangle:
+ multiple color24's, top to bottom by row, left to right within row
+
+messages from applications to compositor:
+
+ open window:
+ byte: 0x00
+ dword: window width
+ dword: window height
+
+ update window region:
+ byte: 0x01
+ dword: start x
+ dword: start y
+ dword: width
+ dword: height
+ color24 rectangle: the data
diff --git a/documentation/euler/heap.txt b/documentation/euler/heap.txt
new file mode 100644
index 0000000..de1deec
--- /dev/null
+++ b/documentation/euler/heap.txt
@@ -0,0 +1,32 @@
+this file documents dynamic memory allocation and deallocation in userspace.
+the unused areas of a process's usable mapped memory are divided into "chunks"
+with a start and a length, satisfying the following properties:
+ a) the length of a chunk is a positive power of 2
+ b) the start of a chunk is a multiple of its length
+ c) let s be a power of 2 and k be an integer. there are never two chunks with
+ length s and starts s * (2 * k) and s * (2 * k + 1). if ever an operation
+ would result in two such chunks, they are combined into one chunk with
+ length 2 * s and start 2 * s * k.
+
+a "chunk info page" is divided into 512 64-bit integers describing up to 255
+chunks and a pointer to another chunk info page. for each n from 0 to 254:
+ if the (2 * n)'th integer (where the first integer is the 0th one) is 0:
+ the (2 * n + 1)'th integer is unused.
+ if the (2 * n)'th integer is not 0:
+ the (2 * n)'th integer describes the length of a chunk
+ the (2 * n + 1)'th integer describes the start of the same chunk
+the 510th integer is a pointer to the next chunk info page, and the 511th
+integer is never used.
+
+when a program calls new or malloc with needed size s, we find a free chunk of
+length at least s + 8. we then remove that chunk from the list of free chunks,
+and add back in whatever is left after the first s + 8 bytes, if anything.
+in the first 8 bytes of the original chunk, we store the value s + 8. the
+remainder of the orginal chunk is returned to the program.
+
+during that process, if there isn't a chunk with the needed size, one or more
+new pages are requested from the kernel to create such a chunk.
+
+when a program calls delete or free with pointer ptr, we read the integer in
+the 8 bytes starting at ptr - 8 into a variable s. we then add the region
+starting at ptr - 8 with length s to the free memory.
diff --git a/documentation/panics.txt b/documentation/panics.txt
new file mode 100644
index 0000000..e1b6ec1
--- /dev/null
+++ b/documentation/panics.txt
@@ -0,0 +1,8 @@
+when the kernel panics, it fills the screen with a color indicating the type of
+panic. the following are the defined colors so far:
+ #48a6ed - failed to get root node of initfs
+ #5f8860 - no initfs module was given
+ #7e874d - failed to look up /bin/init
+ #9af5e6 - an unimplemented path in the kernel
+ #ba40bb - cpu exception occurred
+ #c39db3 - failed to parse /bin/init
diff --git a/documentation/sockets.txt b/documentation/sockets.txt
new file mode 100644
index 0000000..73dade6
--- /dev/null
+++ b/documentation/sockets.txt
@@ -0,0 +1,28 @@
+in hilbert os, a "socket" is a two-way byte-wise communication construct. each
+socket has two ends, which can be either open or closed. each process has a
+number of handles to sockets. sockets can be created in one of two ways: either
+creating a private socket or connecting to a socket listener.
+
+private sockets:
+ a private socket is created with the "create private socket" system call. the
+ process creating the socket gets both ends of the socket.
+
+socket listeners:
+ a socket listener is created with the "create socket listener" system call.
+ an id string is passed to that system call and remains associated with the
+ listener throughout its lifetime. only one socket listener may have a given
+ id at once. while a socket listener exists, the owner of the listener can
+ call the "accept socket connection" system call, and any process can call the
+ "connect to socket" system call with that id passed. each of these system
+ calls blocks until the other occurs, at which point a socket is created with
+ the two process as its endpoints, and then both system calls return. the
+ listener remains alive after the socket is created, and can be used to create
+ more sockets until stopped with the "stop socket listener" system call.
+
+when a process is created, an end of a socket can be "gifted" to that process.
+when that happens, the end remains open, and is now accessible by the giftee
+and not by the gifter.
+
+when either end of a socket is closed, the other end of the socket remains
+valid, and can be read from until empty. when both ends of a socket are closed,
+the socket disappears.
diff --git a/documentation/syscalls.txt b/documentation/syscalls.txt
index 15aabfa..52e909d 100644
--- a/documentation/syscalls.txt
+++ b/documentation/syscalls.txt
@@ -3,19 +3,32 @@ on application entry:
executable with guard pages on either side, and rsp is
set to the top of that. all other registers are set to 0.
+the ARGC environment variable holds the number of arguments to main.
+the ARGV0, ARGV1, ARGV2, etc environment variables hold those arguments.
+
for all system calls:
rax, rdi, rsi, rdx are in/out paramters.
rbx, rbp, rsp, r12-r15 are preserved.
rcx, rflags, r8-r11 are clobbered.
-file result:
- 0 = success
- 1 = bad file handle
- 2 = device error
- 3 = file system corrupt
- 4 = tried to read out of bounds
- 5 = file does not exist
- 6 = tried to open directory
+interrupts (including the timer!) are disabled during system calls.
+
+stream result:
+ 0 = success
+ 1 = bad handle
+ 2 = io error
+ 3 = out of bounds
+ 4 = does not exist
+ 5 = not a regular file
+ 6 = not an executable
+ 7 = not writable
+ 8 = not seekable
+ 9 = socket id already used
+ 10 = socket id not in use
+ 11 = socket listener closed
+ 12 = other end closed
+ 13 = already exists
+ 14 = not sized
encode color:
rax in: 0
@@ -34,39 +47,122 @@ open file:
rax in: 2
rdi in: pointer to file path
rsi in: file path length
- rax out: file result
- rdi out: file handle (if rax = success)
+ rdx in:
+ bit 0: allow creation
+ bit 1: only allow creation
+ rax out: stream result
+ rdi out: stream handle (if rax = success)
-get file length:
+end this thread:
rax in: 3
- rdi in: file handle
- rax out: file result
- rdi out: file length (if rax = success)
+ edi in: exit code (signed, only used if this was last thread)
-read from file:
+get new pages:
rax in: 4
- rdi in: pointer to request struct
- rax out: file result
- request struct:
- qword: file handle
- qword: start offset in bytes
- qword: length in bytes
- qword: pointer to buffer
+ rdi in: number of pages to allocate
+ rax out: start of first page
+ the allocated pages are next to each other, writable, and not executable.
-end this process:
+read key packet:
rax in: 5
- edi in: exit code (signed)
+ eax out: key packet
-get new pages:
+create private socket:
rax in: 6
- rdi in: number of pages to allocate
- rax out: start of first page
- the allocated pages are next to each other, writable, and not executable.
+ rax out: end 1 stream handle
+ rdi out: end 2 stream handle
-close file:
+create socket listener:
rax in: 7
- rdi in: file handle
+ rdi in: pointer to id string
+ rsi in: id string length
+ rax out: stream result
+ rdi out: listener handle (if rax = 0)
-read key packet:
+stop socket listener:
rax in: 8
- eax out: key packet
+ rdi in: listener handle
+
+accept socket connection:
+ rax in: 9
+ rdi in: listener handle
+ rax out: stream result
+ rdi out: stream handle
+
+connect to socket:
+ rax in: 10
+ rdi in: pointer to id string
+ rsi in: id string length
+ rax out: stream result
+ rdi out: stream handle (if rax = 0)
+ if the listener is closed while this syscall is blocked, rax is
+ set to "socket id not in use" and not "socket listener closed"
+
+close stream:
+ rax in: 11
+ rdi in: stream handle
+
+seek stream:
+ returns "not seekable" for sockets
+ rax in: 12
+ rdi in: stream handle
+ sil in:
+ 0 = relative to beginning
+ 1 = relative to end
+ 2 = relative to current position
+ rdx in: offset (signed)
+ rax out: stream result
+
+read from stream:
+ rax in: 13
+ rdi in: stream handle
+ rsi in: count
+ rdx in: pointer to buffer
+ rax out: stream result
+
+write to stream:
+ rax in: 14
+ rdi in: stream handle
+ rsi in: count
+ rdx in: pointer to buffer
+ rax out: stream result
+
+get stream length:
+ returns "not sized" for sockets
+ rax in: 15
+ rdi in: stream handle
+ rax out: stream result
+ rdi out: stream length (if rax = success)
+
+start process:
+ rax in: 16
+ rdi in: pointer to process start info struct
+ rax out: stream result
+ rdi out: process handle (if rax = success)
+ process start info struct:
+ qword: file path length
+ qword: pointer to file path
+ qword: count of environment variables
+ qword: pointer to array of environment variable structs
+ qword: count of gifted stream ends
+ qword: pointer to array of gifted stream structs
+ environment variable struct:
+ qword: name length
+ qword: pointer to name
+ qword: value length
+ qword: pointer to value
+ gifted stream struct:
+ qword: stream handle here
+ qword: new stream handle in child
+ new handle must be < 65536
+
+end this process:
+ rax in: 17
+ edi in: exit code (signed)
+
+set stream length:
+ returns "not sized" for sockets
+ rax in: 18
+ rdi in: stream handle
+ rsi in: new length
+ rax out: stream result