diff options
Diffstat (limited to 'documentation')
-rw-r--r-- | documentation/compositor.txt | 26 | ||||
-rw-r--r-- | documentation/euler/heap.txt | 32 | ||||
-rw-r--r-- | documentation/panics.txt | 8 | ||||
-rw-r--r-- | documentation/sockets.txt | 28 | ||||
-rw-r--r-- | documentation/syscalls.txt | 160 |
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 |