diff --git a/.wiki/Build-instructions.md b/.wiki/Build-instructions.md deleted file mode 100644 index efcf560..0000000 --- a/.wiki/Build-instructions.md +++ /dev/null @@ -1,45 +0,0 @@ -# Build instructions -**DISCLAIMER: To build this project you need a linux system (WSL could work for windows users, but I haven't tested it)** - - -First you need to clone the repository: - -`git clone https://codeberg.org/antifallobst/noxos/` - -then there are a few tools required, that need to be installed: -* **gcc** - compiler -* **ld** - linker -* **nasm** - assembler -* **cmake** - build system -* **xorriso** - ISO creation tools -* **qemu** - emulator - -There is a shell script to setup the workspace and compile. -Just run it using the following commands: -```bash -cd noxos -./build.sh -``` -If the Bootloader (Limine ([github](https://github.com/limine-bootloader/limine))) isn't downloaded yet, the script will download it. - -The final ISO file will be written to the *build* directory. - -To launch the ISO, run the `run.sh` script. - -# UEFI Emulation -To emulate an UEFI system, you need to install the `ovmf` package. -Then you can do `./run.sh uefi` to start qemu with uefi instead of bios. - -# Debugging -## Logs -When running through the script, qemu is configured to write the kernels logs to *STDOUT* and a file called *noxos.log*. -## GDB -You can connect GDB to qemu. -To achieve this, run `./run.sh debug`. -QEMU will wait until you connect GDB to it as a 'remote' target on `localhost:1234`. -```bash -gdb build/cmake/kernel/kernel -target remote localhost:1234 -c -``` -(note, that the last to commands have to be 'executed' in gdb not in your shell) \ No newline at end of file diff --git a/.wiki/Code-Style.md b/.wiki/Code-Style.md deleted file mode 100644 index cb6f53b..0000000 --- a/.wiki/Code-Style.md +++ /dev/null @@ -1,61 +0,0 @@ -# Code Style -## Naming conventions -- **structs** are suffixed with **_T** -- **typedefs** are suffixed with **_t** -- **enums** are suffixed with **_E** -- **global** variables are prefixed with **g_** - -Everything is **snake_case**. - -## Code readability -To make the code as readable and self explaining as possible, there are a few patterns that should be used. - -### Avoid abbreviations -Give your variables, functions, etc. meaningfull names. -The times of 80char wide screens are over, feel free to use that space :D - -Example: `sym_at_idx` -> `get_symbol_at_index` - -But you're not forced to (anything) write out everything. -For example the **Interrupt Descriptor Table** is simply referred to as **idt** (this abbreviation is btw standard). - -### Avoid indentation nesting -In a perfect codebase, the maximum indention level would be 3. -The goal of NoxOS is not to be a perfect codebase, but please avoid huge indention nesting. -To achieve this, you can break parts into extra functions and/or use the early return pattern. - -Example: -```c -bool likes_pigs (void* a) { - if (a != NULL) { - if (a == 0xACAB) { - return false; - } - } - return true; -} -``` --> -```c -bool likes_pigs (void* a) { - if (a != NULL) { return true; } - if (a != 0xACAB) { return true; } - - return false; -} -``` - -### align declarations - -Please align declarations, definitions, etc like in the example: -```c -char am_i_a_variable = '?'; -uint64_t number = 0; -bool i_waste_bits = true; -``` - -### namespaces -Unlike C++ C has no namespaces. -To achieve the goal of namespaces, please prefix your functions, structs, etc. with the "namespace" they are in. - -Example: `out_byte` -> `io_out_byte` diff --git a/.wiki/Contribution-guide.md b/.wiki/Contribution-guide.md deleted file mode 100644 index 06b46c3..0000000 --- a/.wiki/Contribution-guide.md +++ /dev/null @@ -1,47 +0,0 @@ -Welcome :D - -Nice, that you're interested in contributing. - -There are several ways to contribute to NoxOS: -- Write code -- Maintain Documentation - - Typos - - Grammar - - Is the documentation up to date? -- Plan stuff (e.g. syscalls) -- open Issues - -# Before Contribution -Please read the [Code-Style wiki entry](https://codeberg.org/antifallobst/noxos/wiki/Code-Style) before you start to contribute. - -For workspace setup and build instructions look at [this wiki entry](https://codeberg.org/antifallobst/noxos/wiki/Build-instructions). - -**We don't accept any Assholes! If you're a fascist, racist, or discriminate others for anything, go fuck yourself.** - -# Contributing - -When you contribute code, please [document](https://codeberg.org/antifallobst/noxos/wiki/Kernel-documentation) it. -You don't have to (and you also shouldn't) write romans, but a few lines for every in a header exposed function, struct etc. help others (and yourself) understanding how to interact with your code. - - -## What dafuq is ...? -OS development can be quite complicated/confusing. That's Ok. -Stuff like Paging can be really weird, if you don't have osdev experience. -But there are learning resources and places, where you can ask questions. - -**A small overview about such resources and places:** -- The [osdev wiki](https://wiki.osdev.org) is like wikipedia - just for hobby os developers. -- The [osdev subreddit](https://reddit.com/r/osdev) is a great place to ask questions and share knowledge -- Intel's [developer manual](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html) is a more advanced but kinda precise information source - -Also feel free to join the [NoxOS Matrix space](https://matrix.to/#/#noxos:systemausfall.org), -where you can chat with other NoxOS devs and ask questions. -**But Stay Respectful, Or We `sudo rm -rf /` Your PC ;)** - -# Where to start? - -Get the codebase and play a bit around with it. -Try to understand basic concepts of the codebase, the [documentation](https://codeberg.org/antifallobst/noxos/wiki/Kernel-documentation) will help you. -After that you can search the [Issues](https://codeberg.org/antifallobst/noxos/issues) for the `Good First Issue` label, -to find easy improvements, etc. that you can try to implement. -Another option is to ask in the [Matrix Space](https://matrix.to/#/#noxos:systemausfall.org). \ No newline at end of file diff --git a/.wiki/Home.md b/.wiki/Home.md deleted file mode 100644 index dbb4fc0..0000000 --- a/.wiki/Home.md +++ /dev/null @@ -1,11 +0,0 @@ -**DISCLAIMER: We don't accept any Assholes! If you're a fascist, racist, or discriminate others for anything, go fuck yourself.** If not, welcome :) - -The wiki on codeberg is probably less frequently updated, than the `.wiki` directory in the codebase. - -Wiki Content: - -* [Contribution guide](https://codeberg.org/antifallobst/noxos/wiki/Contribution-guide) -* [Build instructions](https://codeberg.org/antifallobst/noxos/wiki/Build-instructions) -* [Code Style](https://codeberg.org/antifallobst/noxos/wiki/Code-Style) -* [Kernel Documentation](https://codeberg.org/antifallobst/noxos/wiki/Kernel-documentation) -* [Project Roadmap](https://codeberg.org/antifallobst/noxos/wiki/Roadmap) \ No newline at end of file diff --git a/.wiki/Kernel-documentation.md b/.wiki/Kernel-documentation.md deleted file mode 100644 index 6dfc872..0000000 --- a/.wiki/Kernel-documentation.md +++ /dev/null @@ -1,1779 +0,0 @@ -# Kernel Documentation -The kernel is booted using the limine boot protocol. - -## Directory structure - - **boot** - all stuff related to booting / jumping into the kernel - - **drivers** - everything from the graphics driver, to the FS drivers - - **mm** - memory management stuff like page frames and page maps - - **platform** - universal API to the platform specific code in the subdirs - - **proc** - all the process/thread related stuff like the scheduler - - **utils** - utilities like type definitions, math functions, high-level memory management - ---- - -# General concepts -## Kernel initialization -The single parts of the kernel are initialized in the following order: - - **Page Frame Manager** - - **Interrupts** - - **[IDT] Interrupt Descriptor Table** - - **[PIC] Programmable Interrupt Controller** - - **Paging** - - **Kernel Heap** - - **Graphics Renderer** - - **Scheduler** - -## Interrupt handling -OSDev Wiki: [Interrupts](https://wiki.osdev.org/Interrupts) - -Unfortunatly the x86 architecture doesn't provide a method to get the ID of the current interrupt. -To solve this problem, there is a simple assembly function for every interrupt used by NoxOS. -This function pushes its ID on the stack. -After that it calls a common Interrupt handler, this handler will generate the current `cpu_state_T` and call the C interrupt handler implementation. -The C implementation returns a `cpu_state_T` that will then be loaded. - -## Paging -OSDev Wiki: [Paging](https://wiki.osdev.org/Paging) - -There is a difference between `Virtual Memory Spaces` and the `Physical Memory Space`. -The Physical memory space is how the data lies directly in the RAM. - -Virtual memory spaces are a bit more tricky. -To understand them, we have to understand first, that the physical memory space is divided into so-called **pages** / **page frames**. -These pages have a size of 4KB. - -A virtual memory space is a table of page mappings. -Per default there are no pages mapped to such a table. -When the OS maps a page to a **page table**, it says: -"This page is now accessible from this virtual space, at this address". -When the Computer is in paging mode, only mapped pages are accessible. -Now every Process gets its own page table and tada: we have successfully isolated the processes from each other, -because every process can only access the data that it needs to access. - -## Panic screen -When a fatal / not recoverable error occurs, the kernel panics. It logs panic information and then halts forever. -Such a panic log can look like the following one: -``` -[ Error ] !=====[ KERNEL PANIC ]=====! -Error Message: Division Error -Interrupt ID: 0x00 -Error Code: 0b00000000000000000000000000000000 - -Paging Info: - Page Map: 0x000000000FAE9000 - -CPU Flags: - Parity - Sign - Interrupt Enable - -CPU Registers: - RIP: 0xFFFFFFFF80002745 RAX: 0x0000000000000001 RBX: 0x0000000000000000 - RCX: 0x0000000000000000 RDX: 0x0000000000000000 RSI: 0x000000000001F980 - RDI: 0x00001000005DF7A0 RBP: 0xFFFF80000FAF9F40 RSP: 0xFFFF80000FAF9F30 - -Call Stack: - 0xFFFFFFFF80000000+033F -> _start - 0xFFFFFFFF8000274D+0078 -> kmain - 0xFFFFFFFF80002732+0013 -> test -[ Warning ] !=====[ HALTING SYSTEM ]=====! -``` -but what does it say? - -In most cases, a panic occurs while handling an interrupt. -If this is the case, we will have the state of the cpu while it was interrupted. -This cpu state provides us very much information. - -`Interrup ID` tells us, which interrupt caused the panic. -In this case the ID is `0x0E`, a `Page Fault Exception`. - -`Error Code` is a binary representation of the 32 least significant bits of the error code pushed by some interrupts. -If an interrupt pushes no error code, this will be just zeros. -In our example the code tells us, that the error happened because of a write attempt to a not present page. - -`Error Message` tells us, what happened. - -`Paging Info` contains all information about paging. -At the moment, this is just the physical address of the loaded page map. - -`CPU Flags` contains information about which bits are set in the CPU status register. -If this block doesn't appear, there are no bits set. - -`CPU Registers` contains the data, in the main cpu registers. -This is probably the most interesting block, because you get very detailed information out of here, -if you know what each of these registers does in the cpu. - -`Call Stack` lists the current function call chain, starting from the least recent call. -The big hex number is the base of the function and the small hex number is the offset, where the next function was called. -After the `->` follows the name of the function. - -### Panic without interrupt -If the panic wasn't caused by an interrupt, it has no cpu_state, and because of that it has no detailed info about the execution state. -In this rare case, you will get the following message: -``` -No detailed Information available (cpu_state null reference) -``` -The `Error Message` could still be helpful, but good luck finding that bug. - -## Memory Layout -NoxOS uses a higher half kernel, this means, that the kernels executable is mapped above `0x800000000000`. -All kernel and bootloader resources are also mapped in the higher half. -This leaves the lower half for process specific mappings - - -## Process Memory Isolation -Every process has its own virtual memory space (page map). -This space contains always the following mappings (except in the kernels main process): - -| Name | Address | Permissions | -|---------------------------|--------------------|-------------------| -| Process executable | 0x0000010000000000 | as defined in ELF | -| Thread data (stack, etc.) | 0x0000010100000000 | Read/Write | -| Kernel executable | 0xFFFFFFFF80000000 | Read/Exec | -| Kernel Heap | 0xFFFFFFFFF0000000 | Read/Write | - -### Thread data -Every thread has a _Thread Data_ region, that contains thread specific stuff like a stack. - -The first threads _Thread Data_ region is at `0x0000010100000000`, the seconds at `0x0000010200000000` and so on. - -In this setup, every _Thread Data_ region has a virtual size of 4GB. - -### Context switching -Switching between threads is a bit tricky, when the threads stacks are in different page maps. -When performing a context switch, the memory region `0x0000010000000000` <--> `0x0000020000000000` -is dirty mapped (the PML4 entries are copied) from the next processes' into the kernels page map. -This region contains all _Thread Data_ regions and the processes' executable mappings. -Due to this dirty mapping the next interrupt handler can always access the current processes' or threads' data. - -## Syscalls -NoxOS will use interrupt based syscalls. -To perform a syscall, write its ID into the `rax` register and call interrupt 0x80. - -**Example:** -```nasm -mov rax, 0x0000 -int 0x80 -``` - -The syscalls are grouped into groups and their ID consists of a _group-ID_ (first two digits) and a _syscall-ID_ (last two digits). - -### Syscall groups - - **Misc** - 0x00 - - **File** - 0x01 - - **Proc** - 0x02 - - **Kernel** - 0xFF - -### Misc Syscalls - `0x00--` - -### File Syscalls - `0x01--` - -### Proc Syscalls - `0x02--` - -### Kernel Syscalls - `0xFF--` -The kernel syscalls can only be called by the kernel process and its childs. All other processes, won't be able to use this functions. - -| ID | Name | Description | -|--------|-----------------|------------------------------------------------------------------------------------------------------| -| 0xFF00 | scheduler_start | Initializes the Kernels main thread from the current cpu_state. This is used to start multithreading | - - -## Format strings -Format strings are strings that are formatted at runtime. -They are created by defining a pattern, like the following one: - -`"Name: %s / ID: %d"` - -And giving it arguments at runtime, let's use the following ones for our example: - -`"Main Process", 42` - -This would format to that: - -`Name: Main Process / ID: 42` - -As you see, `%s` and `%d` are placeholders. -Placeholders consist of a `%` sign followed by one or two letters. -When formatting the string, the placeholders are replaced with the arguments. -The first placeholder is replaced with the first argument, the second with the second and so on. - -### Numeric specifier -If you put a `.` followed by a number right after the percentage sign of a placeholder, -you will set the `Numeric specifier`. -If the `.` is followed by an astrix, the numeric specifier is passed as its own argument. -Some placeholders use this numeric specifier to configure their output. -If you don't set a numeric specifier, the placeholders, that would use it will use a default value instead. - -### Arguments -Make sure, that the arguments you pass, are really of the right type. -If you e.g. pass a negative value of type `int32_t` like `-1312`, -the formatter will have problems with that, because the `int32_t` representation of that number is as an `int64_t` a positive number. - -### Placeholders -#### `%s` - string -| **Argument Type** | `string_t` | -|-------------------------------|--------------------------------------------------| -| **Numeric Specifier Use** | Specifies the maximum length the string can have | -| **Numeric Specifier Default** | String Length | -| **Description** | Inserts a string | - -#### `%c` - char -| **Argument Type** | `char` | -|-------------------------------|---------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a character | - -#### `%u` - unsigned decimal -| **Argument Type** | `uint64_t` | -|-------------------------------|-----------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts an unsigned integer | - -#### `%d` - signed decimal -| **Argument Type** | `int64_t` | -|-------------------------------|--------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a signed integer | - -#### `%x` - hexadecimal -| **Argument Type** | `uint64_t` | -|-------------------------------|------------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a 64 bit hex integer | - -##### variants -###### `%xb` - byte hexadecimal -| **Argument Type** | `uint8_t` | -|-------------------------------|-----------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a 8 bit hex integer | - -###### `%xw` - word hexadecimal -| **Argument Type** | `uint16_t` | -|-------------------------------|------------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a 16 bit hex integer | - -###### `%xd` - dword hexadecimal -| **Argument Type** | `uint32_t` | -|-------------------------------|------------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a 32 bit hex integer | - -###### `%xq` - qword hexadecimal -This variant is the `%x` standard. - -| **Argument Type** | `uint64_t` | -|-------------------------------|------------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts a 64 bit hex integer | - - -#### `%?` - boolean -| **Argument Type** | `bool` | -|-------------------------------|---------------------------| -| **Numeric Specifier Use** | None | -| **Numeric Specifier Default** | None | -| **Description** | Inserts `true` or `false` | - -#### `%b` - binary -| **Argument Type** | `uint64_t` | -|-------------------------------|-----------------------------------------------| -| **Numeric Specifier Use** | The amount of bits that are shown | -| **Numeric Specifier Default** | 64 | -| **Description** | Inserts the binary string of the given number | - -#### `%%` - mask -This is not a really a placeholder, but you can use this to mask the % sign, -so it will be interpreted as just a `%` instead of a placeholder. - - -## Executables -NoxOS uses the **ELF** executable format, which is the linux/unix standard. -Further information can be found in the `Syscalls` and `drivers/elf/elf.h` documentation. - ---- - -**DISCLAIMER:** Only the headers are documented, because documenting the whole code itself would be very time intensive and the headers as 'public' API are the most important to document. - -## boot - -### boot_info.h -The goal of this file is to provide a universal struct of information needed by the kernel at start time. -At the moment this information is very limine specific, but the goal is to make it easy to add support for other boot protocols. - -#### `boot_info_T` - struct -| Name | Description | -|-------------|---------------------------------------------------| -| framebuffer | struct with information about the graphics buffer | -| terminal | bootloader terminal / graphical log | -| memory_map | information about the memory layout / regions | -| kernel_file | The unparsed kernel ELF file | -| rsdp | _Root System Description Pointer_ | - -### limine.h -This header provides the API to "communicate" with the limine bootloader. -More information can be found on the limine project's [GitHub](https://github.com/limine-bootloader/limine/blob/trunk/PROTOCOL.md). - - -## drivers - -### acpi/acpi.h -OSDev Wiki: [ACPI](https://wiki.osdev.org/ACPI) - -#### `acpi_init(boot_info)` - function (void) -Initializes the ACPI (Advanced Configuration and Power Interface). - -### acpi/rsdp.h -OSDev Wiki: [RSDP](https://wiki.osdev.org/RSDP) - -#### `rsdp_descriptor_v1_T` - struct [packed] -The RSDP Table used in ACPI v1.0 - -| Name | Type | Description | -|--------------|----------|-----------------------------------------------------------| -| signature | char[8] | Needs to be `"RSD PTR "` (with the withespace at the end) | -| checksum | uint8_t | Used to validate the table | -| oem_id | char[6] | This string identifies the OEM | -| revision | uint8_t | Tells whether the RSDP is version 1 or 2+ | -| rsdt_address | uint32_t | The Physical Address of the RSDT | - -#### `rsdp_descriptor_v2_T` - struct [packed] -The RSDP Table used in ACPI v2.0 or higher - -| Name | Type | Description | -|-------------------|----------------------|----------------------------------------------------------------------------------| -| descriptor_v1 | rsdp_descriptor_v1_T | A table in the format of the ACPI 1.0 specification | -| length | uint32_t | The size of the whole table | -| xsdt_address | uint64_t | The Address of the XSDT (when available this should be used instead of the RSDT) | -| checksum_extended | uint8_t | Used to calculate the checksum of the whole table | -| reserved | uint8_t[3] | Can be ignored | - - -### elf/elf.h -#### `elf_executable_T` - struct -This struct holds the parsed data of an ELF executable. - -| Name | Type | Description | -|--------------|----------------|----------------------------------------------------------------------------------------------------------------------------------| -| header | elf_header_T | The header of the elf file | -| num_symbols | uint64_t | The size of _symbols_ | -| symbols | symbol_T* | An array containing all symbols of the elf file | -| num_mappings | uint64_t | The size of _mappings_ | -| mappings | elf_mapping_T* | An array containing the mappings needed to load the elf file | -| string_table | void* | A copy of the elf files `.strtab` section, all strings are referenced here to have them available even if the elf file is closed | - -#### `elf_executable_temp_T` - struct -This struct is used while generating an `elf_executable_T`. -It holds parse-time information about the elf file. - -| Name | Type | Description | -|-----------------------------|-------------------|------------------------------------------------| -| executable | elf_executable_T* | A pointer to the final `elf_executable_T` | -| symbol_table | elf_section_T* | A pointer to `.symtab` in _buffer_ | -| section_header_string_table | elf_section_T* | A pointer to `.shstrtab` in _buffer_ | -| buffer | uint8_t* | The buffer where the executable is loaded from | - -#### `elf_executable_create(buffer)` - function (elf_executable_T*) -Generates an `elf_executable_T` from an elf file loaded to **_buffer_** and returns a pointer to it. - -#### `elf_executable_destruct(executable)` - function (void) -Frees all memory allocated for **_executable_**. - -### elf/header.h -The enums in this header describe the possible values that a field of the elf header can have. - -#### `elf_target_architecture_E` - enum -Field in header: **identity[4]** - -#### `elf_endianness_E` - enum -Field in header: **identity[5]** - -#### `elf_sysabi_E` - enum -Field in header: **identity[7]** - -#### `elf_object_type_E` - enum -Field in header: **type** - -#### `elf_instruction_set_E` - enum -Field in header: **isa** - -#### `elf_header_T` - struct - -| Name | Type | Description | -|----------------------------|-------------|-------------------------------------------------------------------| -| identity | uint8_t[16] | Information like the used endian and the SysABI is stored in here | -| type | uint16_t | The type of the elf file -> `elf_object_type_E` | -| isa | uint16_t | The used instruction set -> `elf_instruction_set_E` | -| version | uint32_t | ELF version | -| address_entry_point | uint64_t | The start point for program execution | -| offset_program_header | uint64_t | The position of the program header array in the file | -| offset_section_header | uint64_t | The position of the section header array in the file | -| flags | uint32_t | Architecture dependent, can be ignored | -| len_header | uint16_t | The size of this header | -| len_program_header_entry | uint16_t | The size of one program header | -| num_program_header_entries | uint16_t | The amount of program headers | -| len_section_header_entry | uint16_t | The size of one section header | -| num_section_header_entries | uint16_t | The amount of section headers | -| string_section_index | uint16_t | The section header index of the `.shstrtab` section | - - -#### `g_elf_target_architecture_strings` - global variable -An array of strings matching `elf_target_architecture_E`. - -#### `g_elf_endianness_strings` - global variable -An array of strings matching `elf_endianess_E`. - -#### `g_elf_sysabi_strings` - global variable -An array of strings matching `elf_sysabi_E`. - -#### `g_elf_object_type_strings` - global variable -An array of strings matching `elf_object_type_E`. - -#### `g_elf_instruction_set_strings` - global variable -An array of strings matching `elf_instruction_set_E`. - -#### `elf_init_kernel_exec(boot_info)` - function (void) [Will be replaced in near future] -Loads the kernel elf into `g_kernel_executable`. - -#### `g_kernel_executable` - global variable [Will be replaced in near future] -Holds the parsed kernel executable. - -This will be removed, when processes are implemented, because then this can be accessed via the kernel process control struct. - -### elf/mapping.h -#### `elf_mapping_T` - struct -A mapping describes an area of memory, -that should be copied from the elf file into the RAM and how/where it should be mapped. - -| Name | Type | Description | -|----------------|----------|------------------------------------------------------------------------------------------------------------------| -| offset_file | uint64_t | The mappings' start in the elf file | -| offset_virtual | uint64_t | The mappings' start in memory | -| length_file | uint64_t | The mappings' size in the elf file | -| length_virtual | uint64_t | The mappings' size in memory, if this is bigger than _length_file_ the remaining space will be filled with zeros | - -#### `elf_mappings_apply(mappings, num_mappings, buffer, base, page_map)` - function (void) -Maps all **_mappings_** into **_page_map_** and copies the related data from **_buffer_** (elf file) to the mapped memory. -**_base_** specifies where the mappings should start in the virtual address space. - -### elf/section.h -#### `elf_section_type_E` - enum - - **Null** - These sections can be ignored - - **Program Data** - These link to segments, if I remember right - - **Symbol Table** - Here are all the executables' symbols stored - - **String Table** - Here are all strings stored - - **RelocationA** - Contains relocation information - - **Hash** - Symbol Table hash table - - **Dynamic Link** - This provides information for the dynamic linker - - **Note** - notes that were created by the compiler / toolchain - - **Nobits** - Nulled data like `.bss` - -#### `elf_section_T` - struct - -| Name | Type | Description | -|-----------------|----------|-------------------------------------------------------------------| -| name_offset | uint32_t | The offset of the sections name in `.shstrtab` | -| type | uint32_t | The type of the section -> `elf_section_type_E` | -| flags | uint64_t | Sections attribute flags | -| virtual_address | uint64_t | The address where the section should be mapped to (if it's not 0) | -| offset | uint64_t | The sections offset in the file | -| length | uint64_t | The size of the section | -| link | uint32_t | Type specific link to another section | -| info | uint32_t | Type specific information | -| alignment | uint64_t | If the section is aligned, this value specifies the alignment | -| entry_size | uint64_t | The size of the sections entries | - - -#### `g_elf_section_type_strings` - global variable -An array of strings matching `elf_section_type_E`. - -### elf/segment.h -#### `elf_segment_type_E` - enum - - **Null** - Unused segment - - **Load** - Segment that should be included into mappings - - **Dynamic** - Segments of this type contain dynamic linking information - - **Interpreter** - This holds a path to an interpreter - - **Note** - These segments hold notes by the compiler / toolchain - - **Program Header Table** - This points to the table that is holding the segment headers - - **TLS** - This holds a Thread Local Storage template - -#### `elf_segment_T` - struct - -| Name | Type | Description | -|------------------|----------|-----------------------------------------------------------------| -| type | uint32_t | The segments type -> `elf_segment_type_E` | -| flags | uint32_t | The segments flags (Read / Write / Execute) | -| offset | uint64_t | The segments position in the elf file | -| address_virtual | uint64_t | Where the segment should be mapped in the virtual address space | -| address_physical | uint64_t | Not used in the `System V` ABI | -| length_file | uint64_t | The segments size in the file | -| length_memory | uint64_t | The size of the area that should be mapped for the segment | -| align | uint64_t | The segments alignment (has to be a power of 2) | - -#### `g_elf_segment_type_strings` - global variable -An array of strings matching `elf_segment_type_E`. - -### elf/symbol.h -#### `ELF_SYMBOL_TYPE(info)` - macro -Extracts the `elf_symbol_type_E` from the symbols info value. - -#### `elf_symbol_type_E` - enum - - **None** - Unspecified type - - **Object** - Data objects like variables, arrays, etc. - - **Func** - Function - - **Section** - Associated section - - **File** - The path to the source file associated with the object - - **Common** - Uninitialized common blocks - - **TLS** - Thread Local Storage - -#### `elf_symbol_T` - struct - -| Name | Type | Description | -|-----------------------|-------------------------------------------------------------------|-------------| -| name_offset | The offset of the symbols name in `.strtab` | | -| info | Information about the symbol (type, bind) | | -| other | Information about the symbol (visibility) | | -| related_section_index | The index of the symbols related section | | -| value | Value, in most cases this is an address | | -| length | The size of the symbol (e.g. num bytes if the symbol is an array) | | - - -### fs/ramfs.h -**Warning:** This is a filesystem specific driver, by this it should only be accessed by the vfs. - -The ramfs (ram-filesystem) is not a filesystem in the common sense. -All data that is stored in ramfs is stored in the virtual file systems cache. -This means that all data in ramfs is temporary and erased after a reboot. - -#### `ramfs_file_delete(node)` - function (void) -Frees the files cache space. This won't delete the node in the vfs. - -#### `ramfs_file_write(node, size, buffer_in)` - function (void) -If this file has some cache space allocated, it will be freed. -Then there will be some cache space (**_size_** bytes) allocated and **_size_** bytes from **_buffer_in_** copied into the cache. - -This use of the vfs cache isn't a great solution and should be reworked. - -#### `ramfs_file_read(node, size, buffer_out)` - function (void) -Copies **_size_** bytes from the files' cache to **_buffer_out_**. -This won't copy more bytes than the allocated cache space is big. - -### fs/ustar.h -The USTAR '_filesystem_' is probably more common known as **tar**-archive. -It is a really simple concept, where a file consists of a header block followed by data blocks. -These blocks are aligned at 512 bytes. - -OSDev Wiki: [USTAR](https://wiki.osdev.org/USTAR) - -#### `ustar_type_E` - enum -The types an entry can have: - - **File** - - **Hardlink** - - **Symlink** - - **Char Device** - - **Block Device** - - **Directory** - - **Pipe** - -#### `ustar_header_T` - struct [packed / 512B aligned] - -| Name | Type | Description | -|-------------------|-----------|------------------------------------------------------------------------------| -| name | char[100] | The name of the entry | -| mode | uint64_t | file mode (permissions, etc) | -| owner_id | uint64_t | The owners ID | -| group_id | uint64_t | The groups ID | -| size | char[12] | The size of the entry, represented as a string of an octal number (dafuq) | -| last_modification | char[12] | The unix-timestamp, when the entry was modified the last time | -| checksum | uint64_t | I think this is a weird checksum of the header | -| type | uint8_t | The type (`ustar_type_E`) of the entry, represented as ascii numbers (dafuq) | -| name_linked | char[100] | The path to the linked entry, if this is a link-entry | -| indicator | char[6] | This needs to be `ustar` | -| version | uint16_t | The version of the **tar** command, that created the archive | -| owner_user_name | char[32] | The name of the file owner | -| owner_group_name | char[32] | The name of the file group | -| device_major | uint64_t | The devices major number | -| device_minor | uint64_t | The devices minor number | -| name_prefix | char[155] | If this is not null, this acts as a prefix for _name_ | - - -### fs/vfs.h - -**VFS** stands for _Virtual File System_ and is an abstraction, -that kinda merges all mounted filesystems into one. -It provides a general API for dealing with files, and handles all fs specific stuff in the background. -This VFS is node based, meaning, that every file, directory, mount point, etc is represented as a node in memory. -Nodes have a type and a fs. -Nodes can have children and next and previous nodes. - -Example node relations: -``` -+-----------+ -| Root Node | <---------+ -+-----------+ | - | | -[Childs] [Parent] - | +-------------+---------------+ - v / | \ -+-------+ +-------+ +-------+ -| Child | --[Next]-> | Child | --[Next]-> | Child | -| 1 | <-[Prev]-- | 2 | <-[Prev]-- | 3 | ... -+-------+ +-------+ +-------+ - | -[Childs] - | - v - ... -``` - -If a node is accessed it is linked as the first node in the childs order, to make name resolving process faster. - -#### `VFS_MAX_NAME_LENGTH` - macro -The maximum length of a nodes name. -Bigger names will be cut of at the end. - -#### `fs_type_E` - enum -This enum specifies all supported filesystems: - - **RAMFS** - A filesystem, that is bound very tight to the vfs and is completely in the RAM. - -#### `vfs_node_type_E` - enum -This enum specifies all types a node can have: - - **Directory** - A directory can contain other nodes - - **File** - A file can hold data - - **Mount Point** - A mount point is like a directory, but in the vfs backend this resolves to the root of a filesystem - - **Block Device** - Neither used nor implemented yet - -#### `fs_T` - struct -This struct specifies a filesystem instance. - -| Name | Type | Description | -|-----------|-------------|-------------------------------------------------------------| -| type | fs_type_E | The type of the filesystem | -| root_node | vfs_node_T* | A pointer to the vfs node of the filesystems root directory | - -#### `vfs_node_cache_T` - struct -The current node caching system is just a small placeholder that will be reworked soon. - -| Name | Type | Description | -|-------------|-------------|-----------------------------------------------------| -| buffer | void* | The actual buffer, where data is cached | -| buffer_size | uint64_t | The size of _buffer_ | -| reclaimable | bool | Not used atm, but could be important after refactor | -| node | vfs_node_T* | The node, that the cache belongs to | - - -#### `vfs_node_T` - struct - -| Name | Type | Description | -|------------|------------------|------------------------------------------------| -| name | char[] | The name of the node | -| type | vfs_node_type_E | The type of the node | -| cache | vfs_node_cache_T | The nodes cache segment | -| size | uint64_t | The nodes size | -| specific | void* | General purpose pointer (details below) | -| filesystem | fs_T* | The filesystem this node actually lies in | -| prev | vfs_node_T* | The previous node | -| next | vfs_node_T* | The next node | -| parent | vfs_node_T* | The parent node (has to be dir or mount point) | -| childs | vfs_node_T* | The first child node | - -##### specific -The usage of this value is specific to th nodes type: - - **Directories:** NULL - - **Files:** NULL - - **Mount points:** a pointer to the mounted filesystem. - - **Block devices:** NULL - -#### `g_root_fs` - global variable -The systems root filesystem. -Every node resolve will start at this filesystem. - -#### `vfs_node_cache_create(node, size)` - function (vfs_node_cache_T*) -Allocates a **_size_** bytes big cache segment for **_node_**. - -#### `vfs_node_cache_destruct(node_cache)` - function (void) -Frees **_node_cache_** and its buffer. - -#### `vfs_node_create(parent, name, type, specific)` - function (vfs_node_T*) -Allocates a node with the given parameters. -The nodes _fs_ value is inherited from **_parent_**, -or from **_parent_**'s specific value if **_parent_** is a mount point. - -#### `vfs_node_destruct(node)` - function (void) -Recursively destructs **_node_** and all it's children. - -#### `vfs_node_dump_info(node, indent)` - function (void) -Prints the complete directory structure starting at **_node_**. -**_indent_** is used for the recursive calls and should be set to 0. - -#### `vfs_node_resolve_child(node, child_name)` - function (vfs_node_T*) -Searches **_node_** for a child named **_child_name_**. -Returns the first matching child or NULL if no matching child was found. - -#### `vfs_file_create(filesystem, path)` - function (vfs_node_T*) -Creates a file at **_path_** in **_filesystem_** and returns a pointer to it. -The directory in **_path_** needs to exist and the filename needs to not exist. - -#### `vfs_file_delete(file)` - function (void) -Deletes **_file_**. - -#### `vfs_file_write(file, position, size, buffer_in)` - function (void) -Writes **_size_** bytes from **_buffer_in_** at **_position_** into **_file_**. - -**Warning:** the current ramfs implementation will ignore **_position_**! - -#### `vfs_file_read(file, position, size, buffer_out)` - function (void) -Reads **_size_** bytes from **_file_** at **_position_** into **_buffer_out_**. - -**Warning:** the current ramfs implementation will ignore **_position_**! - -#### `vfs_directory_create(filesystem, path)` - function (vfs_node_T*) -Creates a directory at **_path_** in **_filesystem_** and returns a pointer to it. -The directory in **_path_** needs to exist and the name of the new directory (after the last `/`) needs to not exist. - -#### `vfs_directory_delete(directory)` - function (void) [not implemented yet] -Deletes a directory. - -#### `vfs_init(boot_info)` - function (void) -Initializes the VFS. -In future this will also unpack the initial ramdisk into the _temp_ directory. - -#### `vfs_resolve_path(filesystem, path)` - function (vfs_node_T*) -Returns the node at **_path_** or NULL if **_path_** is invalid. - -#### `vfs_unpack_archive_ustar(filesystem, archive)` - function (void) -This will unpack a USTAR-archive (**_archive_**) at **_filesystem_**'s root. - -### graphics/color.h - -#### `color_palette_E` - enum -Indexes for `g_color_palette` - - **Grey Dark** - - **Pink** - - **Signal Green** - - **Orange** - - **Blue** - - **Purple** - - **Green** - - **Grey Light** - - **Red** - -#### `color_argb_T` - struct -| Name | Type | Description | -|-------|---------|---------------------------------| -| alpha | uint8_t | Transparency value of the color | -| red | uint8_t | Red value of the color | -| green | uint8_t | Green value of the color | -| blue | uint8_t | Blue value of the color | - -#### `color_argb_blend_alpha(background, foreground)` - function (color_argb_T) -Blends **_background_** and **_foreground_** with the _alpha_ value of **_foreground_**. - -#### `g_color_palette` - global variable -An array of standard colors. -This array is indexed using `color_palette_E`. - -### graphics/font.h -#### `font_T` - struct - -| Name | Type | Description | -|------------|----------|------------------------------------------------| -| width | uint8_t | The width of each char (in pixels) | -| height | uint8_t | The height of each char (in pixels) | -| glyph_size | uint8_t | The amount of bytes a char takes in the buffer | -| buffer | uint8_t* | The buffer, where the char bitmaps lay | - -#### `g_font` - global variable -A global usable 8x8 font. - -### graphics/framebuffer.h -#### `framebuffer_T` - struct - -| Name | Type | Description | -|-----------------|----------|-----------------------------------------------------| -| address | void* | The address of the framebuffer | -| width | uint64_t | The pixel width of the framebuffer | -| height | uint64_t | The pixel height of the framebuffer | -| pitch | uint64_t | The number of bytes in each row | -| bits_per_pixel | uint16_t | The amount of bits a pixel consumes in the buffer | -| bytes_per_pixel | uint8_t | The amount of bytes a pixel consumes in the buffer | -| shift_red | uint8_t | How many bits the red value is shifted in a pixel | -| shift_green | uint8_t | How many bits the green value is shifted in a pixel | -| shift_blue | uint8_t | How many bits the blue value is shifted in a pixel | - - -### graphics/renderer.h -#### `graphics_buffer_layer_E` - enum - - **Standard** - The layer, where almost everything should be on - - **Overlay** - This layer should be used for stuff like a mouse cursor, that should always be visible - -#### `graphics_buffer_T` - struct - -| Name | Type | Description | -|---------|-------------------------|------------------------------------------------------------------------------| -| buffer | color_argb_T* | The buffer, where all the pixels are stored | -| width | uint32_t | The width of the buffer | -| height | uint32_t | The height of the buffer | -| pos_x | uint32_t | The buffers x offset (from the top-left corner) in the renderers main buffer | -| pos_y | uint32_t | The buffers y offset (from the top-left corner) in the renderers main buffer | -| blocked | bool | Thread safety block variable | -| render | bool | Controls, if the buffer will be rendered or not | -| layer | graphics_buffer_layer_E | The layer, on which the buffer will be rendered | -| prev | graphics_buffer_T* | The previous buffer in the rendering queue | -| next | graphics_buffer_T* | The next buffer in the rendering queue | - -#### `graphics_renderer_T` - struct - -| Name | Type | Description | -|------------------------|---------------------|------------------------------------------------------------------------------------------| -| framebuffer | framebuffer_T | The systems framebuffer (requested from bootloader) | -| back_buffer | uint32_t* | The buffer, where the final image is calculated, before sending it to the framebuffer | -| buffer_size | uint64_t | The size of `back_buffer` (in bytes) | -| graphics_buffer_layers | graphics_buffer_T** | List of pointers to the first graphics_buffer of every layer | -| font | font_T | The font, all graphics buffers use to draw chars (could be moved to `graphics_buffer_T`) | -| initialized | bool | Indicates whether the renderer is initialized or not | -| blocked | bool | Blocking variable that is used for thread safety in `graphics_renderer_update` | - - -#### `graphics_buffer_request(pos_x, pos_y, width, height, layer)` - function (graphics_buffer_T*) -Allocates a graphics buffer and pushes it on top of the rendering queue of **_layer_**. - -#### `graphics_buffer_show(graphics_buffer)` - function (void) -Enables rendering for this buffer. -Every created buffer will be rendered by default. - -#### `graphics_buffer_hide(graphics_buffer)` - function (void) -Disables rendering for this buffer. - -#### `graphics_buffer_destruct(graphics_buffer)` - function (void) -Removes **_graphics_buffer_** from the rendering queue and frees its memory allocations. - -#### `graphics_buffer_shift_up(graphics_buffer, shift)` - function (void) -Shifts **_graphics_buffer_**'s content **_shift_** rows up. - -#### `graphics_buffer_set_pixel(graphics_buffer, x, y, color)` - function (void) -Sets a pixel with the given **_color_** at position(**_x_** | **_y_**) in **_graphics_buffer_**. -**_x_** and **_y_** are graphics buffer relative. - -#### `graphics_buffer_get_pixel(graphics_buffer, x, y)` - function (color_argb_T) -Returns the color of the pixel at position(**_x_** | **_y_**) in **_graphics_buffer_**. - -#### `graphics_buffer_draw_char(graphics_buffer, x, y, color, chr)` - function (void) -Draws a character (**_chr_**) at position(**_x_** | **_y_**) in **_graphics_buffer_**. -The position is the top-left corner of the char. - -#### `graphics_buffer_draw_string(graphics_buffer, x, y, color, string)` - function (position_T) -Draws **_string_** at position(**_x_** | **_y_**) in **_graphics_buffer_**. -The position is the top-left corner of the string. -Returns the position after the last char of the string. - -#### `graphics_renderer_init(boot_info)` - function (void) -Initializes the global graphics renderer. -Needs a pointer to `boot_info` to extract information about the framebuffer. - -#### `graphics_renderer_update()` - function (void) -Updates the renderers back_buffer and swaps it into the framebuffer. -To update the back_buffer, it iterates over the rendering queue and copies every buffer to the back_buffer. -If there are overlapping graphics_buffers, it alpha-blends them. - -#### `graphics_renderer_get_top_buffer(layer)` - function (graphics_buffer_T*) -Returns a pointer to the graphics_buffer, that is on top of the rendering queue of **_layer_**. - -#### `graphics_renderer_get_width()` - function (uint32_t) -Returns the width of the framebuffer. - -#### `graphics_renderer_get_height()` - function (uint32_t) -Returns the height of the framebuffer. - -### time/pit.h -#### `PIT_CHANNEL_0_PORT` - macro -The IO port, where channel 0 of the PIT (which is capable of firing IRQs) can be configured. - -#### `PIT_DIVISOR` - macro -The standard divisor nox_os loads into channel 0 of the PIT. -`32768` fires an interrupt every `~27ms`, what is perfect for preemptive multithreading. - -#### `pit_set_divisor(divisor)` - function (void) -Loads **_divisor_** into channel 0 of the PIT. -If **_divisor_** is smaller than 100, it will be set to 100. - -## mm - -### region.h - -The first 4 digits can be ignored, they are ignored by the MMU, -but for clarity / readability reasons they are `FFFF` in the kernel space. -See _General Concepts / Memory Layout_ and _General Concepts / Process Memory Isolation_ for more details. - -| Name | Start | Description | -|----------------------------------|--------------------|---------------------------------------------------| -| `MEM_REGION_PROCESS` | 0x0000000000000000 | This is the start of the process space | -| `MEM_REGION_PROCESS_EXEC` | 0x0000010000000000 | Every processes' executable will be mapped here | -| `MEM_REGION_PROCESS_THREAD_BASE` | 0x0000010100000000 | The start of the _Thread Data_ regions | -| `MEM_REGION_KERNEL` | 0xFFFF800000000000 | This is the start of the kernel space | -| `MEM_REGION_KERNEL_STACK_DUMMY` | 0xFFFFF00000000000 | This area is used when preparing a threads' stack | -| `MEM_REGION_KERNEL_HEAP` | 0xFFFFF80000000000 | The kernels' heap begins here | -| `MEM_REGION_KERNEL_THREAD_BASE` | 0xFFFFFF0000000000 | The kernel processes' _Thread Data_ regions | -| `MEM_REGION_KERNELEXEC` | 0xFFFFFFFF80000000 | The kernel executable is mapped here | - -#### `MEM_REGION_THREAD_OFFSET` - macro -This time the threads id specifies its offset in its processes' _Thread Data_ region. - -#### `KERNEL_START_ADDRESS` - macro -Returns the address of `_kernel_start`. - -#### `KERNEL_END_ADDRESS` - macro -Returns the address of `_kernel_end`. - -#### `_kernel_start` - global variable -This symbol is inserted by the linker at the beginning of the kernel. -To access its value use the `KERNEL_START_ADDRESS` macro. - -#### `_kernel_end` - global variable -This symbol is inserted by the linker at the end of the kernel. -To access its value use the `KERNEL_END_ADDRESS` macro. - -### heap.h - -#### `heap_segment_T` - struct -This is the header for each heap segment. -It holds its status information and a pointer to the next and previous segments. -It lies in memory, directly before the accessible buffer of the segment. - -#### `heap_T` - struct -This struct describes a heap. -The area between **_start_** and **_end_** is filled with heap segments. - -#### `heap_init(heap*, base)` - function (void) -Initializes **_heap_** at **_base_** (virtual address). -It will automatically map some page frames to that address. - -#### `heap_memory_allocate(heap*, size)` - function (void) -Returns a pointer to a free usable memory location, that has at least the given **_size_**. -It will return `NULL` and log an error, if the heap is corrupted. -Because this function iterates over the complete heap to find a free segment, it is slow. - -#### `heap_memory_free(heap*, address)` - function (void) -Frees a with `heap_memory_allocate` created heap segment, and makes it usable again. -Does nothing, if the address doesn't point to a valid heap segment. - -#### `heap_dump_segments(heap*)` - function (void) -Logs a complete list, of all heap segments. -Useful, when debugging / testing the heap. - -#### `heap_destruct(heap*)` - function (void) -Invalidates all segments of a heap, frees all used page frames and unmaps them. - -### memory_map.h - -#### `memory_map_get_total_memory_size(boot_info*)` - function (uint64_t) -Calculates the total amount of memory available, by iterating over the memory map. -The size is stored in a static variable, so no matter how often you call this function, the size will only be calculated once. -It returns the total amount of memory in bytes. - -### page_frame.h -This header provides the functions for basic interactions with pages (in the physical memory space). - -#### `pframe_manager_init()` - function (void) -Initializes the page frame manager, needs to be called once at kernel init. - -#### `pframe_reserve(address)` - function (void) [Thread Safe] -Blocks a page, so it can't be requested or anything else. -If the page is already blocked by anything else, e.g. by a request, it won't be reserved. - -#### `pframe_reserve_multi(address, n)` - function (void) [Thread Safe] -Reserves the page at the given address, plus *n* pages after that page. - -#### `pframe_unreserve(address)` - function (void) [Thread Safe] -Unreserves a reserved page and makes it accessible again. - -#### `pframe_unreserve_multi(address, n)` - function (void) [Thread Safe] -Unreserves the page at the given address, plus *n* pages after that page. - -#### `pframe_request()` - function (void*) [Thread Safe] -Returns the physical address of a page. -This is kind of the low level version of malloc. - -#### `pframe_free(address)` - function (void) [Thread Safe] -Needs a valid page address produced by `pframe_request()` as argument. -Invalidates the address and frees it, so it can be requested again. -This is kind of the low level version of free. - -#### `pframe_free_multi(address, n)` - function (void) [Thread Safe] -Frees the page at the given address, plus *n* pages after that page. - -### page_map.h - -#### `VIRTUAL_ADDRESS_MAX` - macro -The highest mappable virtual address. -4 level page maps have a maximum address space of 256TB. - -#### `page_map_flag_E` - enum - - **Present** - This indicates if the entry is used or should be ignored. Automatically set when mapping a page. - - **Read & Write** - A mapped Page is always readable. This flag allows writing to that page. - - **User Super** - If set, user mode access to the page is allowed. - - **Write Through** - Enables _Write Through Caching_ for this page. - - **Cache Disabled** - If this bit is set, the page won't be cached. - - **Accessed** - Set by the CPU, when this PDE or PTE was read. Won't be reset by the CPU. - - **Dirty** - Set when the page has been modified. - - **Larger Pages** - When this bit is set in a PDE or PTE, the entry points to a 1GB or 2MB page. - - **Custom 1 - 3** - Not used in NoxOS. - - **No Execute** - When this bit is set, the CPU won't execute code that lies in that page. - -#### `page_map_T` - struct [page aligned] -This struct contains 512 entries. -These entries contain an address and flags. -The addresses link like this: - - **PML4** --> **Page Directory** or _1GB Page_ - - **Page Directory** --> **Page Table** or _2MB Page_ - - **Page Table** --> _4KB Page_ - -A pointer to a `page_map_T` can be loaded into `cr3` to load this pagemap. - -#### `page_map_create()` - function (page_map_T*) -Allocates a `page_map_T` and returns a pointer to it. - -#### `page_map_fetch_current()` - function (page_map_T*) [ASM implementation] -This function will return the page map, that is currently loaded. -To achieve this, it just reads the `cr3` value. - -#### `page_map_load(page_map*)` - function (void) [ASM implementation] -Loads the given page map. -To achieve this, it writes the `cr3` value. - -#### `page_map_map_memory(page_map*, virtual_address, physical_address, flags)` - function (void) -This maps **_physical_address_** to **_virtual_address_** in **_page_map_**. -The **_flags_** will be applied to the page mapping / page table entry. -It always applies the _Present_ flag. - -#### `page_map_unmap_memory(page_map*, virtual_address)` - function (void) -Removes a page mapping from the **_page_map_**. -Page map structure intern pages won't be checked if they're still needed or not. - -#### `page_map_get_physical_address(page_map*, virtual_address)` - function (void*) -Returns the physical address of the page, that is mapped to **_virtual_address_**. - -#### `page_map_destruct(page_map*)` - function (void) -Clears a page map and frees all page map structure intern pages. - -#### `page_map_dump_info(page_map)` - function (void) -Logs information about **_page_map_**, including a map of all mapped regions. -A region is a block of continuously mapped pages. - -#### `page_map_entry_set_flags(entry, uint64_t flags)` - function (void) -This will set the provided flags to a page map entry. - -#### `page_map_entry_get_flag(entry, page_map_flag_E flag)` - function (bool) -Returns if the given flag is set in the page map entry, or not. - -#### `page_map_entry_set_address(entry, void* address)` - function (void) -This will set the provided address to a page map entry. - -#### `page_map_entry_get_address(entry)` - function (void*) -This will read and return the address set in the page map entry. - -#### `paging_init()` - function (void) -Initializes paging. -This reads the current page map set by the kernel and writes it to `g_kernel_page_map`. - -#### `g_kernel_page_map` - global variable -The kernels page map. This page map is provided by the bootloader and read from `cr3` at `paging_init`. - - -### stack.h -#### `stack_dump_call_info(rip, symbol)` - function (void) -Logs information about a call. -Give this function the **_rip_** of the call and the related **_symbol_**, to make it happy. - -#### `stack_trace_call_stack(rbp)` - function (void) -Analyses the stack and recursively dumps information about all calls until it hits a call to `_start`. - -## platform - -### cpu.h -This header contains stuff directly related to the CPU. - -OSDev Wiki: [x86 CPU Registers](https://wiki.osdev.org/CPU_Registers_x86) - -#### `cpu_state_T` - struct - - **cr3** - Control register 3, holds the current page table - - **rax** - General purpose register - - **rbx** - General purpose register - - **rcx** - General purpose register - - **rdx** - General purpose register - - **rsi** - General purpose register - - **rdi** - General purpose register - - **rbp** - The Bottom of the current stack frame - - **interrupt_id** - The ID of the interrupt, that captured the cpu state - - **error_code** - Some exceptions such as the Page fault push more detailed information into here - - **rip** - The current instruction address - - **crs** - Segment selector of the associated IDT descriptor - - **flags** - The CPU's FLAGS register, a status bitmap - - **rsp** - The Top of the current stack frame - - **ss** - Not totally sure, what this does, but it has to do with security rings - -This struct defines a *complete* CPU state, that can be saved and restored. -It is saved when the CPU fires an interrupt and restored by the interrupt handler when it's finished. -This allows multithreading and exception analysis. - -#### `cpu_flags_E` - enum - - **CPU_FLAG_CARRY** - - **CPU_FLAG_PARITY** - - **CPU_FLAG_AUXILIARY** - - **CPU_FLAG_ZERO** - - **CPU_FLAG_SIGN** - - **CPU_FLAG_TRAP** - - **CPU_FLAG_INTERRUPT_ENABLE** - - **CPU_FLAG_DIRECTION** - - **CPU_FLAG_OVERFLOW** - - **CPU_FLAG_IO_PRIVILEGE_0** - - **CPU_FLAG_IO_PRIVILEGE_1** - - **CPU_FLAG_NESTED_TASK** - - **CPU_FLAG_RESUME** - - **CPU_FLAG_VIRTUAL_8086** - - **CPU_FLAG_ALIGNMENT_CHECK** - - **CPU_FLAG_VIRTUAL_INTERRUPT** - - **CPU_FLAG_VIRTUAL_INTERRUPT_PENDING** - - **CPU_FLAG_CPUID** - -### exceptions.h -OSDev Wiki: [Exceptions](https://wiki.osdev.org/Exceptions) - -#### `exception_type_E` - enum -These are just the definitions of the CPU-exception interrupt IDs. - -#### `g_exception_type_strings` - global variable -This array of strings defines the names of the Exceptions. - -#### `exception_handle(cpu_state)` - function (cpu_state_T*) -If an interrupt is an exception, the interrupt handler will call this function to handle the exception. -At the moment it will just panic, but in far future this could get expanded for page swapping, etc. - -### gdt.h -OSDev Wiki: [Global Descriptor Table](https://wiki.osdev.org/GDT) - -#### `gdt_selector_E` - enum -- **Null** -- **Kernel Code** - Readable -- **Kernel Data** - Readable + Writable -- **User Null** -- **User Code** - Readable -- **User Data** - Readable + Writable - -#### `gdt_descriptor_T` - struct [packed] - -| Name | Type | Description | -|--------|----------|-----------------------------------------------------| -| size | uint16_t | The tables size in bytes (-1) | -| offset | uint64_t | The virtual address, where the table lies in memory | - - -#### `gdt_entry_T` - struct [packed] -| Name | Type | Description | -|--------------|----------|--------------------------------------------------------------| -| limit0 | uint16_t | Can be ignored in long mode | -| base0 | uint16_t | Can be ignored in long mode | -| base1 | uint8_t | Can be ignored in long mode | -| access | uint8_t | Specifies permissions (details in osdev wiki) | -| limit1_flags | uint8_t | The first 4 bits can be ignored and the last 4 specify flags | -| base2 | uint8_t | Can be ignored in long mode | - -#### `gdt_T` - struct [packed / page aligned] -| Name | Type | Description | -|-------------|-------------|------------------------------------------| -| null | gdt_entry_T | The entry for `GDT_SELECTOR_NULL` | -| kernel_code | gdt_entry_T | The entry for `GDT_SELECTOR_KERNEL_CODE` | -| kernel_data | gdt_entry_T | The entry for `GDT_SELECTOR_KERNEL_DATA` | -| user_null | gdt_entry_T | The entry for `GDT_SELECTOR_USER_NULL` | -| user_code | gdt_entry_T | The entry for `GDT_SELECTOR_USER_CODE` | -| user_data | gdt_entry_T | The entry for `GDT_SELECTOR_USER_DATA` | - -#### `g_default_gdt` - global variable -The systems GDT. - -#### `gdt_init` - function (void) -Populates and loads `g_default_gdt`. -This will also set all the data segment registers to 0x10 (Kernel Data) and `cs` to 0x08 (Kernel Code). - -### interrupts.h -This header contains all the stuff, needed to init and handle Interrupts. - -#### `idt_register_T` - struct [packed] -This struct is very similar to the GDT descriptor. -It holds the size and address of the Table, where the interrupt handlers are looked up. - -#### `idt_descriptor_entry_T` - struct -This struct stores information about one interrupt handler. -The osdev wiki explains this more detailed. - -#### `g_idt_register` - global variable -The default IDT configuration loaded when the IDT gets initialized. - -#### `g_handling_interrupt` - global variable -When the system isn't handling an interrupt this is set to 0. -If this is greater than 0 the system is currently handling an interrupt, - -#### `idt_init()` - function (void) -This function fills all the interrupt gates (handlers) into the IDT and loads it. - - -## proc - -The general processing structure is a bit more complex, -so I've split the schematics into multiple parts. - -Processes Schematic: -``` -+----------------+ -| Kernel Process | <----+ -| [Threads] | | -+----------------+ | - | [Parent] - [Childs] | - | +--------+--------+ - v / \ - +-----------+ +-----------+ - | Process 1 | --[Next]-> | Process 2 | - | [Threads] | <-[Prev]-- | [Threads] | . . . - +-----------+ +-----------+ - | | - [Childs] [Childs] - | | - v v - . . . . . . -``` - -Thread Schematics (processes view): -``` -+---------+ -| Process | <-------+ -+---------+ | - | [Process] - [Threads] | - | +--------+--------+ - v / \ -+----------+ +----------+ -| Thread 1 | --[LocalNext]-> | Thread 2 | -| | <-[LocalPrev]-- | | . . . -+----------+ +----------+ -``` - -Thread schematics (schedulers view): -``` - [RunningThread] - | - v - +----------+ +----------+ +----------+ -+---> | Thread 1 | --[GlobalNext]-> | Thread 2 | --[GlobalNext]-> | Thread 3 | . . . ----+ -| +-- | | <-[GlobalPrev]-- | | <-[GlobalPrev]-- | | . . . <-+ | -| | +----------+ +----------+ +----------+ | | -| | | | -| +------------------------------------[GlobalPrev]------------------------------------+ | -+--------------------------------------[GlobalNext]--------------------------------------+ -``` - -### thread.h - -#### `thread_T` - struct -| Name | Type | Description | -|-------------|--------------|--------------------------------------------------------------------------------------------------| -| state | cpu_state_T* | The last saved state of the thread ( -> _context switching_) | -| cpu_time | uint64_t | The amount of cpu time the thread had. (currently the amount of context switches the thread had) | -| stack | void* | The bottom of the threads stack | -| stack_size | uint32_t | The size of the threads stack (in bytes) | -| process | process_T* | The process, to which the thread belongs to | -| global_prev | thread_T* | The previous thread in the scheduling queue (**should only be accessed by the scheduler!**) | -| global_next | thread_T* | The next thread in the scheduling queue (**should only be accessed by the scheduler!**) | -| local_prev | thread_T* | The previous thread of _process_ (**should only be accessed by the scheduler!**) | -| local_next | thread_T* | The next thread of _process_ (**should only be accessed by the scheduler!**) | -| local_id | uint32_t | The threads id in its process | - - -#### `thread_spawn(function)` - function (thread_T*) -Allocates a `thread_T` and registers it in the scheduler. -The thread starts execution at **_function_**. -The for the thread allocated stack has a size of 16 KB (4 Pages). -The thread still needs to be started with a `thread_start` call. -Returns a pointer to the created thread. - -#### `thread_spawn_from_state(state)` - function (thread_T*) -Allocates a `thread_T` and registers it in the scheduler. -The threads' _cpu_state_ is copied from **_state_**. -This won't allocate a stack for the stack. -The thread still needs to be started with a `thread_start` call. -Returns a pointer to the created thread. -This function should be avoided. - -#### `thread_start(thread)` - function (void) -Starts/unpauses **_thread_**. - -#### `thread_pause(thread)` - function (void) -Pauses **_thread_**. - -#### `thread_kill(thread)` - function (void) -Kills **_thread_**. -The threads stack and `thread_T` structure will be freed. - -### process.h - -#### `MAX_THREADS_PER_PROCESS` - macro -The maximum amount of threads a process can have. -This limitation is just for the bitmap, -the overall processing structure would be capable of processes with unlimited threads, in theory. - -#### `THREAD_ID_INVALID` - macro -If `process_get_thread_id` returns this, the process can't spawn one more thread. - -#### `pid_t` - typedef -A typedef for `uint32_t`, used for process identification. -Such an identification number is also called `pid`. - -#### `processes_standard_E` - enum -These are standard pids - - **None** - This pid is invalid, like `NULL` is an invalid pointer - - **Kernel** - The kernels' main process - -#### `process_T` - struct - -| Name | Type | Description | -|-------------|-------------------|-----------------------------------------------------------------| -| name | char[128] | The processes' name | -| id | pid_t | The process-identification number | -| chunk | void* | A pointer to the chunk, where the process is stored in | -| chunk_id | uint32_t | The processes id inside of its chunk | -| page_map | page_map_T* | The processes page map. | -| executable | elf_executable_T* | The processes executable | -| num_threads | uint32_t | The amount of spawned threads, that belong to the process | -| threads | void* | A pointer to the processes' first thread | -| thread_ids | bitmap_T | This bitmap keeps track of the local thread ids the process has | -| parent | process_T* | The process, that spawned this process | -| childs | process_T* | A pointer to the processes' first child process | -| prev | process_T* | The previous process | -| next | process_T* | The next process | - - -#### `process_kernel_spawn(executable)` - function (void) -Spawns the kernels' main process. - -**Warning:** this should only be called once, when initializing the scheduler! - -#### `process_spawn(parent, name, executable, buffer)` - function (pid_t) -Spawns a process named **_name_** as child of **_parent_** and returns its pid. -The process gets its own page map with the mappings specified in **_executable_**. -In order to apply these mappings, this function needs the **_buffer_** where the executable was loaded from. - -#### `process_get_thread_id(process)` - function (int32_t) -Searches for a free thread id in the process. -If it finds one it returns it, else it returns `THREAD_ID_INVALID`. - -#### `process_clear_thread_id(process, id)` - function (void) -Frees the thread **_id_** and makes it request-able again. - -#### `process_kill_pid(pid)` - function (void) -Resolves the pids process and performs `process_kill` on it. - -#### `process_kill(process)` - function (void) -Kills **_process_** and all of its threads and child processes. -This will also destruct the `executable` and `page_map` associated with **_process_**. - -### scheduler.h - -#### `scheduler_processes_chunk_T` - struct -These chunks are a combination of static array and linked list. -They store the `process_T` pointer for each valid `pid_T`. - -| Name | Type | Description | -|------------------|------------------------------|------------------------------------------------------------------------------------| -| processes | process_T** | The array of process pointers | -| processes_bitmap | bitmap_T | If a bit in this bitmap is set, the _processes_ entry with the same index is valid | -| num_free_pids | uint32_t | The amount of free slots in this chunk | -| prev | scheduler_processes_chunk_T* | The previous chunk | -| next | scheduler_processes_chunk_T* | The next chunk | - - -#### `scheduler_T` - struct -| Name | Type | Description | -|----------------|------------------------------|--------------------------------------------------------------------| -| num_threads | uint32_t | Total amount of currently spawned threads | -| num_processes | uint32_t | Total amount of currently spawned processes | -| running_thread | thread_T* | A pointer to the currently running thread. | -| processes | scheduler_processes_chunk_T* | The first processes store chunk | -| blocked | bool | Set to true, while switching the context. Thread safety mechanism. | -| initialized | bool | Set to true, if the scheduler is initialized and started. | - -#### `scheduler_init(boot_info)` - function (void) -Initializes the scheduler and performs a `scheduler_start` kernel syscall. -**_boot_info_** is needed in to spawn the kernels' main process. -After this function, the whole kernel is in scheduling mode. - -#### `scheduler_start(state)` - function (cpu_state_T*) -Creates and starts a thread from **_state_**. -It returns the result of a context switch, I forgot, why I did it like that. -This is basically the backend for the `scheduler_start` kernel syscall. - -#### `scheduler_is_initialized()` - function (bool) -Returns if the scheduler is initialized (and running) or not. - -#### `scheduler_dump_info(process, indent)` - function (void) -This recursively lists information(pid, name, threads) for all child processes of **_process_**. -**_indent_** is used intern for the recursive calls and should be set to 0 initially. - -#### `scheduler_register_thread(thread)` - function (thread_T*) -Registers **_thread_** in the scheduler. - -#### `scheduler_pause_thread(thread)` - function (void) -Pauses **_thread_**, by removing it from the scheduling queue. - -**Potential Bug:** if **_thread_** was the currently running thread, -this could cause issues, because it's _prev_ and _next_ values are nulled. - -#### `scheduler_start_thread(thread)` - function (void) -Starts **_thread_**, by linking it into the scheduling queue. - -#### `scheduler_kill_thread(thread)` - function (void) -Pauses and unregisters **_thread_**. - -#### `scheduler_register_process(process)` - function (pid_t) -Reqisters **_process_** and returns its pid. - -#### `scheduler_kill_process(process)` - function (void) -Kills **_process_** and its threads and childs. - -#### `scheduler_get_process(pid)` - function (process_T*) -Returns the `process_T` pointer that is associated with **_pid_**. - -#### `scheduler_get_current_thread()` - function (thread_T*) -Returns a pointer to the currently running thread. - -#### `scheduler_get_current_process()` - function (process_T*) -Returns a pointer to the currently running threads process. - -#### `scheduler_switch_context(state)` - function (cpu_state_T*) -Saves **_state_** in the running threads _state_ value and increments their _cpu_time_ value. -Then it sets the next thread as the running thread and returns its _state_. -This needs to be called from an interrupt handler, for the returned state to be loaded. - -## utils - -### bitmap.h -Provides functionalities to create, destruct and work with bitmaps. - -#### `bitmap_T` - struct - -| Name | Type | Description | -|-----------|----------|---------------------------------------| -| size | uint32_t | The size of _buffer_ (in bytes) | -| size_bits | uint32_t | The amount of storable bits | -| buffer | uint8_t* | The buffer, where the bits are stored | - -#### `bitmap_init_from_buffer(buffer, size)` - function (bitmap_T) -Creates a bitmap object from a given buffer and size - -#### `bitmap_init(size)` - function (bitmap_T) -Allocates memory to hold a bitmap in the given size and returns a `bitmap_T` with that buffer and size. - -#### `bitmap_destruct(bitmap*)` - function (void) -Frees the memory of the given bitmap created with `bitmap_init`. - -#### `bitmap_set(bitmap*, index, value)` - function (bool) -Sets the bit at the given index in the given bitmap to the given boolean value. -Returns **false**, if the index is out of the bitmaps size bounds. -Returns **true**, if the operation was successful. - -#### `bitmap_get(bitmap*, index)` - function (bool) -Returns the boolean value stored at the given index in the given bitmap. -Always returns **false**, if the index is out of the bitmaps size bounds. - -### core.h -All the utils, which I didn't know how to name. - -#### `CORE_INTERRUPTABLE_HALT_WHILE(a)` - macro -This halts until **_a_** is true. -Used when working with blocking variables in e.g. thread safe functions. -To avoid deadlocks, this macro won't halt, while the system is handling an interrupt. - -#### `CORE_HALT_WHILE(a)` - macro -This halts until **_a_** is true. -Used when working with blocking variables in e.g. thread safe functions. - -**Warning:** When a function containing this macro is used while handling an interrupt, -this could cause deadlocks, think about using `CORE_INTERRUPTABLE_HALT_WHILE` instead. - -#### `CORE_HALT_FOREVER` - macro -This halts forever and warns about this in the log. - -### io.h -Provides basic Input/Output functionalities. - -#### `io_out_byte(port, data)` - function (void) -Writes one byte of **_data_** to **_port_**. -This is a wrapper around the assembly `outb` instruction. - -#### `io_in_byte(port)` - function (uint8_t) -Reads one byte from **_port_** and returns it. -This is a wrapper around the assembly `inb` instruction. - -#### `io_wait()` - function (void) -Waits one IO cycle. -Should be used to give the devices enough time to respond. - -### logger.h -Functionalities to write logs to QEMU's serial port. - -#### `log_level_E` - enum - - **None** - Logs just the message without a prefix - - **Info** - General information, that could be useful - - **Debug** - Should only be used to find bugs and removed (or commented out) after the bug is found - - **Warning** - Used for warnings and not important errors - - **Error** - Used for Fatal Errors / Will be printed to the screen (graphics driver is not Implemented yet) - -#### `log(log_level, string, ...)` - function (void) -Logs the given string to QEMU's log port, the string is prefixed with the log type. -Format strings are supported. - -### math.h -Mathematical functions, definitions, etc. - -#### `MAX(a, b)` - macro -Returns the bigger one of the given values. - -#### `MIN(a, b)` - macro -Returns the smaller one of the given values. - -#### `CEIL_TO(a, b)` - macro -Aligns **_a_** upwards to **_b_**. -Example: `CEIL_TO(13, 8)` would return 16, because 16 is the next higher multiple of 8 after 13. - -#### `FLOOR_TO(a, b)` - macro -Aligns **_a_** downwards to **_b_**. -Example: `FLOOR_TO(13, 8)` would return 8, because 8 is the next smaller multiple of 8 before 13. - -#### `position_T` - struct - -| Name | Description | -|------|------------------------------| -| x | X coordinate of the position | -| y | Y coordinate of the position | - - -#### `pow(base, exponent)` - function (uint64_t) -Returns the power of `base ^ exponent`. - -#### `abs(number)` - function (uint64_t) -Returns the absolute value of **_number_**. - -#### `octal_string_to_int(string, size)` - function (uint64_t) -Converts a base-8 **_string_** with length **_size_** into an integer and returns it. - -### memory.h -Basic memory functionalities. - -#### `memory_copy(source, destination, num)` - function (void) -Copies **_num_** bytes from **_source_** to **_destination_**. -On linux this function is called _memcpy_. - -#### `memory_set(destination, data, num)` - function (void) -Sets **_num_** bytes at **_destination_** to **_data_**. -On linux this function is called _memset_. - -#### `memory_compare(a, b, num)` - function (bool) -Compares the first **_num_** bytes at **_a_** and **_b_**. -Returns **false** if there is a different byte. -Returns **true** if the data is the same. -There is a similar function on linux called _memcmp_. - -#### `memory_allocate(size)` - function (void*) -Returns the address to a buffer, that is at least **_size_** bytes big. -On linux this function is called _malloc_. - -#### `memory_free(address)` - function (void) -Free the buffer at address and make it reallocatable , this buffer needs to be a buffer, that was created with `memory_allocate`. -On linux this function is called _free_. - -#### `memory_allocator_init(base)` - function (void) -This initializes the heap, where `memory_allocate` allocates memory. - -#### `memory_hexdump(address, num)` - function (void) -Logs **_num_** bytes from **_address_** as 8 byte rows. -The data is represented in hexadecimal and ascii. - -### panic.h -Ahhhhh - the kernel is burning! - -#### `panic(state, message)` - function (void) -This prints out the error message, a stack backtrace (planned) and a register dump (planned). -After that, the kernel halts forever. -This function is called, when a fatal error occurs - -### stdtypes.h -Standard type definitions, that are used almost everywhere. - -#### `uint8_t` - typedef -8-bit wide unsigned int. - -Range: `0` - `255` - -#### `int8_t` - typedef -8-bit wide signed int. - -Range: `-128` - `127` - -#### `uint16_t` - typedef -16-bit wide unsigned int. - -Range: `0` - `65536` - -#### `int16_t` - typedef -16-bit wide signed int. - -Range: `-32768` - `32767` - -#### `uint32_t` - typedef -32-bit wide unsigned int. - -Range: `0` - `4294967296` - -#### `int32_t` - typedef -32-bit wide signed int. - -Range: `-2147483648` - `2147483647` - -#### `uint64_t` - typedef -64-bit wide unsigned int. - -Range: `0` - `18446744073709551616` - -#### `int64_t` - typedef -64-bit wide signed int. - -Range: `-9223372036854775808` - `9223372036854775807` - -#### `bool` - typedef -Boolean type, can hold a logical value **true** or **false**. - -#### `true` - macro -Logical **true** value. - -#### `false` - macro -Logical **false** value - -#### `NULL` - macro -A pointer to nowhere. - -### string.h - -#### `string_t` - typedef -A null-terminated array of chars. - -#### `string_length(string)` - function (uint32_t) -Returns the amount of chars a string has before it's null-terminator. - -#### `string_compare(a, b)` - function (bool) -Returns **true** when the strings **_a_** and **_b_** are equal. -Returns **false** if they aren't equal. - -#### `string_find_next(string, chr)` - function (uint32_t) -Returns the index of the next character that matches **_chr_** in **_string_**. - -#### `string_find_last(string, chr)` - function (uint32_t) -Returns the index of the last character that matches **_chr_** in **_string_**. - -#### `variadic_format_size(string, args)` - function (uint64_t) -Returns how long a format string with the given pattern (**_string_**) and **_args_** would be. -Useful to create a big enough buffer before formatting a string. - -#### `format_size(string, ...)` - function (uint64_t) -This calls `variadic_format_size`, but instead of giving it a `va_list` you can give this function the actual arguments. - -#### `variadic_format(output, string, args)` - function (void) -Formats **_string_** with **_args_** and writes the product to **_output_**. -The rules for format strings are specified on top of this document in the _General concepts_ block. - -#### `format(output, string, ...)` - function (void) -This calls `variadic_format`, but instead of giving it a `va_list` you can give this function the actual arguments. - -#### `string_unsigned_dec_to_alpha(string, value)` - function (void) -Converts the unsigned integer in **_value_** to an alphanumeric string. -The representation is decimal. -This string will be written into **_string_**. - -#### `string_dec_to_alpha(string, value)` - function (void) -Converts the signed integer in **_value_** to an alphanumeric string. -If it is negative it will be prefixed with a hyphen. -The representation is decimal. -This string will be written into **_string_**. - -#### `string_hex_8bit_to_alpha(string, value)` - function (void) -Converts the byte in **_value_** to an alphanumeric string. -The representation is hexadecimal. -This string will be written into **_string_**. - -#### `string_hex_16bit_to_alpha(string, value)` - function (void) -Converts the word(16-bits) in **_value_** to an alphanumeric string. -The representation is hexadecimal. -This string will be written into **_string_**. - -#### `string_hex_32bit_to_alpha(string, value)` - function (void) -Converts the dword(32-bits) in **_value_** to an alphanumeric string. -The representation is hexadecimal. -This string will be written into **_string_**. - -#### `string_hex_64bit_to_alpha(string, value)` - function (void) -Converts the qword(64-bits) in **_value_** to an alphanumeric string. -The representation is hexadecimal. -This string will be written into **_string_**. - -#### `string_bin_to_alpha(string, num_bits, value)` - function (void) -Converts the data in **_value_** to an alphanumeric string. -The representation is binary. -**_num_bits_** specifies how many bits, starting at the least significant bit, will be converted. -This string will be written into **_string_**. - -#### `string_bool_to_alpha(string, value`) - function (void) -Converts the boolean in **_value_** to an alphanumeric string. -The representation is `true` or `false`. -This string will be written into **_string_**. - -#### `string_is_char_text(chr)` - function (bool) -Returns whether the char (**_chr_**) contains text(a-z, A-Z, 0-9, special chars) or not. - -#### `string_is_char_number(chr)` - function (bool) -Returns whether the char (**_chr_**) is a number(0-9) or not. - -#### `string_is_char_alpha(chr)` - function (bool) -Returns whether the char (**_chr_**) is alphanumeric(a-z, A-Z, 0-9) or not. - -#### `string_is_char_uppercase(chr)` - function (bool) -Returns whether the char (**_chr_**) is uppercase(A-Z) or not. - -#### `string_is_char_lowercase(chr)` - function (bool) -Returns whether the char (**_chr_**) is lowercase(a-z) or not. - -### symbol.h -#### `symbol_type_E` - enum - - **Function** - - **Variable** - - **Unknown** - -#### `symbol_T` - struct - -| Name | Type | Description | -|---------|---------------|-------------------------------------------------------------------------------------| -| name | string_t | The name of the symbol (e.g. the name of the kernels entry symbol would be `_start` | -| type | symbol_type_E | The symbols type (elf types like `File` are of type `Unknown`) | -| address | uint64_t | The symbols address | - -#### `symbol_resolve_from_name(symbols, num_symbols, name);` - function (symbol_T*) -This searches **_symbols_** for a symbol with a matching **_name_**. - -#### `symbol_resolve_from_rip(symbols, num_symbols, rip);` - function (symbol_T*) -Give it a list of **_symbols_** and an instruction pointer (**_rip_**) and it will return the symbol (function), where **_rip_** lays in. diff --git a/.wiki/Roadmap.md b/.wiki/Roadmap.md deleted file mode 100644 index f4de98f..0000000 --- a/.wiki/Roadmap.md +++ /dev/null @@ -1,29 +0,0 @@ -# Roadmap -- [x] Bootable system -- [x] Logger -- [X] Page frame manager -- [X] Interrupts -- [X] Page maps -- [X] Heap -- [X] Format strings -- [X] Graphics Renderer - - [X] Text - - [X] Double buffering - - [X] Buffer requests -- [X] Panic Screen - - [X] Register dump - - [X] Stack tracing -- [X] Scheduler -- [X] (Kernel) Threads -- [X] Ramdisk - - [X] USTAR - - [X] RAMFS - - [X] VFS -- [X] ELF loading -- [X] Processes -- [ ] Keyboard input (ps/2 int) -- [ ] Shell -- [ ] JSON parser for system config -- [ ] FAT32 -- [ ] Text Editor -- [ ] TCC \ No newline at end of file