diff --git a/content/projects/noxos/docs/codebase/platform/cpu.h.md b/content/projects/noxos/docs/codebase/platform/cpu.h.md new file mode 100644 index 0000000..93a0b40 --- /dev/null +++ b/content/projects/noxos/docs/codebase/platform/cpu.h.md @@ -0,0 +1,46 @@ +--- +title: "cpu.h" +summary: "stuff related directly with 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 +- **cs** - Segment selector of the associated IDT descriptor +- **flags** - The CPU's FLAGS register, a status bitmap -> [cpu_flags_E](https://nerdcult.net/projects/noxos/docs/codebase/platform/cpu.h/#cpu_flags_e---enum) +- **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. +Such a state 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** diff --git a/content/projects/noxos/docs/codebase/platform/exceptions.h.md b/content/projects/noxos/docs/codebase/platform/exceptions.h.md new file mode 100644 index 0000000..c31a7ce --- /dev/null +++ b/content/projects/noxos/docs/codebase/platform/exceptions.h.md @@ -0,0 +1,16 @@ +--- +title: "exceptions.h" +summary: "CPU-exception handling" +--- + +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 CPU-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. diff --git a/content/projects/noxos/docs/codebase/platform/gdt.h.md b/content/projects/noxos/docs/codebase/platform/gdt.h.md new file mode 100644 index 0000000..c676169 --- /dev/null +++ b/content/projects/noxos/docs/codebase/platform/gdt.h.md @@ -0,0 +1,51 @@ +--- +title: "gdt.h" +summary: "definitions to handle segments (_Global Descriptor Table_)" +--- + +Segmentation is deprecated and is only needed for backwards compatibility. + +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](https://nerdcult.net/projects/noxos/docs/codebase/platform/gdt.h/#g_default_gdt---global-variable). +This will also set all the data segment registers to 0x10 (Kernel Data) and `cs` to 0x08 (Kernel Code). diff --git a/content/projects/noxos/docs/codebase/platform/interrupts.h.md b/content/projects/noxos/docs/codebase/platform/interrupts.h.md new file mode 100644 index 0000000..f8ed175 --- /dev/null +++ b/content/projects/noxos/docs/codebase/platform/interrupts.h.md @@ -0,0 +1,22 @@ +--- +title: "interrupts.h" +summary: "the infrastructure to handle x86 interrupts" +--- + +# `idt_register_T` - struct [packed] +This struct is very similar to the [GDT descriptor](https://nerdcult.net/projects/noxos/docs/codebase/platform/gdt.h/#gdt_descriptor_t---struct-packed). +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.